Further progress with rewrite
This commit is contained in:
parent
44a1d33f0f
commit
e6ace77c39
|
|
@ -1,40 +0,0 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import tschipp.carryon.platform.Services;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.food.FoodProperties;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommonClass {
|
||||
|
||||
// This method serves as an initialization hook for the mod. The vanilla
|
||||
// game has no mechanism to load tooltip listeners so this must be
|
||||
// invoked from a mod loader specific project like Forge or Fabric.
|
||||
public static void init() {
|
||||
|
||||
Constants.LOG.info("Hello from Common init on {}! we are currently in a {} environment!", Services.PLATFORM.getPlatformName(), Services.PLATFORM.isDevelopmentEnvironment() ? "development" : "production");
|
||||
Constants.LOG.info("Diamond Item >> {}", Registry.ITEM.getKey(Items.DIAMOND));
|
||||
}
|
||||
|
||||
// This method serves as a hook to modify item tooltips. The vanilla game
|
||||
// has no mechanism to load tooltip listeners so this must be registered
|
||||
// by a mod loader like Forge or Fabric.
|
||||
public static void onItemTooltip(ItemStack stack, TooltipFlag context, List<Component> tooltip) {
|
||||
|
||||
if (!stack.isEmpty()) {
|
||||
|
||||
final FoodProperties food = stack.getItem().getFoodProperties();
|
||||
|
||||
if (food != null) {
|
||||
|
||||
tooltip.add(Component.literal("Nutrition: " + food.getNutrition()));
|
||||
tooltip.add(Component.literal("Saturation: " + food.getSaturationModifier()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package tschipp.carryon.client.render;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Vector3f;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
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.block.state.BlockState;
|
||||
import tschipp.carryon.common.carry.CarryOnData;
|
||||
import tschipp.carryon.common.carry.CarryOnData.CarryType;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
|
||||
public class CarriedObjectRender
|
||||
{
|
||||
|
||||
public static boolean drawFirstPerson(Player player, MultiBufferSource buffer, PoseStack matrix, int light)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(carry.isCarrying(CarryType.BLOCK))
|
||||
drawFirstPersonBlock(player, buffer, matrix, light, carry.getBlock());
|
||||
else
|
||||
;
|
||||
|
||||
return carry.isCarrying();
|
||||
}
|
||||
|
||||
private static void drawFirstPersonBlock(Player player, MultiBufferSource buffer, PoseStack matrix, int light, BlockState state)
|
||||
{
|
||||
matrix.pushPose();
|
||||
matrix.scale(2.5f, 2.5f, 2.5f);
|
||||
matrix.translate(0, -0.5, -1);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.disableCull();
|
||||
int perspective = CarryRenderHelper.getPerspective();
|
||||
|
||||
//TODO: FacePlayer config
|
||||
if (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);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
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);
|
||||
|
||||
RenderSystem.enableCull();
|
||||
RenderSystem.disableBlend();
|
||||
matrix.popPose();
|
||||
}
|
||||
|
||||
|
||||
public static boolean isChest(Block block)
|
||||
{
|
||||
return block == Blocks.CHEST || block == Blocks.ENDER_CHEST || block == Blocks.TRAPPED_CHEST;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package tschipp.carryon.client.render;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Quaternion;
|
||||
import com.mojang.math.Vector3f;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class CarryRenderHelper
|
||||
{
|
||||
public static Vec3 getExactPos(Entity entity, float partialticks)
|
||||
{
|
||||
return new Vec3(entity.xOld + (entity.getX() - entity.xOld) * partialticks, entity.yOld + (entity.getY() - entity.yOld) * partialticks, entity.zOld + (entity.getZ() - entity.zOld) * partialticks);
|
||||
}
|
||||
|
||||
public static float getExactBodyRotationDegrees(LivingEntity entity, float partialticks)
|
||||
{
|
||||
if (entity.getVehicle() != null && entity.getVehicle() instanceof LivingEntity)
|
||||
return -(entity.yHeadRotO + (entity.yHeadRot - entity.yHeadRotO) * partialticks);
|
||||
else
|
||||
return -(entity.yBodyRotO + (entity.yBodyRot - entity.yBodyRotO) * partialticks);
|
||||
}
|
||||
|
||||
public static Quaternion getExactBodyRotation(LivingEntity entity, float partialticks)
|
||||
{
|
||||
return Vector3f.YP.rotationDegrees(getExactBodyRotationDegrees(entity, partialticks));
|
||||
}
|
||||
|
||||
//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]);
|
||||
// }
|
||||
|
||||
public static void renderItem(BlockState state, CompoundTag tag, 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);
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public static int getPerspective()
|
||||
{
|
||||
boolean isThirdPerson = !Minecraft.getInstance().options.getCameraType().isFirstPerson(); // isThirdPerson
|
||||
boolean isThirdPersonReverse = Minecraft.getInstance().options.getCameraType().isMirrored();
|
||||
|
||||
if (!isThirdPerson && !isThirdPersonReverse)
|
||||
return 0;
|
||||
if (isThirdPerson && !isThirdPersonReverse)
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ 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 javax.annotation.Nullable;
|
||||
|
||||
|
|
@ -35,6 +36,10 @@ public class CarryOnData {
|
|||
public void setBlock(BlockState state, @Nullable BlockEntity tile)
|
||||
{
|
||||
this.type = CarryType.BLOCK;
|
||||
|
||||
if(state.hasProperty(BlockStateProperties.WATERLOGGED))
|
||||
state = state.setValue(BlockStateProperties.WATERLOGGED, false);
|
||||
|
||||
CompoundTag stateData = NbtUtils.writeBlockState(state);
|
||||
nbt.put("block", stateData);
|
||||
|
||||
|
|
@ -81,6 +86,29 @@ public class CarryOnData {
|
|||
return EntityType.create(nbt.getCompound("entity"), level).orElseThrow();
|
||||
}
|
||||
|
||||
public boolean isCarrying()
|
||||
{
|
||||
return this.type != CarryType.INVALID;
|
||||
}
|
||||
|
||||
public boolean isCarrying(CarryType type)
|
||||
{
|
||||
return this.type == type;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
this.type = CarryType.INVALID;
|
||||
this.nbt = new CompoundTag();
|
||||
}
|
||||
|
||||
public int getTick()
|
||||
{
|
||||
if(!this.nbt.contains("tick"))
|
||||
return -1;
|
||||
return this.nbt.getInt("tick");
|
||||
}
|
||||
|
||||
public enum CarryType {
|
||||
BLOCK,
|
||||
ENTITY,
|
||||
|
|
|
|||
|
|
@ -5,21 +5,27 @@ 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 {
|
||||
|
||||
public static final EntityDataAccessor<CompoundTag> CARRY_DATA_KEY = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG);
|
||||
|
||||
|
||||
public CarryOnData getCarryData(Player player)
|
||||
public static CarryOnData getCarryData(Player player)
|
||||
{
|
||||
CompoundTag data = player.getEntityData().get(CARRY_DATA_KEY);
|
||||
return new CarryOnData(data);
|
||||
return new CarryOnData(data.copy());
|
||||
}
|
||||
|
||||
public void setCarryData(Player player, CarryOnData data)
|
||||
public static void setCarryData(Player player, CarryOnData data)
|
||||
{
|
||||
player.getEntityData().set(CARRY_DATA_KEY, data.getNbt());
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
package tschipp.carryon.common.carry;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
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.Entity.RemovalReason;
|
||||
import net.minecraft.world.entity.TamableAnimal;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PickupHandler {
|
||||
|
||||
//TODO: CONFIG
|
||||
private static final double range = 2.0;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if(player.position().distanceTo(pos) >= range)
|
||||
return false;
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(carry.isCarrying())
|
||||
return false;
|
||||
|
||||
if(player.tickCount == carry.getTick())
|
||||
return false;
|
||||
|
||||
if (player.gameMode.getGameModeForPlayer() == GameType.SPECTATOR || player.gameMode.getGameModeForPlayer() == GameType.ADVENTURE)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static boolean tryPickUpBlock(ServerPlayer player, BlockPos pos, Level level)
|
||||
{
|
||||
if(!canCarryGeneral(player, Vec3.atCenterOf(pos)))
|
||||
return false;
|
||||
|
||||
//TODO: Whitelist/Blacklist checks
|
||||
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
BlockState state = level.getBlockState(pos);
|
||||
carry.setBlock(state, blockEntity);
|
||||
|
||||
level.removeBlockEntity(pos);
|
||||
level.removeBlock(pos, false);
|
||||
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
level.playSound(null, pos, state.getSoundType().getHitSound(), SoundSource.BLOCKS, 1.0f, 0.5f);
|
||||
player.swing(InteractionHand.MAIN_HAND, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean tryPickupEntity(ServerPlayer player, Entity entity)
|
||||
{
|
||||
if(!canCarryGeneral(player, entity.position()))
|
||||
return false;
|
||||
|
||||
if (entity.invulnerableTime != 0)
|
||||
return false;
|
||||
|
||||
if (entity instanceof Player)
|
||||
return false;
|
||||
|
||||
if (entity instanceof TamableAnimal tame)
|
||||
{
|
||||
UUID owner = tame.getOwnerUUID();
|
||||
UUID playerID = player.getGameProfile().getId();
|
||||
if (owner != null && !owner.equals(playerID))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entity instanceof Animal)
|
||||
((Animal) entity).dropLeash(true, true);
|
||||
|
||||
//TODO: White and blacklist
|
||||
|
||||
//TODO: Protections
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
|
||||
|
||||
entity.ejectPassengers();
|
||||
carry.setEntity(entity);
|
||||
entity.remove(RemovalReason.DISCARDED);
|
||||
|
||||
player.level.playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC, SoundSource.AMBIENT, 1.0f, 0.5f);
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
player.swing(InteractionHand.MAIN_HAND, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
package tschipp.carryon.common.carry;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
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.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
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.common.carry.CarryOnData.CarryType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class PlacementHandler
|
||||
{
|
||||
|
||||
public static boolean tryPlaceBlock(ServerPlayer player, BlockPos pos, Direction facing, @Nullable BiFunction<BlockPos, BlockState, Boolean> placementCallback)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if (!carry.isCarrying(CarryOnData.CarryType.BLOCK))
|
||||
return false;
|
||||
|
||||
if (player.tickCount == carry.getTick())
|
||||
return false;
|
||||
|
||||
Level level = player.getLevel();
|
||||
BlockState state = carry.getBlock();
|
||||
|
||||
BlockPlaceContext context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(player.position(), facing, pos));
|
||||
|
||||
if (!level.getBlockState(pos).canBeReplaced(context))
|
||||
pos = pos.relative(facing);
|
||||
|
||||
context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(player.position(), facing, pos));
|
||||
|
||||
BlockEntity blockEntity = carry.getBlockEntity(pos);
|
||||
|
||||
boolean canPlace = state.canSurvive(level, pos) && level.mayInteract(player, pos) && level.getBlockState(pos).canBeReplaced(context) && level.isUnobstructed(state, pos, CollisionContext.of(player));
|
||||
if (!canPlace)
|
||||
return false;
|
||||
|
||||
state = getPlacementState(state, player, context, pos);
|
||||
boolean doPlace = placementCallback == null ? true : placementCallback.apply(pos, state);
|
||||
|
||||
if (!doPlace)
|
||||
return false;
|
||||
|
||||
level.setBlock(pos, state, 3);
|
||||
if (blockEntity != null)
|
||||
level.setBlockEntity(blockEntity);
|
||||
carry.clear();
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
player.playSound(state.getSoundType().getPlaceSound(), 1.0f, 0.5f);
|
||||
level.playSound(null, pos, state.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0f, 0.5f);
|
||||
player.swing(InteractionHand.MAIN_HAND, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
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) {
|
||||
state = updateProperty(state, placementState, prop);
|
||||
}
|
||||
if (prop instanceof EnumProperty<?>) {
|
||||
if (state.getValue(prop) instanceof Axis)
|
||||
state = updateProperty(state, placementState, prop);
|
||||
}
|
||||
//TODO: Add config for state variant names, which should be taken from the placementState
|
||||
if (prop.getName().equals("type")) {
|
||||
state = updateProperty(state, placementState, prop);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(state);
|
||||
|
||||
state = Block.updateFromNeighbourShapes(state, player.level, pos);
|
||||
|
||||
if (placementState.hasProperty(BlockStateProperties.WATERLOGGED))
|
||||
state = state.setValue(BlockStateProperties.WATERLOGGED, placementState.getValue(BlockStateProperties.WATERLOGGED));
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>, V extends T> BlockState updateProperty(BlockState state, BlockState otherState, Property<T> prop)
|
||||
{
|
||||
var val = otherState.getValue(prop);
|
||||
return state.setValue(prop, val);
|
||||
}
|
||||
|
||||
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))
|
||||
return false;
|
||||
|
||||
if (player.tickCount == carry.getTick())
|
||||
return false;
|
||||
|
||||
Level level = player.getLevel();
|
||||
|
||||
BlockPlaceContext context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(player.position(), facing, pos));
|
||||
if (!level.getBlockState(pos).canBeReplaced(context))
|
||||
pos = pos.relative(facing);
|
||||
|
||||
Vec3 placementPos = Vec3.atBottomCenterOf(pos);
|
||||
|
||||
|
||||
Entity entity = carry.getEntity(level);
|
||||
entity.setPos(placementPos);
|
||||
|
||||
boolean doPlace = placementCallback == null ? true : placementCallback.apply(placementPos, entity);
|
||||
if (!doPlace)
|
||||
return false;
|
||||
|
||||
level.addFreshEntity(entity);
|
||||
if(entity instanceof Mob mob)
|
||||
mob.playAmbientSound();
|
||||
|
||||
player.swing(InteractionHand.MAIN_HAND, true);
|
||||
carry.clear();
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package tschipp.carryon.mixin;
|
||||
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
|
||||
@Mixin(Inventory.class)
|
||||
public class InventoryMixin
|
||||
{
|
||||
@Shadow
|
||||
public Player player;
|
||||
|
||||
// @Redirect(method = "selected:I", at = @At())
|
||||
// private void setSelected(Inventory inv, int value)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package tschipp.carryon.mixin;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
public class MinecraftMixin
|
||||
{
|
||||
@Redirect(method = "handleKeybinds()V", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Inventory;selected:I", ordinal = 0, opcode = 181)) //Opcode for PUTFIELD
|
||||
private void onSlotSelected(Inventory inv,int slot)
|
||||
{
|
||||
if(!CarryOnDataManager.getCarryData(inv.player).isCarrying())
|
||||
inv.selected = slot;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,26 +2,44 @@ package tschipp.carryon.mixin;
|
|||
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import 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(Player.class)
|
||||
public abstract class PlayerMixin extends Entity {
|
||||
public abstract class PlayerMixin extends LivingEntity {
|
||||
|
||||
public PlayerMixin(EntityType<?> type, Level level) {
|
||||
private PlayerMixin(EntityType<? extends LivingEntity> type, Level level) {
|
||||
super(type, level);
|
||||
}
|
||||
|
||||
@Inject(at = @At("RETURN"), method = "defineSynchedData()V")
|
||||
@Inject(method = "defineSynchedData()V", at = @At("RETURN"))
|
||||
private void onDefineSynchedData(CallbackInfo info) {
|
||||
this.entityData.define(CarryOnDataManager.CARRY_DATA_KEY, new CompoundTag());
|
||||
}
|
||||
|
||||
@Inject(method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN"))
|
||||
private void onAddAdditionalSaveData(CompoundTag tag, CallbackInfo info)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData((Player)(Object)this);
|
||||
tag.put("CarryOnData", carry.getNbt());
|
||||
}
|
||||
|
||||
@Inject(method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN"))
|
||||
private void onReadAdditionalSaveData(CompoundTag tag, CallbackInfo info)
|
||||
{
|
||||
if(tag.contains("CarryOnData"))
|
||||
{
|
||||
CarryOnData data = new CarryOnData(tag.getCompound("CarryOnData"));
|
||||
CarryOnDataManager.setCarryData((Player)(Object)this, data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,11 @@
|
|||
"package": "tschipp.carryon.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"InventoryMixin",
|
||||
"PlayerMixin"
|
||||
],
|
||||
"client": [
|
||||
"MinecraftMixin"
|
||||
],
|
||||
"server": [
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
|
||||
|
||||
public class ExampleMod implements ModInitializer {
|
||||
public class CarryOnFabricMod implements ModInitializer {
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
|
|
@ -14,10 +13,6 @@ public class ExampleMod implements ModInitializer {
|
|||
|
||||
// Use Fabric to bootstrap the Common mod.
|
||||
Constants.LOG.info("Hello Fabric world!");
|
||||
CommonClass.init();
|
||||
|
||||
// Some code like events require special initialization from the
|
||||
// loader specific code.
|
||||
ItemTooltipCallback.EVENT.register(CommonClass::onItemTooltip);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"tschipp.carryon.ExampleMod"
|
||||
"tschipp.carryon.CarryOnFabricMod"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
|
|
|
|||
18
Forge/src/main/java/tschipp/carryon/CarryOnForge.java
Normal file
18
Forge/src/main/java/tschipp/carryon/CarryOnForge.java
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod(Constants.MOD_ID)
|
||||
public class CarryOnForge {
|
||||
|
||||
public CarryOnForge() {
|
||||
|
||||
// This method is invoked by the Forge mod loader when it is ready
|
||||
// to load your mod. You can access Forge and Common code in this
|
||||
// project.
|
||||
|
||||
// Use Forge to bootstrap the Common mod.
|
||||
Constants.LOG.info("Hello Forge world!");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod(Constants.MOD_ID)
|
||||
public class ExampleMod {
|
||||
|
||||
public ExampleMod() {
|
||||
|
||||
// This method is invoked by the Forge mod loader when it is ready
|
||||
// to load your mod. You can access Forge and Common code in this
|
||||
// project.
|
||||
|
||||
// Use Forge to bootstrap the Common mod.
|
||||
Constants.LOG.info("Hello Forge world!");
|
||||
CommonClass.init();
|
||||
|
||||
// Some code like events require special initialization from the
|
||||
// loader specific code.
|
||||
MinecraftForge.EVENT_BUS.addListener(this::onItemTooltip);
|
||||
|
||||
}
|
||||
|
||||
// This method exists as a wrapper for the code in the Common project.
|
||||
// It takes Forge's event object and passes the parameters along to
|
||||
// the Common listener.
|
||||
private void onItemTooltip(ItemTooltipEvent event) {
|
||||
|
||||
CommonClass.onItemTooltip(event.getItemStack(), event.getFlags(), event.getToolTip());
|
||||
}
|
||||
}
|
||||
31
Forge/src/main/java/tschipp/carryon/events/ClientEvents.java
Normal file
31
Forge/src/main/java/tschipp/carryon/events/ClientEvents.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package tschipp.carryon.events;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
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.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.client.render.CarriedObjectRender;
|
||||
import tschipp.carryon.client.render.CarryRenderHelper;
|
||||
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Constants.MOD_ID, value = Dist.CLIENT)
|
||||
public class ClientEvents {
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@SubscribeEvent
|
||||
public static void renderHand(RenderHandEvent event)
|
||||
{
|
||||
Player player = Minecraft.getInstance().player;
|
||||
MultiBufferSource buffer = event.getMultiBufferSource();
|
||||
PoseStack matrix = event.getPoseStack();
|
||||
int light = event.getPackedLight();
|
||||
|
||||
if(CarriedObjectRender.drawFirstPerson(player, buffer, matrix, light) && CarryRenderHelper.getPerspective() == 0)
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
105
Forge/src/main/java/tschipp/carryon/events/CommonEvents.java
Normal file
105
Forge/src/main/java/tschipp/carryon/events/CommonEvents.java
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package tschipp.carryon.events;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
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.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.common.Mod;
|
||||
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.carry.PickupHandler;
|
||||
import tschipp.carryon.common.carry.PlacementHandler;
|
||||
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Constants.MOD_ID)
|
||||
public class CommonEvents
|
||||
{
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void onBlockClick(PlayerInteractEvent.RightClickBlock event)
|
||||
{
|
||||
if (event.isCanceled())
|
||||
return;
|
||||
|
||||
Player player = event.getEntity();
|
||||
Level level = event.getLevel();
|
||||
BlockPos pos = event.getPos();
|
||||
|
||||
if (level.isClientSide)
|
||||
return;
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if (!carry.isCarrying()) {
|
||||
if (PickupHandler.tryPickUpBlock((ServerPlayer) player, pos, level)) {
|
||||
cancel = true;
|
||||
}
|
||||
} else {
|
||||
if (carry.isCarrying(CarryType.BLOCK)) {
|
||||
if (PlacementHandler.tryPlaceBlock((ServerPlayer) player, pos, event.getFace(), (pos2, state) -> {
|
||||
BlockSnapshot snapshot = BlockSnapshot.create(level.dimension(), level, pos2);
|
||||
EntityPlaceEvent event1 = new EntityPlaceEvent(snapshot, level.getBlockState(pos), player);
|
||||
MinecraftForge.EVENT_BUS.post(event1);
|
||||
return !event1.isCanceled();
|
||||
})) {
|
||||
cancel = true;
|
||||
}
|
||||
} else {
|
||||
if (PlacementHandler.tryPlaceEntity((ServerPlayer) player,pos, event.getFace(), null))
|
||||
{
|
||||
cancel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cancel)
|
||||
{
|
||||
event.setUseBlock(Event.Result.DENY);
|
||||
event.setUseItem(Event.Result.DENY);
|
||||
event.setCancellationResult(InteractionResult.SUCCESS);
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void onEntityRightClick(PlayerInteractEvent.EntityInteract event)
|
||||
{
|
||||
if (event.isCanceled())
|
||||
return;
|
||||
|
||||
Player player = event.getEntity();
|
||||
Level level = event.getLevel();
|
||||
Entity target = event.getTarget();
|
||||
|
||||
if (level.isClientSide)
|
||||
return;
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if (!carry.isCarrying()) {
|
||||
if (PickupHandler.tryPickupEntity((ServerPlayer) player, target)) {
|
||||
event.setResult(Result.DENY);
|
||||
event.setCancellationResult(InteractionResult.SUCCESS);
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(carry.isCarrying(CarryType.ENTITY))
|
||||
{
|
||||
//TODO: Stacking
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package tschipp.carryon.events;
|
||||
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import tschipp.carryon.Constants;
|
||||
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, modid = Constants.MOD_ID)
|
||||
public class ModBusEvents {
|
||||
}
|
||||
|
|
@ -15,33 +15,29 @@ license="All rights reserved"
|
|||
# A list of mods - how many allowed here is determined by the individual mod loader
|
||||
[[mods]] #mandatory
|
||||
# The modid of the mod
|
||||
modId="multiloader" #mandatory
|
||||
modId="carryon" #mandatory
|
||||
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
|
||||
# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
|
||||
# see the associated build.gradle script for how to populate this completely automatically during a build
|
||||
version="${file.jarVersion}" #mandatory
|
||||
# A display name for the mod
|
||||
displayName="Example Mod" #mandatory
|
||||
displayName="Carry On" #mandatory
|
||||
# A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
|
||||
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
|
||||
# A URL for the "homepage" for this mod, displayed in the mod UI
|
||||
#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional
|
||||
# A file name (in the root of the mod JAR) containing a logo for display
|
||||
logoFile="multiloader.png" #optional
|
||||
logoFile="carryon.png" #optional
|
||||
# A text field displayed in the mod UI
|
||||
credits="Thanks for this example mod goes to Java" #optional
|
||||
credits="Tschipp, PurpliciousCow, cy4n" #optional
|
||||
# A text field displayed in the mod UI
|
||||
authors="Love, Cheese and small house plants" #optional
|
||||
authors="Tschipp, PurpliciousCow, cy4n" #optional
|
||||
# The description text for the mod (multi line!) (#mandatory)
|
||||
description='''
|
||||
This is a long form description of the mod. You can write whatever you want here
|
||||
|
||||
Have some lorem ipsum.
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis lacinia magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed sagittis luctus odio eu tempus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque volutpat ligula eget lacus auctor sagittis. In hac habitasse platea dictumst. Nunc gravida elit vitae sem vehicula efficitur. Donec mattis ipsum et arcu lobortis, eleifend sagittis sem rutrum. Cras pharetra quam eget posuere fermentum. Sed id tincidunt justo. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
Carry On Mod.
|
||||
'''
|
||||
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
||||
[[dependencies.multiloader]] #optional
|
||||
[[dependencies.carryon]] #optional
|
||||
# the modid of the dependency
|
||||
modId="forge" #mandatory
|
||||
# Does this dependency have to exist - if not, ordering below must be specified
|
||||
|
|
@ -53,7 +49,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis lacinia magn
|
|||
# Side this dependency is applied on - BOTH, CLIENT or SERVER
|
||||
side="BOTH"
|
||||
# Here's another dependency
|
||||
[[dependencies.multiloader]]
|
||||
[[dependencies.carryon]]
|
||||
modId="minecraft"
|
||||
mandatory=true
|
||||
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ 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
|
||||
|
|
@ -16,6 +17,10 @@ forge_version=43.1.30
|
|||
fabric_version=0.62.0+1.19.2
|
||||
fabric_loader_version=0.14.9
|
||||
|
||||
# Quilt
|
||||
quilt_loader_version=0.16.0-beta.7
|
||||
quilt_stdlib_version=1.1.0-beta.3+1.18.2
|
||||
|
||||
# Mod options
|
||||
mod_name=Carry On
|
||||
mod_author=Tschipp, PurpliciousCow
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user