Further progress with rewrite

This commit is contained in:
Tschipp 2022-10-11 22:25:56 +02:00
parent 44a1d33f0f
commit e6ace77c39
20 changed files with 740 additions and 101 deletions

View File

@ -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()));
}
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -4,8 +4,11 @@
"package": "tschipp.carryon.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"InventoryMixin",
"PlayerMixin"
],
"client": [
"MinecraftMixin"
],
"server": [
],

View File

@ -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);
}
}

View File

@ -19,7 +19,7 @@
"environment": "*",
"entrypoints": {
"main": [
"tschipp.carryon.ExampleMod"
"tschipp.carryon.CarryOnFabricMod"
]
},
"mixins": [

View 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!");
}
}

View File

@ -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());
}
}

View 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);
}
}

View 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
}
}
}

View File

@ -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 {
}

View File

@ -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

View File

@ -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