diff --git a/.idea/scopes/Fabric_sources.xml b/.idea/scopes/Fabric_sources.xml
deleted file mode 100644
index 0448412..0000000
--- a/.idea/scopes/Fabric_sources.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/scopes/Forge_sources.xml b/.idea/scopes/Forge_sources.xml
deleted file mode 100644
index 7b5f24d..0000000
--- a/.idea/scopes/Forge_sources.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/Common/src/main/java/tschipp/carryon/Constants.java b/Common/src/main/java/tschipp/carryon/Constants.java
index c7ce9f8..4410baa 100644
--- a/Common/src/main/java/tschipp/carryon/Constants.java
+++ b/Common/src/main/java/tschipp/carryon/Constants.java
@@ -2,10 +2,20 @@ package tschipp.carryon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import tschipp.carryon.common.config.CarryConfig;
+import tschipp.carryon.config.ConfigLoader;
public class Constants {
public static final String MOD_ID = "carryon";
public static final String MOD_NAME = "Carry On";
public static final Logger LOG = LoggerFactory.getLogger(MOD_NAME);
+
+ 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);
+ }
}
\ No newline at end of file
diff --git a/Common/src/main/java/tschipp/carryon/client/render/CarriedObjectRender.java b/Common/src/main/java/tschipp/carryon/client/render/CarriedObjectRender.java
index d0f9163..1cfeacd 100644
--- a/Common/src/main/java/tschipp/carryon/client/render/CarriedObjectRender.java
+++ b/Common/src/main/java/tschipp/carryon/client/render/CarriedObjectRender.java
@@ -5,27 +5,36 @@ 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.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.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.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 java.util.Optional;
+
public class CarriedObjectRender
{
- public static boolean drawFirstPerson(Player player, MultiBufferSource buffer, PoseStack matrix, int light)
+ public static boolean drawFirstPerson(Player player, MultiBufferSource buffer, PoseStack matrix, int light, float partialTicks)
{
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if(carry.isCarrying(CarryType.BLOCK))
drawFirstPersonBlock(player, buffer, matrix, light, carry.getBlock());
- else
- ;
+ else if (carry.isCarrying(CarryType.ENTITY))
+ drawFirstPersonEntity(player, buffer, matrix, light, carry.getEntity(player.level), partialTicks);
return carry.isCarrying();
}
@@ -39,8 +48,7 @@ public class CarriedObjectRender
RenderSystem.disableCull();
int perspective = CarryRenderHelper.getPerspective();
- //TODO: FacePlayer config
- if (isChest(state.getBlock())) {
+ if (Constants.CLIENT_CONFIG.facePlayer && isChest(state.getBlock())) {
matrix.mulPose(Vector3f.YP.rotationDegrees(180));
matrix.mulPose(Vector3f.XN.rotationDegrees(8));
} else {
@@ -74,8 +82,76 @@ public class CarriedObjectRender
matrix.popPose();
}
+ private static void drawFirstPersonEntity(Player player, MultiBufferSource buffer, PoseStack matrix, int light, Entity entity, float partialTicks) {
+ EntityRenderDispatcher manager = Minecraft.getInstance().getEntityRenderDispatcher();
- public static boolean isChest(Block block)
+ if (entity != null)
+ {
+ Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialTicks);
+
+ entity.setPos(playerpos.x, playerpos.y, playerpos.z);
+ entity.xRotO = 0.0f;
+ entity.yRotO = 0.0f;
+ entity.setYHeadRot(0.0f);
+
+ float height = entity.getBbHeight();
+ float width = entity.getBbWidth();
+
+ matrix.pushPose();
+ matrix.scale(0.8f, 0.8f, 0.8f);
+ matrix.mulPose(Vector3f.YP.rotationDegrees(180));
+ matrix.translate(0.0, -height - .1, width + 0.1);
+
+ // RenderSystem.enableAlphaTest();
+
+ // 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> 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);
+ }
+
+ // RenderSystem.disableAlphaTest();
+ matrix.popPose();
+ }
+
+
+ private static boolean isChest(Block block)
{
return block == Blocks.CHEST || block == Blocks.ENDER_CHEST || block == Blocks.TRAPPED_CHEST;
}
diff --git a/Common/src/main/java/tschipp/carryon/client/render/CarryRenderHelper.java b/Common/src/main/java/tschipp/carryon/client/render/CarryRenderHelper.java
index 69c37d5..0dab93c 100644
--- a/Common/src/main/java/tschipp/carryon/client/render/CarryRenderHelper.java
+++ b/Common/src/main/java/tschipp/carryon/client/render/CarryRenderHelper.java
@@ -10,8 +10,11 @@ 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.util.Mth;
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.state.BlockState;
import net.minecraft.world.phys.Vec3;
@@ -36,6 +39,87 @@ public class CarryRenderHelper
return Vector3f.YP.rotationDegrees(getExactBodyRotationDegrees(entity, partialticks));
}
+ public static void applyGeneralTransformations(Player player, float partialticks, PoseStack matrix)
+ {
+ int perspective = CarryRenderHelper.getPerspective();
+ Quaternion playerrot = CarryRenderHelper.getExactBodyRotation(player, partialticks);
+ Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialticks);
+ Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
+ Vec3 offset = playerpos.subtract(cameraPos);
+ Pose pose = player.getPose();
+
+ matrix.pushPose();
+ matrix.translate(offset.x, offset.y, offset.z);
+
+ if (perspective == 2)
+ playerrot.mul(Vector3f.YP.rotationDegrees(180));
+ matrix.mulPose(playerrot);
+
+ matrix.pushPose();
+ matrix.scale(0.6f, 0.6f, 0.6f);
+
+ if (perspective == 2)
+ matrix.translate(0, 0, -1.35);
+
+ if (doSneakCheck(player))
+ {
+ matrix.translate(0, -0.4, 0);
+ }
+
+ if (pose == Pose.SWIMMING)
+ {
+ float f = player.getSwimAmount(partialticks);
+ float f3 = player.isInWater() ? -90.0F - player.xRotO : -90.0F;
+ float f4 = Mth.lerp(f, 0.0F, f3);
+ if (perspective == 2)
+ {
+ matrix.translate(0, 0, 1.35);
+ matrix.mulPose(Vector3f.XP.rotationDegrees(f4));
+ }
+ else
+ matrix.mulPose(Vector3f.XN.rotationDegrees(f4));
+
+ matrix.translate(0, -1.5, -1.848);
+ if (perspective == 2)
+ matrix.translate(0, 0, 2.38);
+ }
+
+ if (pose == Pose.FALL_FLYING)
+ {
+ float f1 = player.getFallFlyingTicks() + partialticks;
+ float f2 = Mth.clamp(f1 * f1 / 100.0F, 0.0F, 1.0F);
+ if (!player.isAutoSpinAttack())
+ {
+ if (perspective == 2)
+ matrix.translate(0, 0, 1.35);
+
+ if (perspective == 2)
+ matrix.mulPose(Vector3f.XP.rotationDegrees(f2 * (-90.0F - player.xRotO)));
+ else
+ matrix.mulPose(Vector3f.XN.rotationDegrees(f2 * (-90.0F - player.xRotO)));
+ }
+
+ Vec3 Vector3d = player.getViewVector(partialticks);
+ Vec3 Vector3d1 = player.getDeltaMovement();
+ double d0 = Vector3d1.horizontalDistanceSqr();
+ double d1 = Vector3d1.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;
+
+ matrix.mulPose(Vector3f.YP.rotation((float) (Math.signum(d3) * Math.acos(d2))));
+ }
+
+ if (perspective != 2)
+ matrix.translate(0, 0, -1.35);
+ matrix.translate(0, -0.2, 0);
+ }
+
+ matrix.translate(0, 1.6, 0.65);
+ }
+
+
//TODO: Scripting
// public static void performOverrideTransformation(PoseStack matrix, CarryOnOverride override)
// {
@@ -84,4 +168,12 @@ public class CarryRenderHelper
return 1;
return 2;
}
+
+ public static boolean doSneakCheck(Player player)
+ {
+ if (player.getAbilities().flying)
+ return false;
+
+ return player.isShiftKeyDown() || player.isCrouching();
+ }
}
diff --git a/Common/src/main/java/tschipp/carryon/common/carry/ListHandler.java b/Common/src/main/java/tschipp/carryon/common/carry/ListHandler.java
new file mode 100644
index 0000000..7773f47
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/common/carry/ListHandler.java
@@ -0,0 +1,194 @@
+package tschipp.carryon.common.carry;
+
+import net.minecraft.core.Registry;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.tags.TagKey;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.state.properties.Property;
+import tschipp.carryon.Constants;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class ListHandler {
+
+ private static Set FORBIDDEN_TILES = new HashSet<>();
+ private static Set FORBIDDEN_ENTITIES = new HashSet<>();
+ private static Set ALLOWED_ENTITIES = new HashSet<>();
+ private static Set ALLOWED_TILES = new HashSet<>();
+ private static Set FORBIDDEN_STACKING = new HashSet<>();
+ private static Set ALLOWED_STACKING = new HashSet<>();
+
+ private static List> FORBIDDEN_TILES_TAGS = new ArrayList<>();
+ private static List>> FORBIDDEN_ENTITIES_TAGS = new ArrayList<>();
+ private static List>> ALLOWED_ENTITIES_TAGS = new ArrayList<>();
+ private static List> ALLOWED_TILES_TAGS = new ArrayList<>();
+ private static List>> FORBIDDEN_STACKING_TAGS = new ArrayList<>();
+ private static List>> ALLOWED_STACKING_TAGS = new ArrayList<>();
+
+
+ private static Set> PROPERTY_EXCEPTION_CLASSES = new HashSet<>();
+
+
+ public static boolean isPermitted(Block block)
+ {
+ if(Constants.COMMON_CONFIG.settings.useWhitelistBlocks)
+ return doCheck(block, ALLOWED_TILES, ALLOWED_TILES_TAGS);
+ else
+ return !doCheck(block, FORBIDDEN_TILES, FORBIDDEN_TILES_TAGS);
+ }
+
+ public static boolean isPermitted(Entity entity)
+ {
+ if(Constants.COMMON_CONFIG.settings.useWhitelistEntities)
+ return doCheck(entity, ALLOWED_ENTITIES, ALLOWED_ENTITIES_TAGS);
+ else
+ return !doCheck(entity, FORBIDDEN_ENTITIES, FORBIDDEN_ENTITIES_TAGS);
+ }
+
+ public static boolean isStackingPermitted(Entity entity)
+ {
+ if(Constants.COMMON_CONFIG.settings.useWhitelistStacking)
+ return doCheck(entity, ALLOWED_STACKING, ALLOWED_STACKING_TAGS);
+ else
+ return !doCheck(entity, FORBIDDEN_STACKING, FORBIDDEN_STACKING_TAGS);
+ }
+
+ public static boolean isPropertyException(Property> prop)
+ {
+ return PROPERTY_EXCEPTION_CLASSES.contains(prop.getValueClass());
+ }
+
+ private static boolean doCheck(Block block, Set regular, List> tags)
+ {
+ String name = Registry.BLOCK.getKey(block).toString();
+ if(regular.contains(name))
+ return true;
+ for(TagKey tag : tags)
+ if(block.defaultBlockState().is(tag))
+ return true;
+ return false;
+ }
+
+ private static boolean doCheck(Entity entity, Set regular, List>> tags)
+ {
+ String name = Registry.ENTITY_TYPE.getKey(entity.getType()).toString();
+ if(regular.contains(name))
+ return true;
+ for(TagKey> tag : tags)
+ if(entity.getType().is(tag))
+ return true;
+ return false;
+ }
+
+ public static void initConfigLists()
+ {
+ FORBIDDEN_ENTITIES.clear();
+ FORBIDDEN_ENTITIES_TAGS.clear();
+ FORBIDDEN_STACKING.clear();
+ FORBIDDEN_STACKING_TAGS.clear();
+ FORBIDDEN_TILES.clear();
+ FORBIDDEN_TILES_TAGS.clear();
+ ALLOWED_ENTITIES.clear();
+ ALLOWED_ENTITIES_TAGS.clear();
+ ALLOWED_STACKING.clear();
+ ALLOWED_STACKING_TAGS.clear();
+ ALLOWED_TILES.clear();
+ ALLOWED_TILES_TAGS.clear();
+ PROPERTY_EXCEPTION_CLASSES.clear();
+
+ Map> blocktags = Registry.BLOCK.getTagNames().collect(Collectors.toMap(t -> t.location(), t -> t));
+ Map>> entitytags = Registry.ENTITY_TYPE.getTagNames().collect(Collectors.toMap(t -> t.location(), t -> t));
+
+ List forbidden = new ArrayList<>(List.of(Constants.COMMON_CONFIG.blacklist.forbiddenTiles));
+ forbidden.add("#carryon:block_blacklist");
+ addWithWildcards(forbidden, FORBIDDEN_TILES, Registry.BLOCK, blocktags, FORBIDDEN_TILES_TAGS);
+
+ List forbiddenEntity = new ArrayList<>(List.of(Constants.COMMON_CONFIG.blacklist.forbiddenEntities));
+ forbiddenEntity.add("#carryon:entity_blacklist");
+ addWithWildcards(forbiddenEntity, FORBIDDEN_ENTITIES, Registry.ENTITY_TYPE, entitytags, FORBIDDEN_ENTITIES_TAGS);
+
+ List allowedEntities = new ArrayList<>(List.of(Constants.COMMON_CONFIG.whitelist.allowedEntities));
+ allowedEntities.add("#carryon:entity_whitelist");
+ addWithWildcards(allowedEntities, ALLOWED_ENTITIES, Registry.ENTITY_TYPE, entitytags, ALLOWED_ENTITIES_TAGS);
+
+ List allowedBlocks = new ArrayList<>(List.of(Constants.COMMON_CONFIG.whitelist.allowedBlocks));
+ allowedBlocks.add("#carryon:block_whitelist");
+ addWithWildcards(allowedBlocks, ALLOWED_TILES, Registry.BLOCK, blocktags, ALLOWED_TILES_TAGS);
+
+ List forbiddenStacking = new ArrayList<>(List.of(Constants.COMMON_CONFIG.blacklist.forbiddenStacking));
+ forbiddenStacking.add("#carryon:stacking_blacklist");
+ addWithWildcards(forbiddenStacking, FORBIDDEN_STACKING, Registry.ENTITY_TYPE, entitytags, FORBIDDEN_STACKING_TAGS);
+
+ List allowedStacking = new ArrayList<>(List.of(Constants.COMMON_CONFIG.whitelist.allowedStacking));
+ allowedStacking.add("#carryon:stacking_whitelist");
+ addWithWildcards(allowedStacking, ALLOWED_STACKING, Registry.ENTITY_TYPE, entitytags, ALLOWED_STACKING_TAGS);
+
+ for(String propString : Constants.COMMON_CONFIG.settings.placementStateExceptions)
+ {
+ if(!propString.contains("[") || !propString.contains("]"))
+ continue;
+ String name = propString.substring(0, propString.indexOf("["));
+ String propName = propString.substring(propString.indexOf("[") + 1, propString.indexOf("]"));
+ Block blk = Registry.BLOCK.get(new ResourceLocation(name));
+ for(Property> prop : blk.defaultBlockState().getProperties())
+ {
+ if(prop.getName().equals(propName))
+ PROPERTY_EXCEPTION_CLASSES.add(prop.getValueClass());
+ }
+ }
+
+
+ }
+
+ private static void addTag(String tag, Map> tagMap, List> tags) {
+ String sub = tag.substring(1);
+ TagKey t = tagMap.get(new ResourceLocation(sub));
+ if (t != null)
+ tags.add(t);
+ }
+
+ private static void addWithWildcards(List entries, Set toAddTo, Registry registry, Map> tags, List> toAddTags) {
+
+ ResourceLocation[] keys = registry.keySet().toArray(new ResourceLocation[0]);
+ for (int i = 0; i < entries.size(); i++)
+ {
+ String curr = entries.get(i);
+ if (!curr.startsWith("#"))
+ {
+ if (curr.contains("*"))
+ {
+ String[] filter = curr.replace("*", ",").split(",");
+
+ for (ResourceLocation key : keys)
+ {
+ if (containsAll(key.toString(), filter))
+ {
+ toAddTo.add(key.toString());
+ }
+ }
+ }
+ else
+ toAddTo.add(curr);
+ }
+ else
+ addTag(curr, tags, toAddTags);
+ }
+ }
+
+ public static boolean containsAll(String str, String... strings)
+ {
+ boolean containsAll = true;
+
+ for (String s : strings)
+ {
+ if (!str.contains(s))
+ containsAll = false;
+ }
+
+ return containsAll;
+ }
+
+}
diff --git a/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java b/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java
index a08c452..e7c185c 100644
--- a/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java
+++ b/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java
@@ -1,12 +1,15 @@
package tschipp.carryon.common.carry;
import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
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.AgeableMob;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Entity.RemovalReason;
+import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.entity.TamableAnimal;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.player.Player;
@@ -15,15 +18,12 @@ 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 tschipp.carryon.Constants;
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
@@ -33,13 +33,14 @@ public class PickupHandler {
if(!player.getMainHandItem().isEmpty() || !player.getOffhandItem().isEmpty())
return false;
- if(player.position().distanceTo(pos) >= range)
+ if(player.position().distanceTo(pos) > Constants.COMMON_CONFIG.settings.maxDistance)
return false;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if(carry.isCarrying())
return false;
+ //Needed so that we don't pick up and place in the same tick
if(player.tickCount == carry.getTick())
return false;
@@ -47,6 +48,7 @@ public class PickupHandler {
return false;
+
return true;
}
@@ -56,12 +58,33 @@ public class PickupHandler {
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);
+
+ if(!ListHandler.isPermitted(state.getBlock()))
+ return false;
+
+ if(state.getDestroySpeed(level, pos) == -1 && !player.isCreative())
+ return false;
+
+ if(blockEntity == null && !Constants.COMMON_CONFIG.settings.pickupAllBlocks)
+ return false;
+
+ //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
+
carry.setBlock(state, blockEntity);
level.removeBlockEntity(pos);
@@ -94,19 +117,37 @@ public class PickupHandler {
return false;
}
- if (entity instanceof Animal)
- ((Animal) entity).dropLeash(true, true);
+ if(!ListHandler.isPermitted(entity))
+ {
+ //We can pick up baby animals even if the grown up animal is blacklisted.
+ if(!(entity instanceof AgeableMob ageableMob && Constants.COMMON_CONFIG.settings.allowBabies && (ageableMob.getAge() < 0 || ageableMob.isBaby())))
+ return false;
+ }
- //TODO: White and blacklist
+ //Non-Creative only guards
+ if(!player.isCreative())
+ {
+ 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())
+ return false;
+ }
+
+ //TODO: Script conditions
+
+ //TODO: Gamestages conditions check
//TODO: Protections
CarryOnData carry = CarryOnDataManager.getCarryData(player);
-
entity.ejectPassengers();
+ if (entity instanceof Animal animal)
+ animal.dropLeash(true, true);
+
carry.setEntity(entity);
- entity.remove(RemovalReason.DISCARDED);
+ entity.remove(RemovalReason.UNLOADED_WITH_PLAYER);
player.level.playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC, SoundSource.AMBIENT, 1.0f, 0.5f);
CarryOnDataManager.setCarryData(player, carry);
diff --git a/Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java b/Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java
index 34dbe60..dccc4c8 100644
--- a/Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java
+++ b/Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java
@@ -2,7 +2,6 @@ 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;
@@ -16,7 +15,6 @@ 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;
@@ -55,7 +53,7 @@ public class PlacementHandler
return false;
state = getPlacementState(state, player, context, pos);
- boolean doPlace = placementCallback == null ? true : placementCallback.apply(pos, state);
+ boolean doPlace = placementCallback == null || placementCallback.apply(pos, state);
if (!doPlace)
return false;
@@ -80,12 +78,12 @@ public class PlacementHandler
if (prop instanceof DirectionProperty) {
state = updateProperty(state, placementState, prop);
}
- if (prop instanceof EnumProperty>) {
- if (state.getValue(prop) instanceof Axis)
- state = updateProperty(state, placementState, prop);
+ if (prop.getValueClass() == Direction.Axis.class) {
+ state = updateProperty(state, placementState, prop);
}
- //TODO: Add config for state variant names, which should be taken from the placementState
- if (prop.getName().equals("type")) {
+
+ //This is needed for certain blocks, otherwise we get problems like chests not connecting
+ if (ListHandler.isPropertyException(prop)) {
state = updateProperty(state, placementState, prop);
}
}
@@ -100,7 +98,7 @@ public class PlacementHandler
return state;
}
- private static , V extends T> BlockState updateProperty(BlockState state, BlockState otherState, Property prop)
+ private static > BlockState updateProperty(BlockState state, BlockState otherState, Property prop)
{
var val = otherState.getValue(prop);
return state.setValue(prop, val);
@@ -127,7 +125,7 @@ public class PlacementHandler
Entity entity = carry.getEntity(level);
entity.setPos(placementPos);
- boolean doPlace = placementCallback == null ? true : placementCallback.apply(placementPos, entity);
+ boolean doPlace = placementCallback == null || placementCallback.apply(placementPos, entity);
if (!doPlace)
return false;
diff --git a/Common/src/main/java/tschipp/carryon/common/config/CarryConfig.java b/Common/src/main/java/tschipp/carryon/common/config/CarryConfig.java
new file mode 100644
index 0000000..1fff280
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/common/config/CarryConfig.java
@@ -0,0 +1,311 @@
+package tschipp.carryon.common.config;
+
+import tschipp.carryon.config.PropertyType;
+import tschipp.carryon.config.annotations.Category;
+import tschipp.carryon.config.annotations.Config;
+import tschipp.carryon.config.annotations.Property;
+
+public class CarryConfig {
+
+ @Config("carryon-common")
+ public static class Common {
+ //Settings
+ @Property(
+ type = PropertyType.CATEGORY,
+ description = "General Settings"
+ )
+ public Settings settings = new Settings();
+
+ @Category("settings")
+ public static class Settings {
+ @Property(
+ type = PropertyType.DOUBLE,
+ description = "Maximum distance from where Blocks and Entities can be picked up",
+ minD = 0
+ )
+ public double maxDistance = 2.5;
+
+ @Property(
+ type = PropertyType.DOUBLE,
+ description = "Max width of entities that can be picked up in survival mode",
+ minD = 0,
+ maxD = 10
+ )
+ public double maxEntityWidth = 1.5;
+
+ @Property(
+ type = PropertyType.DOUBLE,
+ description = "Max height of entities that can be picked up in survival mode",
+ minD = 0,
+ maxD = 10
+ )
+ public double maxEntityHeight = 2.5;
+
+ @Property(
+ type = PropertyType.DOUBLE,
+ description = "Slowness multiplier for blocks",
+ minD = 0
+ )
+ public double blockSlownessMultiplier = 1;
+
+ @Property(
+ type = PropertyType.DOUBLE,
+ description = "Slowness multiplier for entities",
+ minD = 0
+ )
+ public double entitySlownessMultiplier = 1;
+
+ @Property(
+ type = PropertyType.INT,
+ description = "Maximum stack limit for entities",
+ min = 1
+ )
+ public int maxEntityStackLimit = 10;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "More complex Tile Entities slow down the player more"
+ )
+ public boolean heavyTiles = true;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Allow all blocks to be picked up, not just Tile Entites. White/Blacklist will still be respected."
+ )
+ public boolean pickupAllBlocks = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Whether Blocks and Entities slow the creative player down when carried"
+ )
+ public boolean slownessInCreative = true;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Whether hostile mobs should be able to picked up in survival mode"
+ )
+ public boolean pickupHostileMobs = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Larger Entities slow down the player more"
+ )
+ public boolean heavyEntities = true;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Allow babies to be carried even when adult mob is blacklisted (or not whitelisted)"
+ )
+ public boolean allowBabies = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Use Whitelist instead of Blacklist for Blocks"
+ )
+ public boolean useWhitelistBlocks = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Use Whitelist instead of Blacklist for Entities"
+ )
+ public boolean useWhitelistEntities = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Use Whitelist instead of Blacklist for Stacking"
+ )
+ public boolean useWhitelistStacking = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Whether the player can hit blocks and entities while carrying or not"
+ )
+ public boolean hitWhileCarrying = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Whether the player drops the carried object when hit or not"
+ )
+ public boolean dropCarriedWhenHit = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Use custom Pickup Scripts. Having this set to false, will not allow you to run scripts, but will increase your performance"
+ )
+ public boolean useScripts = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Allows entities to be stacked on top of each other"
+ )
+ public boolean stackableEntities = true;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Whether entities' size matters when stacking or not. This means that larger entities cannot be stacked on smaller ones"
+ )
+ public boolean entitySizeMattersStacking = true;
+
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Usually all the block state information is retained when placing a block that was picked up. But some information is changed to a modified property, like rotation or orientation. In this list, add additional properties that should NOT be saved and instead be updated when placed. Format: modid:block[propertyname]. Note: You don't need to add an entry for every subtype of a same block. For example, we only add an entry for one type of slab, but the change is applied to all slabs."
+ )
+ public String[] placementStateExceptions = {
+ "minecraft:chest[type]"
+ };
+ }
+
+ @Property(
+ type = PropertyType.CATEGORY,
+ description = "Whitelist. Read about the format here: https://github.com/Tschipp/CarryOn/wiki/Black---and-Whitelist-Config"
+ )
+
+ //Whitelist
+ public Whitelist whitelist = new Whitelist();
+ @Category("whitelist")
+ public static class Whitelist {
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Entities that CAN be picked up (useWhitelistEntities must be true)"
+ )
+ public String[] allowedEntities = {};
+
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Blocks that CAN be picked up (useWhitelistBlocks must be true)"
+ )
+ public String[] allowedBlocks = {};
+
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Entities that CAN have other entities stacked on top of them (useWhitelistStacking must be true)"
+ )
+ public String[] allowedStacking = {};
+ }
+
+ //Blacklist
+ @Property(
+ type = PropertyType.CATEGORY,
+ description = "Blacklist. Read about the format here: https://github.com/Tschipp/CarryOn/wiki/Black---and-Whitelist-Config"
+ )
+ public Blacklist blacklist = new Blacklist();
+ @Category("blacklist")
+ public static class Blacklist {
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Blocks that cannot be picked up"
+ )
+ public String[] forbiddenTiles = {
+ "#forge:immovable", "#forge:relocation_not_supported", "minecraft:end_portal",
+ "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",
+ "minecraft:nether_portal", "minecraft:tall_seagrass", "animania:block_trough",
+ "animania:block_invisiblock", "colossalchests:*", "ic2:*", "bigreactors:*", "forestry:*",
+ "tconstruct:*", "rustic:*", "botania:*", "astralsorcery:*", "quark:colored_bed_*",
+ "immersiveengineering:*", "embers:block_furnace", "embers:ember_bore",
+ "embers:ember_activator", "embers:mixer", "embers:heat_coil", "embers:large_tank",
+ "embers:crystal_cell", "embers:alchemy_pedestal", "embers:boiler", "embers:combustor",
+ "embers:catalzyer", "embers:field_chart", "embers:inferno_forge",
+ "storagedrawers:framingtable", "skyresources:*", "lootbags:*", "exsartagine:*",
+ "aquamunda:tank", "opencomputers:*", "malisisdoors:*", "industrialforegoing:*",
+ "minecolonies:*", "thaumcraft:pillar*", "thaumcraft:infernal_furnace",
+ "thaumcraft:placeholder*", "thaumcraft:infusion_matrix", "thaumcraft:golem_builder",
+ "thaumcraft:thaumatorium*", "magneticraft:oil_heater", "magneticraft:solar_panel",
+ "magneticraft:steam_engine", "magneticraft:shelving_unit", "magneticraft:grinder",
+ "magneticraft:sieve", "magneticraft:solar_tower", "magneticraft:solar_mirror",
+ "magneticraft:container", "magneticraft:pumpjack", "magneticraft:solar_panel",
+ "magneticraft:refinery", "magneticraft:oil_heater", "magneticraft:hydraulic_press",
+ "magneticraft:multiblock_gap", "refinedstorage:*", "mcmultipart:*", "enderstorage:*",
+ "betterstorage:*", "practicallogistics2:*", "wearablebackpacks:*", "rftools:screen",
+ "rftools:creative_screen", "create:*", "magic_doorknob:*", "iceandfire:*", "ftbquests:*",
+ "waystones:*"
+ };
+
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Entities that cannot be picked up"
+ )
+ public String[] forbiddenEntities = {
+ "minecraft:end_crystal", "minecraft:ender_dragon", "minecraft:ghast",
+ "minecraft:shulker", "minecraft:leash_knot", "minecraft:armor_stand",
+ "minecraft:item_frame", "minecraft:painting", "minecraft:shulker_bullet",
+ "animania:hamster", "animania:ferret*", "animania:hedgehog*", "animania:cart",
+ "animania:wagon", "mynko:*", "pixelmon:*", "mocreatures:*", "quark:totem", "vehicle:*"
+ };
+
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Entities that cannot have other entities stacked on top of them"
+ )
+ public String[] forbiddenStacking = {
+ "minecraft:horse"
+ };
+ }
+
+ //Custom Pickup Conditions
+ @Property(
+ type = PropertyType.CATEGORY,
+ description = "Custom Pickup Conditions. Read about the format here: https://github.com/Tschipp/CarryOn/wiki/Custom-Pickup-Condition-Config"
+ )
+ public CustomPickupConditions customPickupConditions = new CustomPickupConditions();
+ @Category("customPickupConditions")
+ public static class CustomPickupConditions {
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Custom Pickup Conditions for Blocks"
+ )
+ public String[] customPickupConditionsBlocks = {};
+
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Custom Pickup Conditions for Entities"
+ )
+ public String[] customPickupConditionsEntities = {};
+ }
+ }
+
+ @Config("carryon-client")
+ public static class Client {
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "If the front of the Tile Entities should face the player or should face outward"
+ )
+ public boolean facePlayer = false;
+
+ @Property(
+ type = PropertyType.BOOLEAN,
+ description = "Arms should render on sides when carrying. Set to false if you experience issues with mods that replace the player model (like MoBends, etc)"
+ )
+ public boolean renderArms = true;
+
+ @Property(
+ type = PropertyType.STRING_ARRAY,
+ description = "Model Overrides based on NBT or Meta. Advanced users only! Read about the format here: https://github.com/Tschipp/CarryOn/wiki/Model-Override-Config"
+ )
+ public String[] modelOverrides = {
+ "minecraft:hopper->(block)minecraft:hopper",
+ "minecraft:comparator->(block)minecraft:comparator",
+ "minecraft:repeater->(block)minecraft:repeater",
+ "minecraft:cauldron->(block)minecraft:cauldron",
+ "minecraft:brewing_stand->(item)minecraft:brewing_stand",
+ "minecraft:flower_pot->(block)minecraft:flower_pot",
+ "minecraft:sugar_cane->(block)minecraft:sugar_cane",
+ "minecraft:redstone_wire->(item)minecraft:redstone",
+ "animania:block_nest->(block)animania:block_nest",
+ "animania:cheese_mold;0->(block)animania:cheese_mold;0",
+ "animania:cheese_mold;1->(block)animania:cheese_mold;1",
+ "animania:cheese_mold;2->(block)animania:cheese_mold;2",
+ "animania:cheese_mold;3->(block)animania:cheese_mold;3",
+ "animania:cheese_mold;4->(block)animania:cheese_mold;4",
+ "animania:cheese_mold;5->(block)animania:cheese_mold;5",
+ "animania:cheese_mold;6->(block)animania:cheese_mold;6",
+ "animania:cheese_mold;7->(block)animania:cheese_mold;7",
+ "animania:cheese_mold;8->(block)animania:cheese_mold;8",
+ "animania:cheese_mold;9->(block)animania:cheese_mold;9",
+ "animania:cheese_mold;10->(block)animania:cheese_mold;10"
+ };
+ }
+
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/AnnotationData.java b/Common/src/main/java/tschipp/carryon/config/AnnotationData.java
new file mode 100644
index 0000000..06f7d63
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/AnnotationData.java
@@ -0,0 +1,24 @@
+package tschipp.carryon.config;
+
+
+import tschipp.carryon.config.annotations.Property;
+
+import java.lang.reflect.Field;
+
+public record AnnotationData(
+ PropertyType type,
+ String description,
+ int min, int max,
+ double minD, double maxD
+) {
+
+ public static AnnotationData getData(Field field) {
+ Property annotation = field.getAnnotation(Property.class);
+ return new AnnotationData(
+ annotation.type(),
+ annotation.description(),
+ annotation.min(), annotation.max(),
+ annotation.minD(), annotation.maxD()
+ );
+ }
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/BuiltCategory.java b/Common/src/main/java/tschipp/carryon/config/BuiltCategory.java
new file mode 100644
index 0000000..b001281
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/BuiltCategory.java
@@ -0,0 +1,37 @@
+package tschipp.carryon.config;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+public class BuiltCategory {
+
+ public final List properties = new ArrayList<>();
+ public final List categories = new ArrayList<>();
+
+ public final String categoryDesc;
+ public final String category;
+
+ public BuiltCategory(String categoryDesc, String category) {
+ this.categoryDesc = categoryDesc;
+ this.category = category;
+ }
+
+ public Optional getProperty(String id) {
+ for (PropertyData property : properties) {
+ if (property.getId().equals(id)) {
+ return Optional.of(property);
+ }
+ }
+ return Optional.empty();
+ }
+
+ public Optional getCategory(String id) {
+ for (BuiltCategory category : categories) {
+ if (category.category.equals(id)) {
+ return Optional.of(category);
+ }
+ }
+ return Optional.empty();
+ }
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/BuiltConfig.java b/Common/src/main/java/tschipp/carryon/config/BuiltConfig.java
new file mode 100644
index 0000000..cb950fb
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/BuiltConfig.java
@@ -0,0 +1,11 @@
+package tschipp.carryon.config;
+
+public class BuiltConfig extends BuiltCategory {
+
+ public final String fileName;
+
+ public BuiltConfig(String fileName) {
+ super(null, fileName);
+ this.fileName = fileName;
+ }
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/ConfigLoader.java b/Common/src/main/java/tschipp/carryon/config/ConfigLoader.java
new file mode 100644
index 0000000..ffe129a
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/ConfigLoader.java
@@ -0,0 +1,61 @@
+package tschipp.carryon.config;
+
+//Many Thanks to ThatGravyBoat for this template!
+
+import tschipp.carryon.common.carry.ListHandler;
+import tschipp.carryon.config.annotations.Category;
+import tschipp.carryon.config.annotations.Config;
+import tschipp.carryon.config.annotations.Property;
+import tschipp.carryon.platform.Services;
+
+import java.lang.reflect.Field;
+
+public class ConfigLoader {
+
+ public static void registerConfig(Object object) {
+ BuiltCategory category;
+ try {
+ category = buildCategory(null, object);
+ } catch (Exception e) {
+ e.printStackTrace();
+ category = null;
+ }
+ if (category instanceof BuiltConfig config) {
+ registerConfig(config);
+ } else {
+ throw new IllegalArgumentException("Config supplied does not have a @Config annotation");
+ }
+ }
+
+ public static void registerConfig(BuiltConfig config) {
+ Services.PLATFORM.registerConfig(config);
+ }
+
+ public static void onConfigLoaded() {
+ ListHandler.initConfigLists();
+ }
+
+ public static BuiltCategory buildCategory(String categoryDesc, Object object) throws IllegalAccessException {
+ Class> configClass = object.getClass();
+ BuiltCategory category;
+ if (configClass.isAnnotationPresent(Config.class)) {
+ category = new BuiltConfig(configClass.getAnnotation(Config.class).value());
+ } else if (configClass.isAnnotationPresent(Category.class)) {
+ category = new BuiltCategory(categoryDesc, configClass.getAnnotation(Category.class).value());
+ } else {
+ throw new IllegalStateException("Config does not contain any @Config annotation or @Category");
+ }
+
+ for (Field field : configClass.getDeclaredFields()) {
+ if (field.isAnnotationPresent(Property.class) && field.canAccess(object)) {
+ PropertyType type = field.getAnnotation(Property.class).type();
+ if (type.equals(PropertyType.CATEGORY)) {
+ category.categories.add(buildCategory(field.getAnnotation(Property.class).description(), field.get(object)));
+ } else {
+ category.properties.add(new PropertyData(object, field, AnnotationData.getData(field)));
+ }
+ }
+ }
+ return category;
+ }
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/PropertyData.java b/Common/src/main/java/tschipp/carryon/config/PropertyData.java
new file mode 100644
index 0000000..af16458
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/PropertyData.java
@@ -0,0 +1,59 @@
+package tschipp.carryon.config;
+
+import java.lang.reflect.Field;
+
+public record PropertyData(Object fieldClass, Field field, AnnotationData data) {
+
+ public String getId() {
+ return field().getName();
+ }
+
+ public boolean getBoolean() throws IllegalAccessException {
+ return field().getBoolean(fieldClass());
+ }
+
+ public void setBoolean(boolean _boolean) {
+ try {
+ field.setBoolean(fieldClass, _boolean);
+ } catch (Exception e) {
+ //Ignore
+ }
+ }
+
+ public int getInt() throws IllegalAccessException {
+ return field().getInt(fieldClass());
+ }
+
+ public void setInt(int _int) {
+ try {
+ field.setInt(fieldClass, _int);
+ } catch (Exception e) {
+ //Ignore
+ }
+ }
+
+ public double getDouble() throws IllegalAccessException {
+ return field().getDouble(fieldClass());
+ }
+
+ public void setDouble(double _double) {
+ try {
+ field.setDouble(fieldClass, _double);
+ } catch (Exception e) {
+ //Ignore
+ }
+ }
+
+ public String[] getStringArray() throws IllegalAccessException {
+ return (String[])field().get(fieldClass());
+ }
+
+ public void setStringArray(String[] arr)
+ {
+ try {
+ field.set(fieldClass, arr);
+ } catch (Exception e) {
+ //Ignore
+ }
+ }
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/PropertyType.java b/Common/src/main/java/tschipp/carryon/config/PropertyType.java
new file mode 100644
index 0000000..9c985d2
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/PropertyType.java
@@ -0,0 +1,9 @@
+package tschipp.carryon.config;
+
+public enum PropertyType {
+ INT,
+ DOUBLE,
+ BOOLEAN,
+ STRING_ARRAY,
+ CATEGORY
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/annotations/Category.java b/Common/src/main/java/tschipp/carryon/config/annotations/Category.java
new file mode 100644
index 0000000..e2cbd08
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/annotations/Category.java
@@ -0,0 +1,12 @@
+package tschipp.carryon.config.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Category {
+ String value();
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/annotations/Config.java b/Common/src/main/java/tschipp/carryon/config/annotations/Config.java
new file mode 100644
index 0000000..897d47c
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/annotations/Config.java
@@ -0,0 +1,12 @@
+package tschipp.carryon.config.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Config {
+ String value();
+}
diff --git a/Common/src/main/java/tschipp/carryon/config/annotations/Property.java b/Common/src/main/java/tschipp/carryon/config/annotations/Property.java
new file mode 100644
index 0000000..680949f
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/config/annotations/Property.java
@@ -0,0 +1,24 @@
+package tschipp.carryon.config.annotations;
+
+import tschipp.carryon.config.PropertyType;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Property {
+
+
+
+ PropertyType type();
+ String description();
+
+ int min() default Integer.MIN_VALUE;
+ int max() default Integer.MAX_VALUE;
+
+ double minD() default Double.MIN_VALUE;
+ double maxD() default Double.MAX_VALUE;
+}
diff --git a/Common/src/main/java/tschipp/carryon/mixin/HumanoidModelMixin.java b/Common/src/main/java/tschipp/carryon/mixin/HumanoidModelMixin.java
new file mode 100644
index 0000000..0df344f
--- /dev/null
+++ b/Common/src/main/java/tschipp/carryon/mixin/HumanoidModelMixin.java
@@ -0,0 +1,55 @@
+package tschipp.carryon.mixin;
+
+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 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.CarryOnData;
+import tschipp.carryon.common.carry.CarryOnDataManager;
+
+@Mixin(HumanoidModel.class)
+public class HumanoidModelMixin {
+
+ @Shadow
+ public ModelPart rightArm;
+
+ @Shadow
+ public ModelPart leftArm;
+
+ @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;
+
+ rightArm.yRot = 0;
+ leftArm.yRot = 0;
+
+ rightArm.xRot = -x;
+ leftArm.xRot = -x;
+
+ rightArm.zRot = z;
+ leftArm.zRot = -z;
+ }
+
+ }
+ }
+
+}
diff --git a/Common/src/main/java/tschipp/carryon/mixin/PlayerMixin.java b/Common/src/main/java/tschipp/carryon/mixin/PlayerMixin.java
index f11a43c..9e31831 100644
--- a/Common/src/main/java/tschipp/carryon/mixin/PlayerMixin.java
+++ b/Common/src/main/java/tschipp/carryon/mixin/PlayerMixin.java
@@ -23,6 +23,7 @@ public abstract class PlayerMixin extends LivingEntity {
@Inject(method = "defineSynchedData()V", at = @At("RETURN"))
private void onDefineSynchedData(CallbackInfo info) {
this.entityData.define(CarryOnDataManager.CARRY_DATA_KEY, new CompoundTag());
+ System.out.println("Added Carry Data!");
}
@Inject(method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN"))
diff --git a/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java b/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java
index b62b62e..ce27a98 100644
--- a/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java
+++ b/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java
@@ -1,5 +1,7 @@
package tschipp.carryon.platform.services;
+import tschipp.carryon.config.BuiltConfig;
+
public interface IPlatformHelper {
/**
@@ -23,4 +25,6 @@ public interface IPlatformHelper {
* @return True if in a development environment, false otherwise.
*/
boolean isDevelopmentEnvironment();
+
+ void registerConfig(BuiltConfig cfg);
}
diff --git a/Common/src/main/resources/assets/carryon/logo.png b/Common/src/main/resources/assets/carryon/logo.png
new file mode 100644
index 0000000..1b9a978
Binary files /dev/null and b/Common/src/main/resources/assets/carryon/logo.png differ
diff --git a/Common/src/main/resources/carryon.mixins.json b/Common/src/main/resources/carryon.mixins.json
index 4879127..ec19c7d 100644
--- a/Common/src/main/resources/carryon.mixins.json
+++ b/Common/src/main/resources/carryon.mixins.json
@@ -8,7 +8,8 @@
"PlayerMixin"
],
"client": [
- "MinecraftMixin"
+ "MinecraftMixin",
+ "HumanoidModelMixin"
],
"server": [
],
diff --git a/Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java b/Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java
index 955c14e..9bc2e24 100644
--- a/Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java
+++ b/Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java
@@ -1,6 +1,10 @@
package tschipp.carryon;
import net.fabricmc.api.ModInitializer;
+import tschipp.carryon.config.fabric.ConfigLoaderImpl;
+import tschipp.carryon.events.CommonEvents;
+
+import java.io.IOException;
public class CarryOnFabricMod implements ModInitializer {
@@ -13,6 +17,14 @@ public class CarryOnFabricMod implements ModInitializer {
// Use Fabric to bootstrap the Common mod.
Constants.LOG.info("Hello Fabric world!");
+ try {
+ ConfigLoaderImpl.initialize();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ CommonEvents.registerEvents();
+
}
}
diff --git a/Fabric/src/main/java/tschipp/carryon/config/fabric/ConfigLoaderImpl.java b/Fabric/src/main/java/tschipp/carryon/config/fabric/ConfigLoaderImpl.java
new file mode 100644
index 0000000..972653c
--- /dev/null
+++ b/Fabric/src/main/java/tschipp/carryon/config/fabric/ConfigLoaderImpl.java
@@ -0,0 +1,131 @@
+package tschipp.carryon.config.fabric;
+
+import com.google.gson.*;
+import net.fabricmc.loader.api.FabricLoader;
+import org.apache.commons.io.FileUtils;
+import tschipp.carryon.config.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ConfigLoaderImpl {
+
+ private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
+
+ //Default JSON and config data.
+ public static final Map CONFIGS = new HashMap<>();
+
+ public static void initialize() throws IOException {
+ Path cfgPath = FabricLoader.getInstance().getConfigDir();
+
+ for (Map.Entry entry : CONFIGS.entrySet()) {
+ File cfgFile = new File(cfgPath.toFile(), entry.getValue().fileName+".json");
+ if (!cfgFile.exists()) {
+ cfgPath.toFile().mkdirs();
+ FileUtils.write(cfgFile, GSON.toJson(entry.getKey()), StandardCharsets.UTF_8);
+ } else {
+ JsonObject cfgJson = GSON.fromJson(FileUtils.readFileToString(cfgFile, StandardCharsets.UTF_8), JsonObject.class);
+ FileUtils.write(cfgFile, GSON.toJson(loadConfig(entry.getValue(), cfgJson)), StandardCharsets.UTF_8);
+ }
+ }
+ }
+
+ private static JsonObject loadConfig(BuiltCategory category, JsonObject config) {
+ config.entrySet().forEach((entry) -> {
+ String id = entry.getKey();
+ if (!id.startsWith("//")) {
+ JsonElement value = entry.getValue();
+ if (value instanceof JsonPrimitive configValue) {
+ category.getProperty(id).ifPresent(data -> {
+ if (configValue.isBoolean() && data.data().type().equals(PropertyType.BOOLEAN))
+ data.setBoolean(configValue.getAsBoolean());
+ if (configValue.isNumber() && data.data().type().equals(PropertyType.INT)) {
+ int configInt = configValue.getAsInt();
+ if (configInt > data.data().max() || configInt < data.data().min()) {
+ try {
+ config.addProperty(id, data.getInt());
+ } catch (IllegalAccessException ignored) {
+ }
+ } else {
+ data.setInt(configInt);
+ }
+ }
+ if (configValue.isNumber() && data.data().type().equals(PropertyType.DOUBLE)) {
+ double configDouble = configValue.getAsDouble();
+ if (configDouble > data.data().maxD() || configDouble < data.data().minD()) {
+ try {
+ config.addProperty(id, data.getDouble());
+ } catch (IllegalAccessException ignored) {
+ }
+ } else {
+ data.setDouble(configDouble);
+ }
+ }
+ });
+ } else if (value instanceof JsonObject subConfig) {
+ category.getCategory(id).ifPresent(cat -> loadConfig(cat, subConfig));
+ } else if (value instanceof JsonArray list) {
+ category.getProperty(id).ifPresent(data -> {
+ if(data.data().type() == PropertyType.STRING_ARRAY)
+ {
+ List ls = new ArrayList<>();
+ for(JsonElement arrEle : list)
+ {
+ if(arrEle instanceof JsonPrimitive p && p.isString())
+ {
+ ls.add(p.getAsString());
+ }
+ }
+ data.setStringArray(ls.toArray(new String[ls.size()]));
+ }
+ });
+ }
+ }
+ });
+ ConfigLoader.onConfigLoaded();
+ return config;
+ }
+
+ public static void registerConfig(BuiltConfig config) {
+ try {
+ JsonObject configJson = new JsonObject();
+ for (PropertyData property : config.properties) buildProperty(configJson, property);
+ for (BuiltCategory category : config.categories) buildCategory(configJson, category);
+ CONFIGS.put(configJson, config);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void buildCategory(JsonObject builder, BuiltCategory category) throws IllegalAccessException {
+ JsonObject categoryJson = new JsonObject();
+ if (category.categoryDesc != null) categoryJson.addProperty("//"+category.category, category.categoryDesc);
+ for (PropertyData property : category.properties) buildProperty(categoryJson, property);
+ for (BuiltCategory builtCategory : category.categories) buildCategory(categoryJson, builtCategory);
+ builder.add(category.category, categoryJson);
+ }
+
+ private static void buildProperty(JsonObject builder, PropertyData data) throws IllegalAccessException {
+ AnnotationData annotationData = data.data();
+ builder.addProperty("//"+data.getId(), annotationData.description());
+
+ switch (annotationData.type()) {
+ case BOOLEAN -> builder.addProperty(data.getId(), data.getBoolean());
+ case INT -> builder.addProperty(data.getId(), data.getInt());
+ case DOUBLE -> builder.addProperty(data.getId(), data.getDouble());
+ case STRING_ARRAY -> {
+ JsonArray arr = new JsonArray();
+ for(String s : data.getStringArray())
+ arr.add(s);
+ builder.add(data.getId(), arr);
+ }
+ default -> throw new IllegalAccessException("Unknown property type.");
+ }
+ }
+}
diff --git a/Fabric/src/main/java/tschipp/carryon/events/ClientEvents.java b/Fabric/src/main/java/tschipp/carryon/events/ClientEvents.java
new file mode 100644
index 0000000..0efba9a
--- /dev/null
+++ b/Fabric/src/main/java/tschipp/carryon/events/ClientEvents.java
@@ -0,0 +1,4 @@
+package tschipp.carryon.events;
+
+public class ClientEvents {
+}
diff --git a/Fabric/src/main/java/tschipp/carryon/events/CommonEvents.java b/Fabric/src/main/java/tschipp/carryon/events/CommonEvents.java
new file mode 100644
index 0000000..5cd490c
--- /dev/null
+++ b/Fabric/src/main/java/tschipp/carryon/events/CommonEvents.java
@@ -0,0 +1,75 @@
+package tschipp.carryon.events;
+
+import net.fabricmc.fabric.api.event.player.UseBlockCallback;
+import net.fabricmc.fabric.api.event.player.UseEntityCallback;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionResult;
+import tschipp.carryon.common.carry.CarryOnData;
+import tschipp.carryon.common.carry.CarryOnDataManager;
+import tschipp.carryon.common.carry.PickupHandler;
+import tschipp.carryon.common.carry.PlacementHandler;
+
+public class CommonEvents {
+
+ public static void registerEvents() {
+
+ UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
+
+ if(world.isClientSide)
+ return InteractionResult.PASS;
+
+ BlockPos pos = hitResult.getBlockPos();
+ Direction facing = hitResult.getDirection();
+
+ CarryOnData carry = CarryOnDataManager.getCarryData(player);
+ if(!carry.isCarrying())
+ {
+ if (PickupHandler.tryPickUpBlock((ServerPlayer) player, pos, world))
+ return InteractionResult.SUCCESS;
+ return InteractionResult.PASS;
+ }
+ else
+ {
+ if(carry.isCarrying(CarryOnData.CarryType.BLOCK))
+ {
+ if(PlacementHandler.tryPlaceBlock((ServerPlayer) player, pos, facing, null))
+ return InteractionResult.SUCCESS;
+ }
+ else
+ {
+ if(PlacementHandler.tryPlaceEntity((ServerPlayer) player, pos, facing, null))
+ return InteractionResult.SUCCESS;
+ }
+
+ //Fail here, so that we don't interact with placed things
+ return InteractionResult.FAIL;
+ }
+ });
+
+
+
+
+ UseEntityCallback.EVENT.register((player, level, hand, entity, hitResult) -> {
+
+ if(level.isClientSide)
+ return InteractionResult.PASS;
+
+ CarryOnData carry = CarryOnDataManager.getCarryData(player);
+ if (!carry.isCarrying()) {
+ if (PickupHandler.tryPickupEntity((ServerPlayer) player, entity)) {
+ return InteractionResult.SUCCESS;
+ }
+ }
+ else if(carry.isCarrying(CarryOnData.CarryType.ENTITY))
+ {
+ //TODO: Stacking
+ }
+
+ return InteractionResult.PASS;
+ });
+
+ }
+
+}
diff --git a/Fabric/src/main/java/tschipp/carryon/platform/FabricPlatformHelper.java b/Fabric/src/main/java/tschipp/carryon/platform/FabricPlatformHelper.java
index bd10051..93e37a3 100644
--- a/Fabric/src/main/java/tschipp/carryon/platform/FabricPlatformHelper.java
+++ b/Fabric/src/main/java/tschipp/carryon/platform/FabricPlatformHelper.java
@@ -1,5 +1,7 @@
package tschipp.carryon.platform;
+import tschipp.carryon.config.BuiltConfig;
+import tschipp.carryon.config.fabric.ConfigLoaderImpl;
import tschipp.carryon.platform.services.IPlatformHelper;
import net.fabricmc.loader.api.FabricLoader;
@@ -21,4 +23,9 @@ public class FabricPlatformHelper implements IPlatformHelper {
return FabricLoader.getInstance().isDevelopmentEnvironment();
}
+
+ @Override
+ public void registerConfig(BuiltConfig cfg) {
+ ConfigLoaderImpl.registerConfig(cfg);
+ }
}
diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json
index 160567a..098c01b 100644
--- a/Fabric/src/main/resources/fabric.mod.json
+++ b/Fabric/src/main/resources/fabric.mod.json
@@ -1,12 +1,12 @@
{
"schemaVersion": 1,
- "id": "modid",
+ "id": "carryon",
"version": "${version}",
- "name": "Example Mod",
+ "name": "Carry On",
"description": "This is an example description! Tell everyone what your mod is about!",
"authors": [
- "Me!"
+ "Tschipp"
],
"contact": {
"homepage": "https://fabricmc.net/",
@@ -14,7 +14,7 @@
},
"license": "CC0-1.0",
- "icon": "assets/modid/icon.png",
+ "icon": "assets/carryon/logo.png",
"environment": "*",
"entrypoints": {
@@ -23,7 +23,8 @@
]
},
"mixins": [
- "carryon.fabric.mixins.json"
+ "carryon.fabric.mixins.json",
+ "carryon.mixins.json"
],
"depends": {
@@ -31,9 +32,6 @@
"fabric": "*",
"minecraft": "1.19.x",
"java": ">=17"
- },
- "suggests": {
- "another-mod": "*"
}
}
\ No newline at end of file
diff --git a/Forge/src/main/java/tschipp/carryon/CarryOnForge.java b/Forge/src/main/java/tschipp/carryon/CarryOnForge.java
index 46799c3..1684936 100644
--- a/Forge/src/main/java/tschipp/carryon/CarryOnForge.java
+++ b/Forge/src/main/java/tschipp/carryon/CarryOnForge.java
@@ -1,6 +1,7 @@
package tschipp.carryon;
import net.minecraftforge.fml.common.Mod;
+import tschipp.carryon.config.forge.ConfigLoaderImpl;
@Mod(Constants.MOD_ID)
public class CarryOnForge {
@@ -13,6 +14,8 @@ public class CarryOnForge {
// Use Forge to bootstrap the Common mod.
Constants.LOG.info("Hello Forge world!");
+
+ ConfigLoaderImpl.initialize();
}
}
\ No newline at end of file
diff --git a/Forge/src/main/java/tschipp/carryon/config/forge/ConfigLoaderImpl.java b/Forge/src/main/java/tschipp/carryon/config/forge/ConfigLoaderImpl.java
new file mode 100644
index 0000000..754206b
--- /dev/null
+++ b/Forge/src/main/java/tschipp/carryon/config/forge/ConfigLoaderImpl.java
@@ -0,0 +1,102 @@
+package tschipp.carryon.config.forge;
+
+import com.electronwill.nightconfig.core.AbstractConfig;
+import com.electronwill.nightconfig.core.UnmodifiableConfig;
+import net.minecraftforge.common.ForgeConfigSpec;
+import net.minecraftforge.eventbus.api.IEventBus;
+import net.minecraftforge.fml.ModLoadingContext;
+import net.minecraftforge.fml.config.IConfigSpec;
+import net.minecraftforge.fml.config.ModConfig;
+import net.minecraftforge.fml.event.config.ModConfigEvent;
+import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
+import tschipp.carryon.config.*;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ConfigLoaderImpl {
+
+ public static final Map CONFIGS = new HashMap<>();
+
+ public static void initialize() {
+ IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
+ bus.addListener(ConfigLoaderImpl::onConfigLoad);
+ bus.addListener(ConfigLoaderImpl::onConfigReload);
+
+ ConfigLoaderImpl.CONFIGS.forEach((spec, config) -> {
+ if(config.fileName.contains("client"))
+ ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, spec, config.fileName+".toml");
+ else
+ ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, spec, config.fileName+".toml");
+ });
+ }
+
+ public static void onConfigLoad(ModConfigEvent.Loading loading) {
+ loadConfig(loading.getConfig().getSpec());
+ ConfigLoader.onConfigLoaded();
+ }
+
+ public static void onConfigReload(ModConfigEvent.Reloading loading) {
+ loadConfig(loading.getConfig().getSpec());
+ ConfigLoader.onConfigLoaded();
+ }
+
+ private static void loadConfig(IConfigSpec spec) {
+ BuiltConfig builtConfig = CONFIGS.get(spec.self());
+ if (builtConfig == null) return;
+ loadConfig(builtConfig, spec.self().getValues());
+ }
+
+ private static void loadConfig(BuiltCategory category, UnmodifiableConfig config) {
+ config.valueMap().forEach((id, value) -> {
+ if (value instanceof ForgeConfigSpec.ConfigValue> configValue) {
+ category.getProperty(id).ifPresent(data -> {
+ if (configValue instanceof ForgeConfigSpec.BooleanValue booleanValue)
+ data.setBoolean(booleanValue.get());
+ if (configValue instanceof ForgeConfigSpec.IntValue intValue)
+ data.setInt(intValue.get());
+ if (configValue instanceof ForgeConfigSpec.DoubleValue doubleValue)
+ data.setDouble(doubleValue.get());
+ if(configValue.get() instanceof List> listVal)
+ data.setStringArray(listVal.toArray(new String[listVal.size()]));
+ });
+ } else if (value instanceof AbstractConfig subConfig) {
+ category.getCategory(id).ifPresent(cat -> loadConfig(cat, subConfig));
+ }
+ });
+ }
+
+ public static void registerConfig(BuiltConfig config) {
+ try {
+ ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
+ for (PropertyData property : config.properties) buildProperty(builder, property);
+ for (BuiltCategory category : config.categories) buildCategory(builder, category);
+ CONFIGS.put(builder.build(), config);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void buildCategory(ForgeConfigSpec.Builder builder, BuiltCategory category) throws IllegalAccessException {
+ builder.push(category.category);
+ if (category.categoryDesc != null) builder.comment(category.categoryDesc);
+ for (PropertyData property : category.properties) buildProperty(builder, property);
+ for (BuiltCategory builtCategory : category.categories) buildCategory(builder, builtCategory);
+ builder.pop();
+ }
+
+ private static void buildProperty(ForgeConfigSpec.Builder builder, PropertyData data) throws IllegalAccessException {
+ AnnotationData annotationData = data.data();
+ builder.comment(annotationData.description());
+
+ switch (annotationData.type()) {
+ case BOOLEAN -> builder.define(data.getId(), data.getBoolean());
+ case INT -> builder.defineInRange(data.getId(), data.getInt(), annotationData.min(), annotationData.max());
+ case DOUBLE -> builder.defineInRange(data.getId(), data.getDouble(), annotationData.minD(), annotationData.maxD());
+ case STRING_ARRAY -> builder.defineList(data.getId(), Arrays.asList(data.getStringArray()), obj -> obj instanceof String);
+ default -> throw new IllegalAccessException("Unknown property type.");
+ }
+ }
+}
diff --git a/Forge/src/main/java/tschipp/carryon/events/ClientEvents.java b/Forge/src/main/java/tschipp/carryon/events/ClientEvents.java
index 233616d..05d6ec0 100644
--- a/Forge/src/main/java/tschipp/carryon/events/ClientEvents.java
+++ b/Forge/src/main/java/tschipp/carryon/events/ClientEvents.java
@@ -24,8 +24,9 @@ public class ClientEvents {
MultiBufferSource buffer = event.getMultiBufferSource();
PoseStack matrix = event.getPoseStack();
int light = event.getPackedLight();
+ float partialTicks = event.getPartialTick();
- if(CarriedObjectRender.drawFirstPerson(player, buffer, matrix, light) && CarryRenderHelper.getPerspective() == 0)
+ if(CarriedObjectRender.drawFirstPerson(player, buffer, matrix, light, partialTicks) && CarryRenderHelper.getPerspective() == 0)
event.setCanceled(true);
}
}
diff --git a/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java b/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java
index f67beca..8c9961f 100644
--- a/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java
+++ b/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java
@@ -25,7 +25,6 @@ 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)
{
@@ -39,12 +38,12 @@ public class CommonEvents
if (level.isClientSide)
return;
- boolean cancel = false;
+ boolean success = false;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (!carry.isCarrying()) {
if (PickupHandler.tryPickUpBlock((ServerPlayer) player, pos, level)) {
- cancel = true;
+ success = true;
}
} else {
if (carry.isCarrying(CarryType.BLOCK)) {
@@ -54,23 +53,23 @@ public class CommonEvents
MinecraftForge.EVENT_BUS.post(event1);
return !event1.isCanceled();
})) {
- cancel = true;
+ success = true;
}
} else {
+ //TODO: Entity place perms
if (PlacementHandler.tryPlaceEntity((ServerPlayer) player,pos, event.getFace(), null))
{
- cancel = true;
+ success = true;
}
}
}
- if(cancel)
+ if(success)
{
event.setUseBlock(Event.Result.DENY);
event.setUseItem(Event.Result.DENY);
event.setCancellationResult(InteractionResult.SUCCESS);
event.setCanceled(true);
- return;
}
}
diff --git a/Forge/src/main/java/tschipp/carryon/platform/ForgePlatformHelper.java b/Forge/src/main/java/tschipp/carryon/platform/ForgePlatformHelper.java
index 8d24bb7..12f42ae 100644
--- a/Forge/src/main/java/tschipp/carryon/platform/ForgePlatformHelper.java
+++ b/Forge/src/main/java/tschipp/carryon/platform/ForgePlatformHelper.java
@@ -1,5 +1,7 @@
package tschipp.carryon.platform;
+import tschipp.carryon.config.BuiltConfig;
+import tschipp.carryon.config.forge.ConfigLoaderImpl;
import tschipp.carryon.platform.services.IPlatformHelper;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.FMLLoader;
@@ -23,4 +25,9 @@ public class ForgePlatformHelper implements IPlatformHelper {
return !FMLLoader.isProduction();
}
+
+ @Override
+ public void registerConfig(BuiltConfig cfg) {
+ ConfigLoaderImpl.registerConfig(cfg);
+ }
}