Merge pull request #185 from CreepyCre/1.16-fabric
Various fixes + Pocket Loader & Placer Rewrite
This commit is contained in:
commit
751a9d1770
89 changed files with 3432 additions and 490 deletions
|
@ -1,26 +1,27 @@
|
|||
package org.dimdev.dimdoors;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.block.entity.ModBlockEntityTypes;
|
||||
import org.dimdev.dimdoors.client.ModSkyRendering;
|
||||
import org.dimdev.dimdoors.entity.ModEntityTypes;
|
||||
import org.dimdev.dimdoors.entity.MonolithEntity;
|
||||
import org.dimdev.dimdoors.fluid.ModFluids;
|
||||
import org.dimdev.dimdoors.network.s2c.PlayerInventorySlotUpdateS2CPacket;
|
||||
import org.dimdev.dimdoors.particle.ModParticleTypes;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class DimensionalDoorsClientInitializer implements ClientModInitializer {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ModEntityTypes.initClient();
|
||||
|
@ -31,5 +32,18 @@ public class DimensionalDoorsClientInitializer implements ClientModInitializer {
|
|||
ModParticleTypes.initClient();
|
||||
|
||||
ClientPlayNetworking.registerGlobalReceiver(DimensionalDoorsInitializer.MONOLITH_PARTICLE_PACKET, (client, networkHandler, buf, sender) -> MonolithEntity.spawnParticles(buf, client));
|
||||
|
||||
// TODO: change this to a normal Receiver with the inventory network handler attached. Will have to register/ unregister when a player joins/ leaves a world
|
||||
ClientPlayNetworking.registerGlobalReceiver(PlayerInventorySlotUpdateS2CPacket.ID, (minecraftClient, clientPlayNetworkHandler, packetByteBuf, packetSender) -> {
|
||||
PlayerInventorySlotUpdateS2CPacket packet = new PlayerInventorySlotUpdateS2CPacket();
|
||||
try {
|
||||
packet.read(packetByteBuf);
|
||||
minecraftClient.player.inventory.setStack(packet.getSlot(), packet.getStack());
|
||||
// TODO: remove commented out debug code
|
||||
//LOGGER.info("Synced slot " + packet.getSlot() + " with item stack " + packet.getStack().toTag(new CompoundTag()));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package org.dimdev.dimdoors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import me.sargunvohra.mcmods.autoconfig1u.ConfigHolder;
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.block.entity.ModBlockEntityTypes;
|
||||
import org.dimdev.dimdoors.command.ModCommands;
|
||||
|
@ -10,13 +15,17 @@ import org.dimdev.dimdoors.entity.ModEntityTypes;
|
|||
import org.dimdev.dimdoors.entity.stat.ModStats;
|
||||
import org.dimdev.dimdoors.fluid.ModFluids;
|
||||
import org.dimdev.dimdoors.item.ModItems;
|
||||
import org.dimdev.dimdoors.item.RiftConfigurationToolItem;
|
||||
import org.dimdev.dimdoors.network.c2s.HitBlockS2CPacket;
|
||||
import org.dimdev.dimdoors.particle.ModParticleTypes;
|
||||
import org.dimdev.dimdoors.pockets.SchematicHandler;
|
||||
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
||||
import org.dimdev.dimdoors.pockets.generator.PocketGenerator;
|
||||
import org.dimdev.dimdoors.pockets.virtual.VirtualSingularPocket;
|
||||
import org.dimdev.dimdoors.pockets.modifier.Modifier;
|
||||
import org.dimdev.dimdoors.rift.targets.Targets;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.sound.ModSoundEvents;
|
||||
import org.dimdev.dimdoors.util.schematic.v2.SchematicTest;
|
||||
import org.dimdev.dimdoors.world.ModBiomes;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.feature.ModFeatures;
|
||||
|
@ -30,13 +39,13 @@ import net.minecraft.world.World;
|
|||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
public class DimensionalDoorsInitializer implements ModInitializer {
|
||||
public static final Identifier MONOLITH_PARTICLE_PACKET = new Identifier("dimdoors", "monolith_particle_packet");
|
||||
public static ConfigHolder<ModConfig> CONFIG_MANAGER;
|
||||
public static ModConfig CONFIG;
|
||||
|
||||
private static Map<UUID, ServerPlayNetworkHandler> UUID_SERVER_PLAY_NETWORK_HANDLER_MAP = new HashMap<>();
|
||||
private static MinecraftServer server;
|
||||
|
||||
@NotNull
|
||||
|
@ -55,13 +64,6 @@ public class DimensionalDoorsInitializer implements ModInitializer {
|
|||
public void onInitialize() {
|
||||
ServerLifecycleEvents.SERVER_STARTING.register((minecraftServer) -> {
|
||||
server = minecraftServer;
|
||||
if (FabricLoader.getInstance().isDevelopmentEnvironment()) {
|
||||
try {
|
||||
SchematicTest.test();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ModBlocks.init();
|
||||
|
@ -81,7 +83,18 @@ public class DimensionalDoorsInitializer implements ModInitializer {
|
|||
Targets.registerDefaultTargets();
|
||||
VirtualTarget.VirtualTargetType.register();
|
||||
|
||||
VirtualSingularPocket.VirtualSingularPocketType.register();
|
||||
|
||||
Modifier.ModifierType.register();
|
||||
|
||||
PocketGenerator.PocketGeneratorType.register();
|
||||
|
||||
SchematicV2Handler.getInstance().load();
|
||||
SchematicHandler.INSTANCE.loadSchematics();
|
||||
|
||||
|
||||
AttackBlockCallback.EVENT.register(RiftConfigurationToolItem::onAttackBlockCallback);
|
||||
|
||||
ServerPlayNetworking.registerGlobalReceiver(HitBlockS2CPacket.ID, RiftConfigurationToolItem::receiveHitBlock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package org.dimdev.dimdoors.block;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.util.DyeColor;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
|
||||
public class AncientFabricBlock extends Block {
|
||||
public AncientFabricBlock(DyeColor color) {
|
||||
super(FabricBlockSettings.of(Material.STONE, color).strength(-1.0F, 3600000.0F).dropsNothing());
|
||||
}
|
||||
|
||||
}
|
|
@ -11,10 +11,13 @@ import net.minecraft.block.Block;
|
|||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.MaterialColor;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -79,4 +82,13 @@ public class DetachedRiftBlock extends Block implements RiftProvider<DetachedRif
|
|||
public BlockRenderType getRenderType(BlockState state) {
|
||||
return BlockRenderType.ENTITYBLOCK_ANIMATED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getRaycastShape(BlockState state, BlockView world, BlockPos pos) {
|
||||
return VoxelShapes.fullCube();
|
||||
}
|
||||
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return VoxelShapes.fullCube();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ import net.minecraft.util.ActionResult;
|
|||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -96,4 +98,9 @@ public class DimensionalDoorBlock extends DoorBlock implements RiftProvider<Entr
|
|||
throw new IllegalStateException("Dimensional door at " + pos + " in world " + world + " contained no rift.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getRaycastShape(BlockState state, BlockView world, BlockPos pos) {
|
||||
return VoxelShapes.fullCube();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import net.minecraft.util.BlockMirror;
|
|||
import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -70,4 +72,9 @@ public class DimensionalPortalBlock extends Block implements RiftProvider<Entran
|
|||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
builder.add(FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getRaycastShape(BlockState state, BlockView world, BlockPos pos) {
|
||||
return VoxelShapes.fullCube();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import net.minecraft.util.ActionResult;
|
|||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -53,4 +55,9 @@ public class DimensionalTrapdoorBlock extends TrapdoorBlock implements RiftProvi
|
|||
public EntranceRiftBlockEntity getRift(World world, BlockPos pos, BlockState state) {
|
||||
return (EntranceRiftBlockEntity) world.getBlockEntity(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getRaycastShape(BlockState state, BlockView world, BlockPos pos) {
|
||||
return VoxelShapes.fullCube();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package org.dimdev.dimdoors.block;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Material;
|
||||
|
@ -15,8 +18,9 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import org.dimdev.dimdoors.util.InstanceMap;
|
||||
|
||||
class FabricBlock extends Block {
|
||||
public class FabricBlock extends Block {
|
||||
FabricBlock(DyeColor color) {
|
||||
super(FabricBlockSettings.of(Material.STONE, color).lightLevel(15));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.dimdev.dimdoors.block;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -18,6 +19,9 @@ import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|||
|
||||
public final class ModBlocks {
|
||||
private static final Map<String, Block> BLOCKS = Maps.newLinkedHashMap();
|
||||
private static final Map<DyeColor, Block> FABRIC_BLOCKS = new HashMap<>();
|
||||
private static final Map<DyeColor, Block> ANCIENT_FABRIC_BLOCKS = new HashMap<>();
|
||||
|
||||
public static final Block GOLD_DOOR = register("dimdoors:gold_door", new DoorBlock(FabricBlockSettings.of(Material.METAL, MaterialColor.GOLD).nonOpaque()));
|
||||
public static final Block QUARTZ_DOOR = register("dimdoors:quartz_door", new DoorBlock(FabricBlockSettings.of(Material.STONE, MaterialColor.QUARTZ).nonOpaque()));
|
||||
public static final Block OAK_DIMENSIONAL_DOOR = register("dimdoors:oak_dimensional_door", new DimensionalDoorBlock(FabricBlockSettings.of(Material.WOOD, MaterialColor.WOOD).nonOpaque().lightLevel(state -> ((DimensionalDoorBlock) state.getBlock()).hasBlockEntity(state) ? 10 : 0)));
|
||||
|
@ -74,11 +78,15 @@ public final class ModBlocks {
|
|||
}
|
||||
|
||||
private static Block registerAncientFabric(String id, DyeColor color) {
|
||||
return register(id, new Block(FabricBlockSettings.of(Material.STONE, color).strength(-1.0F, 3600000.0F).dropsNothing()));
|
||||
Block block = new AncientFabricBlock(color);
|
||||
ANCIENT_FABRIC_BLOCKS.put(color, block);
|
||||
return register(id, block);
|
||||
}
|
||||
|
||||
private static Block registerFabric(String id, DyeColor color) {
|
||||
return register(id, new FabricBlock(color));
|
||||
Block block = new FabricBlock(color);
|
||||
FABRIC_BLOCKS.put(color, block);
|
||||
return register(id, block);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
@ -93,6 +101,14 @@ public final class ModBlocks {
|
|||
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ModBlocks.OAK_DIMENSIONAL_DOOR, ModBlocks.GOLD_DIMENSIONAL_DOOR, ModBlocks.IRON_DIMENSIONAL_DOOR, ModBlocks.OAK_DIMENSIONAL_TRAPDOOR, ModBlocks.QUARTZ_DIMENSIONAL_DOOR, ModBlocks.QUARTZ_DOOR);
|
||||
}
|
||||
|
||||
public static Block ancientFabricFromDye(DyeColor color) {
|
||||
return ANCIENT_FABRIC_BLOCKS.get(color);
|
||||
}
|
||||
|
||||
public static Block fabricFromDye(DyeColor color) {
|
||||
return FABRIC_BLOCKS.get(color);
|
||||
}
|
||||
|
||||
private static class DoorBlock extends net.minecraft.block.DoorBlock {
|
||||
public DoorBlock(Settings settings) {
|
||||
super(settings);
|
||||
|
|
|
@ -27,8 +27,8 @@ public class ModBlockEntityTypes {
|
|||
EntranceRiftBlockEntity::new,
|
||||
ModBlocks.OAK_DIMENSIONAL_DOOR, ModBlocks.IRON_DIMENSIONAL_DOOR, ModBlocks.GOLD_DIMENSIONAL_DOOR, ModBlocks.QUARTZ_DIMENSIONAL_DOOR, ModBlocks.DIMENSIONAL_PORTAL);
|
||||
|
||||
private static <E extends BlockEntity> BlockEntityType<E> register(String id, Supplier<? extends E> supplier, Block... blocks) {
|
||||
return Registry.register(Registry.BLOCK_ENTITY_TYPE, id, new BlockEntityType<>(supplier, Sets.newHashSet(blocks), null));
|
||||
private static <E extends BlockEntity> BlockEntityType<E> register(String id, Supplier<E> supplier, Block... blocks) {
|
||||
return Registry.register(Registry.BLOCK_ENTITY_TYPE, id, BlockEntityType.Builder.create(supplier, blocks).build(null));
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
|
|
@ -46,6 +46,7 @@ public abstract class RiftBlockEntity extends BlockEntity implements BlockEntity
|
|||
// NBT
|
||||
@Override
|
||||
public void fromTag(BlockState state, CompoundTag nbt) {
|
||||
super.fromTag(state, nbt);
|
||||
this.deserialize(nbt);
|
||||
}
|
||||
|
||||
|
@ -55,9 +56,8 @@ public abstract class RiftBlockEntity extends BlockEntity implements BlockEntity
|
|||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
this.serialize(tag);
|
||||
|
||||
return super.toTag(tag);
|
||||
super.toTag(tag);
|
||||
return this.serialize(tag);
|
||||
}
|
||||
|
||||
public CompoundTag serialize(CompoundTag tag) {
|
||||
|
@ -110,7 +110,7 @@ public abstract class RiftBlockEntity extends BlockEntity implements BlockEntity
|
|||
}
|
||||
|
||||
public boolean isRegistered() {
|
||||
return !PocketTemplate.isReplacingPlaceholders() && DimensionalRegistry.getRiftRegistry().isRiftAt(new Location((ServerWorld) this.world, this.pos));
|
||||
return !PocketTemplate.isReplacingPlaceholders() && this.world != null && DimensionalRegistry.getRiftRegistry().isRiftAt(new Location((ServerWorld) this.world, this.pos));
|
||||
}
|
||||
|
||||
public void register() {
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Objects;
|
|||
|
||||
import com.flowpowered.math.TrigMath;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.ModConfig;
|
||||
import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity;
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.client.tesseract.Tesseract;
|
||||
|
@ -48,7 +49,7 @@ public class DetachedRiftBlockEntityRenderer extends BlockEntityRenderer<Detache
|
|||
private void renderCrack(VertexConsumer vc, MatrixStack matrices, DetachedRiftBlockEntity rift) {
|
||||
matrices.push();
|
||||
matrices.translate(0.5, 0.5, 0.5);
|
||||
RiftCrackRenderer.drawCrack(matrices.peek().getModel(), vc, 0, CURVE, ModConfig.INSTANCE.getGraphicsConfig().riftSize * rift.size / 150, 0);//0xF1234568L * rift.hashCode());
|
||||
RiftCrackRenderer.drawCrack(matrices.peek().getModel(), vc, 0, CURVE, DimensionalDoorsInitializer.CONFIG.getGraphicsConfig().riftSize * rift.size / 150, 0);//0xF1234568L * rift.hashCode());
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@ package org.dimdev.dimdoors.item;
|
|||
import java.util.Objects;
|
||||
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.block.DimensionalPortalBlock;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity;
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
|
|
@ -1,8 +1,22 @@
|
|||
package org.dimdev.dimdoors.item;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
|
||||
import net.minecraft.client.item.TooltipContext;
|
||||
|
@ -16,14 +30,19 @@ import net.minecraft.util.ActionResult;
|
|||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.api.Environment;
|
||||
import org.dimdev.dimdoors.network.c2s.HitBlockS2CPacket;
|
||||
import org.dimdev.dimdoors.network.s2c.PlayerInventorySlotUpdateS2CPacket;
|
||||
import org.dimdev.dimdoors.rift.targets.IdMarker;
|
||||
import org.dimdev.dimdoors.util.EntityUtils;
|
||||
import org.dimdev.dimdoors.world.level.Counter;
|
||||
|
||||
import static net.fabricmc.api.EnvType.CLIENT;
|
||||
|
||||
public class RiftConfigurationToolItem extends Item {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public static final String ID = "rift_configuration_tool";
|
||||
|
||||
|
@ -37,24 +56,80 @@ public class RiftConfigurationToolItem extends Item {
|
|||
HitResult hit = player.raycast(RaycastHelper.REACH_DISTANCE, 0, false);
|
||||
|
||||
if (world.isClient) {
|
||||
if (!RaycastHelper.hitsRift(hit, world)) {
|
||||
player.sendMessage(new TranslatableText("tools.rift_miss"), true);
|
||||
RiftBlockEntity.showRiftCoreUntil = System.currentTimeMillis() + DimensionalDoorsInitializer.CONFIG.getGraphicsConfig().highlightRiftCoreFor;
|
||||
return TypedActionResult.fail(stack);
|
||||
} else {
|
||||
Counter counter = Counter.get(stack);
|
||||
|
||||
if (RaycastHelper.hitsRift(hit, world)) {
|
||||
RiftBlockEntity rift = (RiftBlockEntity) world.getBlockEntity(((BlockHitResult) hit).getBlockPos());
|
||||
|
||||
if (rift.getDestination() instanceof IdMarker && ((IdMarker) rift.getDestination()).getId() >= 0) {
|
||||
EntityUtils.chat(player, Text.of("Id: " + ((IdMarker) rift.getDestination()).getId()));
|
||||
} else {
|
||||
int id = counter.increment();
|
||||
sync(stack, player, hand);
|
||||
EntityUtils.chat(player, Text.of("Rift stripped of data and set to target id: " + id));
|
||||
|
||||
rift.setDestination(new IdMarker(id));
|
||||
}
|
||||
|
||||
return TypedActionResult.success(stack);
|
||||
} else {
|
||||
EntityUtils.chat(player, Text.of("Current Count: " + counter.count()));
|
||||
}
|
||||
return new TypedActionResult<>(ActionResult.FAIL, stack);
|
||||
}
|
||||
|
||||
if (RaycastHelper.hitsRift(hit, world)) {
|
||||
RiftBlockEntity rift = (RiftBlockEntity) world.getBlockEntity(new BlockPos(hit.getPos()));
|
||||
|
||||
System.out.println(rift);
|
||||
|
||||
//TODO: implement this tool's functionality
|
||||
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||
}
|
||||
return new TypedActionResult<>(ActionResult.FAIL, stack);
|
||||
return TypedActionResult.success(stack);
|
||||
}
|
||||
|
||||
public static ActionResult onAttackBlockCallback(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) {
|
||||
if (world.isClient && player.isSneaking() && player.getStackInHand(hand).getItem() instanceof RiftConfigurationToolItem) {
|
||||
if(Counter.get(player.getStackInHand(hand)).count() != -1 || world.getBlockEntity(pos) instanceof RiftBlockEntity) {
|
||||
HitBlockS2CPacket packet = new HitBlockS2CPacket(hand, pos, direction);
|
||||
try {
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
packet.write(buf);
|
||||
ClientPlayNetworking.send(HitBlockS2CPacket.ID, buf);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
public static void receiveHitBlock(MinecraftServer server, ServerPlayerEntity player, ServerPlayNetworkHandler networkHandler, PacketByteBuf buf, PacketSender sender) {
|
||||
HitBlockS2CPacket packet = new HitBlockS2CPacket();
|
||||
try {
|
||||
packet.read(buf);
|
||||
server.execute(() -> serverThreadReceiveHitBlock(player, packet.getHand(), packet.getPos()));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void serverThreadReceiveHitBlock(ServerPlayerEntity player, Hand hand, BlockPos pos) {
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
if (player.isSneaking() && stack.getItem() instanceof RiftConfigurationToolItem) {
|
||||
BlockEntity blockEntity = player.getServerWorld().getBlockEntity(pos);
|
||||
if (blockEntity instanceof RiftBlockEntity) {
|
||||
RiftBlockEntity rift = (RiftBlockEntity) blockEntity;
|
||||
if (!(rift.getDestination() instanceof IdMarker) || ((IdMarker) rift.getDestination()).getId() != -1) {
|
||||
rift.setDestination(new IdMarker(-1));
|
||||
EntityUtils.chat(player, Text.of("Rift stripped of data and set to invalid id: -1"));
|
||||
}
|
||||
} else if (Counter.get(stack).count() != -1){
|
||||
Counter.get(stack).set(-1);
|
||||
((RiftConfigurationToolItem) stack.getItem()).sync(stack, player, hand);
|
||||
|
||||
EntityUtils.chat(player, Text.of("Counter has been reset."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Environment(CLIENT)
|
||||
public void appendTooltip(ItemStack itemStack, World world, List<Text> list, TooltipContext tooltipContext) {
|
||||
|
@ -62,4 +137,28 @@ public class RiftConfigurationToolItem extends Item {
|
|||
list.add(new TranslatableText(this.getTranslationKey() + ".info"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getDefaultStack() {
|
||||
ItemStack defaultStack = super.getDefaultStack();
|
||||
Counter.get(defaultStack).set(-1);
|
||||
return defaultStack;
|
||||
}
|
||||
|
||||
private void sync(ItemStack stack, PlayerEntity player, Hand hand) {
|
||||
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
|
||||
PlayerInventorySlotUpdateS2CPacket packet;
|
||||
if (hand == Hand.OFF_HAND) {
|
||||
packet = new PlayerInventorySlotUpdateS2CPacket(45, stack);
|
||||
} else {
|
||||
packet = new PlayerInventorySlotUpdateS2CPacket(serverPlayer.inventory.selectedSlot, stack);
|
||||
}
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
try {
|
||||
packet.write(buf);
|
||||
ServerPlayNetworking.send(serverPlayer, PlayerInventorySlotUpdateS2CPacket.ID, buf);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package org.dimdev.dimdoors.network.c2s;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
// TODO: replace ClientPlayPackListener
|
||||
public class HitBlockS2CPacket implements Packet<ClientPlayPacketListener> {
|
||||
public static Identifier ID = new Identifier("dimdoors:hit_block");
|
||||
|
||||
private Hand hand;
|
||||
private BlockPos pos;
|
||||
private Direction direction;
|
||||
|
||||
|
||||
public HitBlockS2CPacket() {
|
||||
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public HitBlockS2CPacket(Hand hand, BlockPos pos, Direction direction) {
|
||||
this.hand = hand;
|
||||
this.pos = pos;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(PacketByteBuf buf) throws IOException {
|
||||
hand = buf.readEnumConstant(Hand.class);
|
||||
pos = buf.readBlockPos();
|
||||
direction = buf.readEnumConstant(Direction.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) throws IOException {
|
||||
buf.writeEnumConstant(hand);
|
||||
buf.writeBlockPos(pos);
|
||||
buf.writeEnumConstant(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ClientPlayPacketListener listener) {
|
||||
// TODO: write method
|
||||
}
|
||||
|
||||
|
||||
public Hand getHand() {
|
||||
return hand;
|
||||
}
|
||||
|
||||
public BlockPos getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.dimdev.dimdoors.network.s2c;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
// TODO: replace ClientPlayPackListener
|
||||
public class PlayerInventorySlotUpdateS2CPacket implements Packet<ClientPlayPacketListener> {
|
||||
public static Identifier ID = new Identifier("dimdoors:player_inventory_slot_update");
|
||||
|
||||
private int slot;
|
||||
private ItemStack stack;
|
||||
|
||||
public PlayerInventorySlotUpdateS2CPacket() {
|
||||
this.stack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public PlayerInventorySlotUpdateS2CPacket(int slot, ItemStack stack) {
|
||||
this.slot = slot;
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(PacketByteBuf buf) throws IOException {
|
||||
slot = buf.readInt();
|
||||
stack = buf.readItemStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) throws IOException {
|
||||
buf.writeInt(slot);
|
||||
buf.writeItemStack(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ClientPlayPacketListener listener) {
|
||||
// TODO: write method
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public ItemStack getStack() {
|
||||
return stack;
|
||||
}
|
||||
}
|
|
@ -5,8 +5,11 @@ import java.util.Random;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.ModConfig;
|
||||
import org.dimdev.dimdoors.pockets.virtual.reference.PocketGeneratorReference;
|
||||
import org.dimdev.dimdoors.rift.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
@ -26,50 +29,25 @@ public final class PocketGenerator {
|
|||
return pocket;
|
||||
}
|
||||
|
||||
private static Pocket prepareAndPlaceV2Pocket(ServerWorld world, PocketTemplateV2 pocketTemplate, VirtualLocation virtualLocation, boolean setup) {
|
||||
LOGGER.info("Generating pocket from template " + pocketTemplate.getId() + " at virtual location " + virtualLocation);
|
||||
|
||||
Pocket pocket = DimensionalRegistry.getPocketDirectory(world.getRegistryKey()).newPocket();
|
||||
pocketTemplate.place(pocket);
|
||||
pocket.virtualLocation = virtualLocation;
|
||||
return pocket;
|
||||
}
|
||||
|
||||
public static Pocket generatePocketFromTemplate(ServerWorld world, PocketTemplate pocketTemplate, VirtualLocation virtualLocation, boolean setup) {
|
||||
Pocket pocket = prepareAndPlacePocket(world, pocketTemplate, virtualLocation, setup);
|
||||
if (setup) pocketTemplate.setup(pocket, null, null);
|
||||
return pocket;
|
||||
}
|
||||
|
||||
public static Pocket generateV2PocketFromTemplate(ServerWorld world, PocketTemplateV2 pocketTemplate, VirtualLocation virtualLocation, boolean setup) {
|
||||
Pocket pocket = prepareAndPlaceV2Pocket(world, pocketTemplate, virtualLocation, setup);
|
||||
if (setup) {
|
||||
pocketTemplate.setup(pocket, null, null);
|
||||
}
|
||||
return pocket;
|
||||
}
|
||||
|
||||
|
||||
public static Pocket generatePocketFromTemplate(ServerWorld world, PocketTemplate pocketTemplate, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
Pocket pocket = prepareAndPlacePocket(world, pocketTemplate, virtualLocation, true);
|
||||
pocketTemplate.setup(pocket, linkTo, linkProperties);
|
||||
return pocket;
|
||||
}
|
||||
|
||||
public static Pocket generateV2PocketFromTemplate(ServerWorld world, PocketTemplateV2 pocketTemplate, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
Pocket pocket = prepareAndPlaceV2Pocket(world, pocketTemplate, virtualLocation, true);
|
||||
pocketTemplate.setup(pocket, linkTo, linkProperties);
|
||||
return pocket;
|
||||
}
|
||||
|
||||
public static Pocket generatePrivatePocket(VirtualLocation virtualLocation) {
|
||||
PocketTemplate pocketTemplate = SchematicHandler.INSTANCE.getPersonalPocketTemplate();
|
||||
return generatePocketFromTemplate(DimensionalDoorsInitializer.getWorld(ModDimensions.PERSONAL), pocketTemplate, virtualLocation, true);
|
||||
}
|
||||
|
||||
public static Pocket generatePrivatePocketV2(VirtualLocation virtualLocation) {
|
||||
PocketTemplateV2 pocketTemplate = SchematicV2Handler.getInstance().getRandomPrivatePocket();
|
||||
return generateV2PocketFromTemplate(DimensionalDoorsInitializer.getWorld(ModDimensions.PERSONAL), pocketTemplate, virtualLocation, true);
|
||||
return generateFromPocketGroupV2(DimensionalDoorsInitializer.getWorld(ModDimensions.PERSONAL), "private", virtualLocation, null, null);
|
||||
}
|
||||
|
||||
// TODO: size of public pockets should increase with depth
|
||||
|
@ -79,10 +57,22 @@ public final class PocketGenerator {
|
|||
}
|
||||
|
||||
public static Pocket generatePublicPocketV2(VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
PocketTemplateV2 pocketTemplate = SchematicV2Handler.getInstance().getRandomPublicPocket();
|
||||
return generateV2PocketFromTemplate(DimensionalDoorsInitializer.getWorld(ModDimensions.PUBLIC), pocketTemplate, virtualLocation, linkTo, linkProperties);
|
||||
return generateFromPocketGroupV2(DimensionalDoorsInitializer.getWorld(ModDimensions.PUBLIC), "public", virtualLocation, linkTo, linkProperties);
|
||||
}
|
||||
|
||||
public static Pocket generateFromPocketGroupV2(ServerWorld world, String group, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
PocketGenerationParameters parameters = new PocketGenerationParameters(world, group, virtualLocation, linkTo, linkProperties);
|
||||
return generatePocketV2(SchematicV2Handler.getInstance().getGroup(group).getNextPocketGeneratorReference(parameters), parameters);
|
||||
}
|
||||
|
||||
public static Pocket generatePocketV2(PocketGeneratorReference pocketGeneratorReference, PocketGenerationParameters parameters) {
|
||||
return pocketGeneratorReference.prepareAndPlacePocket(parameters);
|
||||
}
|
||||
|
||||
public static Pocket generateDungeonPocketV2(VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
return generateFromPocketGroupV2(DimensionalDoorsInitializer.getWorld(ModDimensions.DUNGEON), "dungeon", virtualLocation, linkTo, linkProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dungeon pockets at a certain depth.
|
||||
*
|
||||
|
|
|
@ -1,44 +1,28 @@
|
|||
package org.dimdev.dimdoors.pockets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.rift.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.util.Location;
|
||||
import org.dimdev.dimdoors.util.schematic.v2.Schematic;
|
||||
import org.dimdev.dimdoors.util.schematic.v2.SchematicPlacer;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.block.entity.DispenserBlockEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
public class PocketTemplateV2 {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final boolean replacingPlaceholders = false;
|
||||
private final Schematic schematic;
|
||||
private final String group;
|
||||
private final int size;
|
||||
private final String id;
|
||||
|
||||
public PocketTemplateV2(Schematic schematic, String group, int size, String id, float weight) {
|
||||
public PocketTemplateV2(Schematic schematic, String id) {
|
||||
this.schematic = schematic;
|
||||
this.group = group;
|
||||
this.size = size;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/*
|
||||
public void setup(Pocket pocket, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
ServerWorld world = DimensionalDoorsInitializer.getWorld(pocket.world);
|
||||
|
||||
|
@ -71,11 +55,12 @@ public class PocketTemplateV2 {
|
|||
|
||||
TemplateUtils.registerRifts(rifts, linkTo, linkProperties, pocket);
|
||||
}
|
||||
*/
|
||||
|
||||
public void place(Pocket pocket) {
|
||||
pocket.setSize(this.size * 16, this.size * 16, this.size * 16);
|
||||
pocket.setSize(schematic.getWidth(), schematic.getHeight(), schematic.getLength());
|
||||
ServerWorld world = DimensionalDoorsInitializer.getWorld(pocket.world);
|
||||
BlockPos origin = new BlockPos(pocket.box.minX, pocket.box.minY, pocket.box.minZ);
|
||||
BlockPos origin = pocket.getOrigin();
|
||||
LOGGER.info("Placing new pocket using schematic " + this.id + " at x = " + origin.getX() + ", z = " + origin.getZ());
|
||||
SchematicPlacer.place(this.schematic, world, origin);
|
||||
}
|
||||
|
@ -84,10 +69,6 @@ public class PocketTemplateV2 {
|
|||
return replacingPlaceholders;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
public Schematic getSchematic() {
|
||||
return this.schematic;
|
||||
}
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
package org.dimdev.dimdoors.pockets;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
public final class PocketType {
|
||||
public static final Codec<PocketType> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.STRING.fieldOf("group").forGetter(PocketType::getGroup),
|
||||
PocketEntry.CODEC.listOf().fieldOf("pockets").forGetter(PocketType::getEntries)
|
||||
).apply(instance, PocketType::new));
|
||||
private final String group;
|
||||
private final List<PocketEntry> entries;
|
||||
|
||||
public PocketType(String group, List<PocketEntry> entries) {
|
||||
this.group = group;
|
||||
this.entries = entries;
|
||||
}
|
||||
public String getGroup() {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
public List<PocketEntry> getEntries() {
|
||||
return this.entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PocketType{" +
|
||||
"group='" + this.group + '\'' +
|
||||
|
||||
", entries=" + this.entries +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (super.equals(o)) return true;
|
||||
if (o == null || this.getClass() != o.getClass()) return false;
|
||||
PocketType that = (PocketType) o;
|
||||
return Objects.equals(this.group, that.group) &&
|
||||
Objects.equals(this.entries, that.entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.group, this.entries);
|
||||
}
|
||||
|
||||
public static final class PocketEntry {
|
||||
public static final Codec<PocketEntry> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.INT.fieldOf("size").forGetter(PocketEntry::getSize),
|
||||
Codec.STRING.fieldOf("id").forGetter(PocketEntry::getName),
|
||||
Codec.INT.optionalFieldOf("weight", 5).forGetter(PocketEntry::getWeight)
|
||||
).apply(instance, PocketEntry::new));
|
||||
private final int size;
|
||||
private final String name;
|
||||
private final int weight;
|
||||
|
||||
PocketEntry(int size, String name, int weight) {
|
||||
this.size = size;
|
||||
this.name = name;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return this.weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || this.getClass() != o.getClass()) return false;
|
||||
PocketEntry that = (PocketEntry) o;
|
||||
return this.size == that.size &&
|
||||
Float.compare(that.weight, this.weight) == 0 &&
|
||||
this.name.equals(that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.size, this.name, this.weight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PocketEntry{" +
|
||||
"size=" + this.size +
|
||||
", name='" + this.name + '\'' +
|
||||
", weight=" + this.weight +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +1,39 @@
|
|||
package org.dimdev.dimdoors.pockets;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.common.collect.*;
|
||||
import com.google.gson.*;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.pockets.generator.PocketGenerator;
|
||||
import org.dimdev.dimdoors.pockets.virtual.VirtualPocket;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.WeightedList;
|
||||
import org.dimdev.dimdoors.util.schematic.v2.Schematic;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
|
||||
public class SchematicV2Handler {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create();
|
||||
private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create();
|
||||
private static final SchematicV2Handler INSTANCE = new SchematicV2Handler();
|
||||
private final List<PocketTemplateV2> templates = Lists.newArrayList();
|
||||
private final Multimap<String, PocketTemplateV2> templateMap = HashMultimap.create();
|
||||
private final List<PocketType> pocketTypes = Lists.newArrayList();
|
||||
private static final Random RANDOM = new Random(new Random().nextLong());
|
||||
private final Map<String, PocketGenerator> pocketGeneratorMap = Maps.newHashMap();
|
||||
private final Map<String, VirtualPocket> pocketGroups = Maps.newHashMap();
|
||||
private final Map<Identifier, PocketTemplateV2> templates = Maps.newHashMap();
|
||||
private boolean loaded = false;
|
||||
|
||||
private SchematicV2Handler() {
|
||||
|
@ -42,67 +41,127 @@ public class SchematicV2Handler {
|
|||
|
||||
public void load() {
|
||||
if (this.loaded) {
|
||||
throw new UnsupportedOperationException("Attempted to load schematics twice!");
|
||||
throw new UnsupportedOperationException("Attempted to load pockets twice!");
|
||||
}
|
||||
this.loaded = true;
|
||||
long startTime = System.currentTimeMillis();
|
||||
Set<String> names = ImmutableSet.of("default_private", "default_public");
|
||||
for (String name : names) {
|
||||
try (BufferedReader reader = Files.newBufferedReader(Paths.get(SchematicV2Handler.class.getResource(String.format("/data/dimdoors/pockets/json/v2/%s.json", name)).toURI()))) {
|
||||
List<String> result = new ArrayList<>();
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
result.add(line);
|
||||
}
|
||||
JsonObject json = GSON.fromJson(String.join("", result), JsonObject.class);
|
||||
PocketType type = PocketType.CODEC.decode(JsonOps.INSTANCE, json).getOrThrow(false, System.err::println).getFirst();
|
||||
this.pocketTypes.add(type);
|
||||
this.loadResourceSchematics(type);
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.info("Loaded schematics in {} seconds", System.currentTimeMillis() - startTime);
|
||||
try {
|
||||
Path path = Paths.get(SchematicV2Handler.class.getResource("/data/dimdoors/pockets/generators").toURI());
|
||||
loadJson(path, new String[0], this::loadPocketGenerator);
|
||||
LOGGER.info("Loaded pockets in {} seconds", System.currentTimeMillis() - startTime);
|
||||
} catch (URISyntaxException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
try {
|
||||
Path path = Paths.get(SchematicV2Handler.class.getResource("/data/dimdoors/pockets/groups").toURI());
|
||||
loadJson(path, new String[0], this::loadPocketGroup);
|
||||
LOGGER.info("Loaded pocket groups in {} seconds", System.currentTimeMillis() - startTime);
|
||||
} catch (URISyntaxException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadResourceSchematics(PocketType type) throws URISyntaxException, IOException {
|
||||
String group = type.getGroup();
|
||||
Path basePath = Paths.get(SchematicV2Handler.class.getResource(String.format("/data/dimdoors/pockets/schematic/v2/%s/", group)).toURI());
|
||||
for (PocketType.PocketEntry entry : type.getEntries()) {
|
||||
Path schemPath = basePath.resolve(entry.getName() + ".schem");
|
||||
CompoundTag schemTag = NbtIo.readCompressed(Files.newInputStream(schemPath));
|
||||
Schematic schematic = Schematic.fromTag(schemTag);
|
||||
for (int i = 0; i < entry.getWeight(); i++) {
|
||||
this.templateMap.put(group, new PocketTemplateV2(schematic, group, entry.getSize(), entry.getName(), entry.getWeight()));
|
||||
}
|
||||
}
|
||||
}
|
||||
public Tag readNbtFromJson(String id) {
|
||||
try {
|
||||
Path path = Paths.get(SchematicV2Handler.class.getResource("/data/dimdoors/pockets/json/" + id + ".json").toURI());
|
||||
if (!Files.isRegularFile(path)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
JsonElement json = GSON.fromJson(String.join("", Files.readAllLines(path)), JsonElement.class);
|
||||
return JsonOps.INSTANCE.convertTo(NbtOps.INSTANCE, json);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public PocketTemplateV2 getRandomPublicPocket() {
|
||||
Collection<PocketTemplateV2> publicPockets = this.templateMap.get("public");
|
||||
int index = RANDOM.nextInt(publicPockets.size());
|
||||
return Lists.newArrayList(publicPockets).get(0);
|
||||
}
|
||||
public <T> T readNbtSerializableFromJson(String id, Function<Tag, T> reader) {
|
||||
Tag tag = readNbtFromJson(id);
|
||||
if (tag == null) return null;
|
||||
return reader.apply(tag);
|
||||
}
|
||||
|
||||
public PocketTemplateV2 getRandomPrivatePocket() {
|
||||
Collection<PocketTemplateV2> publicPockets = this.templateMap.get("private");
|
||||
int index = RANDOM.nextInt(publicPockets.size());
|
||||
return Lists.newArrayList(publicPockets).get(0);
|
||||
}
|
||||
// TODO: fix, some weird "/" stuff
|
||||
private void loadJson(Path path, String[] idParts, BiConsumer<String, Tag> loader) {
|
||||
if (Files.isDirectory(path)) {
|
||||
try {
|
||||
for (Path directoryPath : Files.newDirectoryStream(path)) {
|
||||
String[] directoryIdParts = Arrays.copyOf(idParts, idParts.length + 1);
|
||||
String fileName = directoryPath.getFileName().toString();
|
||||
if (fileName.endsWith("/")) fileName = fileName.substring(0, fileName.length()-1); // https://bugs.openjdk.java.net/browse/JDK-8153248
|
||||
if (Files.isRegularFile(directoryPath)) fileName = fileName.substring(0, fileName.lastIndexOf('.')); // cut extension
|
||||
directoryIdParts[directoryIdParts.length - 1] = fileName;
|
||||
loadJson(directoryPath, directoryIdParts, loader);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("could not load pocket data in path " + path.toString() + " due to malformed json.", e);
|
||||
}
|
||||
} else if(Files.isRegularFile(path) && path.getFileName().toString().endsWith(".json")) {
|
||||
String id = String.join("/", idParts);
|
||||
try {
|
||||
JsonElement json = GSON.fromJson(String.join("", Files.readAllLines(path)), JsonElement.class);
|
||||
loader.accept(id, JsonOps.INSTANCE.convertTo(NbtOps.INSTANCE, json));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("could not load pocket data in path " + path.toString() + " due to malformed json.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadPocketGroup(String id, Tag tag) {
|
||||
VirtualPocket group = VirtualPocket.deserialize(tag);
|
||||
pocketGroups.put(id, group);
|
||||
}
|
||||
|
||||
private void loadPocketGenerator(String id, Tag tag) {
|
||||
if (tag == null || tag.getType() != NbtType.COMPOUND) {
|
||||
LOGGER.error("Could not load PocketGenerator " + id + " since the json does not represent a CompoundTag!");
|
||||
return;
|
||||
}
|
||||
PocketGenerator gen = PocketGenerator.deserialize((CompoundTag) tag);
|
||||
if (gen != null) pocketGeneratorMap.put(id, gen);
|
||||
}
|
||||
|
||||
public void loadSchematic(Identifier templateID, String id) {
|
||||
try {
|
||||
if (templates.containsKey(templateID)) return;
|
||||
Path schemPath = Paths.get(SchematicV2Handler.class.getResource(String.format("/data/dimdoors/pockets/schematic/%s.schem", id.replaceAll("\\.", "/"))).toURI());
|
||||
CompoundTag schemTag = NbtIo.readCompressed(Files.newInputStream(schemPath));
|
||||
Schematic schematic = Schematic.fromTag(schemTag);
|
||||
PocketTemplateV2 template = new PocketTemplateV2(schematic, id);
|
||||
templates.put(templateID, template);
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
LOGGER.error("Could not load schematic!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public WeightedList<PocketGenerator, PocketGenerationParameters> getPocketsMatchingTags(List<String> required, List<String> blackList, boolean exact) {
|
||||
return new WeightedList<>(pocketGeneratorMap.values().stream().filter(pocketGenerator -> pocketGenerator.checkTags(required, blackList, exact)).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public VirtualPocket getGroup(String group) {
|
||||
return pocketGroups.get(group);
|
||||
}
|
||||
|
||||
public static SchematicV2Handler getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public List<PocketTemplateV2> getTemplates() {
|
||||
public Map<Identifier, PocketTemplateV2> getTemplates() {
|
||||
return this.templates;
|
||||
}
|
||||
|
||||
public List<PocketType> getPocketTypes() {
|
||||
return this.pocketTypes;
|
||||
public Map<String, VirtualPocket> getPocketGroups() {
|
||||
return this.pocketGroups;
|
||||
}
|
||||
|
||||
public PocketGenerator getGenerator(String id) {
|
||||
return pocketGeneratorMap.get(id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraft.loot.context.LootContextParameters;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity;
|
||||
|
@ -59,7 +61,7 @@ public class TemplateUtils {
|
|||
}
|
||||
}
|
||||
|
||||
static void setupLootTable(ServerWorld world, BlockEntity tile, Inventory inventory, Logger logger) {
|
||||
public static void setupLootTable(ServerWorld world, BlockEntity tile, Inventory inventory, Logger logger) {
|
||||
LootTable table;
|
||||
if (tile instanceof ChestBlockEntity) {
|
||||
logger.debug("Now populating chest.");
|
||||
|
@ -68,11 +70,11 @@ public class TemplateUtils {
|
|||
logger.debug("Now populating dispenser.");
|
||||
table = world.getServer().getLootManager().getTable(new Identifier("dimdoors:dispenser_projectiles"));
|
||||
}
|
||||
LootContext ctx = new LootContext.Builder(world).random(world.random).build(LootContextTypes.CHEST);
|
||||
LootContext ctx = new LootContext.Builder(world).random(world.random).parameter(LootContextParameters.ORIGIN, Vec3d.of(tile.getPos())).build(LootContextTypes.CHEST);
|
||||
table.supplyInventory(inventory, ctx);
|
||||
}
|
||||
|
||||
static void registerRifts(List<? extends RiftBlockEntity> rifts, VirtualTarget linkTo, LinkProperties linkProperties, Pocket pocket) {
|
||||
static public void registerRifts(List<? extends RiftBlockEntity> rifts, VirtualTarget linkTo, LinkProperties linkProperties, Pocket pocket) {
|
||||
ServerWorld world = DimensionalDoorsInitializer.getWorld(pocket.world);
|
||||
HashMap<RiftBlockEntity, Float> entranceWeights = new HashMap<>();
|
||||
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
package org.dimdev.dimdoors.pockets.generator;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerLightingProvider;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.ChunkRegion;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.chunk.*;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.block.entity.DetachedRiftBlockEntity;
|
||||
import org.dimdev.dimdoors.block.entity.ModBlockEntityTypes;
|
||||
import org.dimdev.dimdoors.rift.targets.PocketEntranceMarker;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.TeleportUtil;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.VirtualLocation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ChunkGenerator extends PocketGenerator {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final String KEY = "chunk";
|
||||
|
||||
private Identifier dimensionID;
|
||||
private Vec3i size; // TODO: equation-ify
|
||||
private Vec3i offset; // TODO: equation-ify
|
||||
private int virtualYOffset; // TODO: equation-ify
|
||||
|
||||
public ChunkGenerator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGenerator fromTag(CompoundTag tag) {
|
||||
super.fromTag(tag);
|
||||
|
||||
this.dimensionID = new Identifier(tag.getString("dimension_id"));
|
||||
|
||||
int[] temp = tag.getIntArray("size");
|
||||
this.size = new Vec3i(temp[0], temp[1], temp[2]);
|
||||
|
||||
temp = tag.contains("offset") ? tag.getIntArray("offset") : new int[]{0, 0, 0};
|
||||
this.offset = new Vec3i(temp[0], temp[1], temp[2]);
|
||||
|
||||
this.virtualYOffset = tag.contains("virtual_y_offset") ? tag.getInt("virtual_y_offset") : 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
|
||||
tag.putString("dimension_id", dimensionID.toString());
|
||||
tag.putIntArray("size", new int[]{this.size.getX(), this.size.getY(), this.size.getZ()});
|
||||
if (!(offset.getX() == 0 && offset.getY() == 0 && offset.getZ() == 0)) {
|
||||
tag.putIntArray("offset", new int[]{this.offset.getX(), this.offset.getY(), this.offset.getZ()});
|
||||
}
|
||||
tag.putInt("virtual_y_offset", this.virtualYOffset);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pocket prepareAndPlacePocket(PocketGenerationParameters parameters) {
|
||||
ServerWorld world = parameters.getWorld();
|
||||
VirtualLocation sourceVirtualLocation = parameters.getSourceVirtualLocation();
|
||||
|
||||
int chunkSizeX = ((this.size.getX() >> 4) + (this.size.getX() % 16 == 0 ? 0 : 1));
|
||||
int chunkSizeZ = ((this.size.getZ() >> 4) + (this.size.getZ() % 16 == 0 ? 0 : 1));
|
||||
|
||||
Pocket pocket = DimensionalRegistry.getPocketDirectory(world.getRegistryKey()).newPocket();
|
||||
pocket.setSize(size);
|
||||
pocket.offsetOrigin(offset);
|
||||
|
||||
LOGGER.info("Generating chunk pocket at location " + pocket.getOrigin());
|
||||
|
||||
ServerWorld genWorld = DimensionalDoorsInitializer.getWorld(RegistryKey.of(Registry.DIMENSION, dimensionID));
|
||||
net.minecraft.world.gen.chunk.ChunkGenerator genWorldChunkGenerator = genWorld.getChunkManager().getChunkGenerator();
|
||||
|
||||
ArrayList<Chunk> protoChunks = new ArrayList<>();
|
||||
for (int z = 0; z < chunkSizeZ; z++) {
|
||||
for (int x = 0; x < chunkSizeX; x++) {
|
||||
ProtoChunk protoChunk = new ProtoChunk(new ChunkPos(pocket.getOrigin().add(x * 16, 0, z * 16)), UpgradeData.NO_UPGRADE_DATA);
|
||||
protoChunk.setLightingProvider(genWorld.getLightingProvider());
|
||||
protoChunks.add(protoChunk);
|
||||
}
|
||||
}
|
||||
ChunkRegion protoRegion = new ChunkRegionHack(genWorld, protoChunks);
|
||||
for (Chunk protoChunk : protoChunks) { // TODO: check wether structures are even activated
|
||||
genWorldChunkGenerator.setStructureStarts(genWorld.getRegistryManager(), genWorld.getStructureAccessor().forRegion(protoRegion), protoChunk, genWorld.getStructureManager(), genWorld.getSeed());
|
||||
((ProtoChunk) protoChunk).setStatus(ChunkStatus.STRUCTURE_STARTS);
|
||||
}
|
||||
for (Chunk protoChunk : protoChunks) {
|
||||
genWorldChunkGenerator.addStructureReferences(protoRegion, genWorld.getStructureAccessor().forRegion(protoRegion), protoChunk);
|
||||
((ProtoChunk) protoChunk).setStatus(ChunkStatus.STRUCTURE_REFERENCES);
|
||||
}
|
||||
for (Chunk protoChunk : protoChunks) {
|
||||
genWorldChunkGenerator.populateBiomes(BuiltinRegistries.BIOME, protoChunk);
|
||||
((ProtoChunk) protoChunk).setStatus(ChunkStatus.BIOMES);
|
||||
}
|
||||
for (Chunk protoChunk : protoChunks) {
|
||||
genWorldChunkGenerator.populateNoise(genWorld, genWorld.getStructureAccessor().forRegion(protoRegion), protoChunk);
|
||||
((ProtoChunk) protoChunk).setStatus(ChunkStatus.NOISE);
|
||||
}
|
||||
for (Chunk protoChunk : protoChunks) {
|
||||
genWorldChunkGenerator.buildSurface(protoRegion, protoChunk);
|
||||
((ProtoChunk) protoChunk).setStatus(ChunkStatus.SURFACE);
|
||||
}
|
||||
for (GenerationStep.Carver carver : GenerationStep.Carver.values()) {
|
||||
for (Chunk protoChunk : protoChunks) {
|
||||
genWorldChunkGenerator.carve(genWorld.getSeed(), genWorld.getBiomeAccess(), protoChunk, carver);
|
||||
ProtoChunk pChunk = ((ProtoChunk) protoChunk);
|
||||
if (pChunk.getStatus() == ChunkStatus.SURFACE) pChunk.setStatus(ChunkStatus.CARVERS);
|
||||
else pChunk.setStatus(ChunkStatus.LIQUID_CARVERS);
|
||||
}
|
||||
}
|
||||
for (Chunk protoChunk : protoChunks) {
|
||||
ChunkRegion tempRegion = new ChunkRegionHack(genWorld, ChunkPos.stream(protoChunk.getPos(), 10).map(chunkPos -> protoRegion.getChunk(chunkPos.x, chunkPos.z)).collect(Collectors.toList()));
|
||||
genWorldChunkGenerator.generateFeatures(tempRegion, genWorld.getStructureAccessor().forRegion(tempRegion));
|
||||
((ProtoChunk) protoChunk).setStatus(ChunkStatus.FEATURES);
|
||||
}
|
||||
for (Chunk protoChunk : protoChunks) { // likely only necessary for spawn step since we copy over anyways
|
||||
((ServerLightingProvider) genWorld.getLightingProvider()).light(protoChunk, false);
|
||||
((ProtoChunk) protoChunk).setStatus(ChunkStatus.LIGHT);
|
||||
}
|
||||
for (Chunk protoChunk : protoChunks) { // TODO: does this even work?
|
||||
ChunkRegion tempRegion = new ChunkRegionHack(genWorld, ChunkPos.stream(protoChunk.getPos(), 5).map(chunkPos -> protoRegion.getChunk(chunkPos.x, chunkPos.z)).collect(Collectors.toList()));
|
||||
genWorldChunkGenerator.populateEntities(tempRegion);
|
||||
((ProtoChunk) protoChunk).setStatus(ChunkStatus.SPAWN);
|
||||
}
|
||||
|
||||
|
||||
BlockPos firstCorner = pocket.getOrigin();
|
||||
BlockPos secondCorner = new BlockPos(firstCorner.getX() + size.getX() - 1, Math.min(firstCorner.getY() + size.getY() - 1, world.getHeight() - virtualYOffset - 1), firstCorner.getZ() + size.getZ() - 1); // subtracting 1 here since it should be 0 inclusive and size exclusive
|
||||
|
||||
BlockPos pocketOriginChunkOffset = new ChunkPos(pocket.getOrigin()).getStartPos().subtract(firstCorner);
|
||||
for (BlockPos blockPos : BlockPos.iterate(firstCorner, secondCorner)) {
|
||||
BlockPos sourcePos = blockPos.add(pocketOriginChunkOffset).add(0, virtualYOffset, 0);
|
||||
BlockState blockState = protoRegion.getBlockState(sourcePos);
|
||||
if (!blockState.isAir()) {
|
||||
world.setBlockState(blockPos, protoRegion.getBlockState(blockPos.add(pocketOriginChunkOffset).add(0, virtualYOffset, 0)));
|
||||
}
|
||||
}
|
||||
Box realBox = new Box(firstCorner, secondCorner);
|
||||
for (Chunk protoChunk : protoChunks) {
|
||||
for(BlockPos virtualBlockPos : protoChunk.getBlockEntityPositions()) {
|
||||
BlockPos realBlockPos = virtualBlockPos.subtract(pocketOriginChunkOffset).add(0, -virtualYOffset, 0);
|
||||
if (realBox.contains(realBlockPos.getX(), realBlockPos.getY(), realBlockPos.getZ())) {
|
||||
world.setBlockEntity(realBlockPos, protoChunk.getBlockEntity(virtualBlockPos)); // TODO: ensure this works, likely bugged
|
||||
}
|
||||
}
|
||||
}
|
||||
Box virtualBox = realBox.offset(pocketOriginChunkOffset.add(0, virtualYOffset, 0));
|
||||
for (Entity entity : protoRegion.getOtherEntities(null, virtualBox)) { // TODO: does this even work?
|
||||
TeleportUtil.teleport(entity, world, entity.getPos().add(-pocketOriginChunkOffset.getX(), -pocketOriginChunkOffset.getY() - virtualYOffset, -pocketOriginChunkOffset.getZ()), entity.yaw);
|
||||
} // TODO: Entities?/ Biomes/ Structure Data
|
||||
|
||||
world.setBlockState(world.getTopPosition(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, pocket.getOrigin()), ModBlocks.DETACHED_RIFT.getDefaultState());
|
||||
|
||||
DetachedRiftBlockEntity rift = ModBlockEntityTypes.DETACHED_RIFT.instantiate();
|
||||
world.setBlockEntity(world.getTopPosition(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, pocket.getOrigin()), rift);
|
||||
|
||||
rift.setDestination(new PocketEntranceMarker());
|
||||
pocket.virtualLocation = sourceVirtualLocation;
|
||||
|
||||
return pocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGeneratorType<? extends PocketGenerator> getType() {
|
||||
return PocketGeneratorType.CHUNK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
private static class ChunkRegionHack extends ChunkRegion { // Please someone tell me if there is a better way
|
||||
ChunkRegionHack(ServerWorld world, List<Chunk> chunks) {
|
||||
super(world, chunks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
|
||||
Chunk chunk = super.getChunk(chunkX, chunkZ, leastStatus, false);
|
||||
return chunk == null ? new ProtoChunkHack(new ChunkPos(chunkX, chunkZ), UpgradeData.NO_UPGRADE_DATA) : chunk;
|
||||
}
|
||||
|
||||
// TODO: Override getSeed()
|
||||
}
|
||||
|
||||
private static class ProtoChunkHack extends ProtoChunk { // exists solely to make some calls in the non utilized chunks faster
|
||||
public ProtoChunkHack(ChunkPos pos, UpgradeData upgradeData) {
|
||||
super(pos, upgradeData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState setBlockState(BlockPos pos, BlockState state, boolean moved) {
|
||||
return Blocks.VOID_AIR.getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
return Blocks.VOID_AIR.getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockPos pos) {
|
||||
return Fluids.EMPTY.getDefaultState();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
package org.dimdev.dimdoors.pockets.generator;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import net.minecraft.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.block.entity.DispenserBlockEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.pockets.TemplateUtils;
|
||||
import org.dimdev.dimdoors.pockets.modifier.Modifier;
|
||||
import org.dimdev.dimdoors.pockets.modifier.RiftManager;
|
||||
import org.dimdev.dimdoors.util.Location;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.Weighted;
|
||||
import org.dimdev.dimdoors.util.math.Equation;
|
||||
import org.dimdev.dimdoors.util.math.Equation.EquationParseException;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class PocketGenerator implements Weighted<PocketGenerationParameters> {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final Registry<PocketGeneratorType<? extends PocketGenerator>> REGISTRY = FabricRegistryBuilder.from(new SimpleRegistry<PocketGeneratorType<? extends PocketGenerator>>(RegistryKey.ofRegistry(new Identifier("dimdoors", "pocket_generator_type")), Lifecycle.stable())).buildAndRegister();
|
||||
|
||||
private static final String defaultWeightEquation = "5"; // TODO: make config
|
||||
private static final int fallbackWeight = 5; // TODO: make config
|
||||
private final List<Modifier> modifierList = new ArrayList<>();
|
||||
|
||||
private String weight;
|
||||
private Equation weightEquation;
|
||||
|
||||
private final List<String> tags = new ArrayList<>();
|
||||
|
||||
public PocketGenerator() { }
|
||||
|
||||
public PocketGenerator(String weight) {
|
||||
this.weight = weight;
|
||||
parseWeight();
|
||||
}
|
||||
|
||||
public static PocketGenerator deserialize(CompoundTag tag) {
|
||||
Identifier id = Identifier.tryParse(tag.getString("type")); // TODO: return some NONE PocketGenerator if type cannot be found or deserialization fails.
|
||||
PocketGeneratorType<? extends PocketGenerator> type = REGISTRY.get(id);
|
||||
if (type == null) {
|
||||
LOGGER.error("Could not deserialize PocketGenerator: " + tag.toString());
|
||||
return null;
|
||||
}
|
||||
return type.fromTag(tag);
|
||||
}
|
||||
|
||||
public static CompoundTag serialize(PocketGenerator pocketGenerator) {
|
||||
return pocketGenerator.toTag(new CompoundTag());
|
||||
}
|
||||
|
||||
private void parseWeight() {
|
||||
try {
|
||||
this.weightEquation = Equation.parse(weight);
|
||||
} catch (EquationParseException e) {
|
||||
LOGGER.error("Could not parse weight equation \"" + weight + "\", defaulting to default weight equation \"" + defaultWeightEquation + "\"", e);
|
||||
try {
|
||||
this.weightEquation = Equation.parse(defaultWeightEquation);
|
||||
} catch (EquationParseException equationParseException) {
|
||||
LOGGER.error("Could not parse default weight equation \"" + defaultWeightEquation + "\", defaulting to fallback weight \"" + fallbackWeight + "\"", equationParseException);
|
||||
this.weightEquation = stringDoubleMap -> fallbackWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PocketGenerator fromTag(CompoundTag tag) {
|
||||
this.weight = tag.contains("weight") ? tag.getString("weight") : defaultWeightEquation;
|
||||
parseWeight();
|
||||
|
||||
if (tag.contains("modifiers")) {
|
||||
ListTag modifiersTag = tag.getList("modifiers", 10);
|
||||
for (int i = 0; i < modifiersTag.size(); i++) {
|
||||
modifierList.add(Modifier.deserialize(modifiersTag.getCompound(i)));
|
||||
}
|
||||
}
|
||||
|
||||
if (tag.contains("tags")) {
|
||||
ListTag listTag = tag.getList("tags", NbtType.STRING);
|
||||
for (int i = 0; i < listTag.size(); i++) {
|
||||
tags.add(listTag.getString(i));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
this.getType().toTag(tag);
|
||||
|
||||
if (!weight.equals("5")) tag.putString("weight", weight);
|
||||
|
||||
ListTag modifiersTag = new ListTag();
|
||||
for (Modifier modifier : modifierList) {
|
||||
modifiersTag.add(modifier.toTag(new CompoundTag()));
|
||||
}
|
||||
if (modifiersTag.size() > 0) tag.put("modifiers", modifiersTag);
|
||||
|
||||
if (tags.size() > 0) {
|
||||
ListTag listTag = new ListTag();
|
||||
for (String tagString : tags) {
|
||||
listTag.add(StringTag.of(tagString));
|
||||
}
|
||||
tag.put("tags", listTag);
|
||||
}
|
||||
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public abstract Pocket prepareAndPlacePocket(PocketGenerationParameters parameters);
|
||||
|
||||
public abstract PocketGeneratorType<? extends PocketGenerator> getType();
|
||||
|
||||
public abstract String getKey();
|
||||
|
||||
@Override
|
||||
public double getWeight(PocketGenerationParameters parameters) {
|
||||
return this.weightEquation.apply(parameters.toVariableMap(new HashMap<>()));
|
||||
}
|
||||
|
||||
public void applyModifiers(PocketGenerationParameters parameters, RiftManager manager) {
|
||||
for (Modifier modifier : modifierList) {
|
||||
modifier.apply(parameters, manager);
|
||||
}
|
||||
}
|
||||
|
||||
public void setup(Pocket pocket, PocketGenerationParameters parameters, boolean setupLootTables) {
|
||||
ServerWorld world = DimensionalDoorsInitializer.getWorld(pocket.world);
|
||||
List<RiftBlockEntity> rifts = new ArrayList<>();
|
||||
|
||||
pocket.getBlockEntities().forEach((blockPos, blockEntity) -> {
|
||||
if (blockEntity instanceof RiftBlockEntity) {
|
||||
LOGGER.debug("Rift found in pocket at " + blockPos);
|
||||
RiftBlockEntity rift = (RiftBlockEntity) blockEntity;
|
||||
rift.getDestination().setLocation(new Location((ServerWorld) Objects.requireNonNull(rift.getWorld()), rift.getPos()));
|
||||
rifts.add(rift);
|
||||
} else if (setupLootTables && blockEntity instanceof Inventory) {
|
||||
Inventory inventory = (Inventory) blockEntity;
|
||||
if (inventory.isEmpty()) {
|
||||
if (blockEntity instanceof ChestBlockEntity || blockEntity instanceof DispenserBlockEntity) {
|
||||
TemplateUtils.setupLootTable(world, blockEntity, inventory, LOGGER);
|
||||
if (inventory.isEmpty()) {
|
||||
LOGGER.error(", however Inventory is: empty!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
TemplateUtils.registerRifts(rifts, parameters.getLinkTo(), parameters.getLinkProperties(), pocket);
|
||||
|
||||
pocket.virtualLocation = parameters.getSourceVirtualLocation(); //TODO: this makes very little sense
|
||||
}
|
||||
|
||||
// why would you want to check for exact tags, but still need a blackList? Good question, but there is probably some use case for it.
|
||||
public boolean checkTags(List<String> required, List<String> blackList, boolean exact) {
|
||||
if (exact && required.size() != tags.size()) return false;
|
||||
if (required != null) {
|
||||
for (String req : required) {
|
||||
if (!tags.contains(req)) return false;
|
||||
}
|
||||
}
|
||||
if (blackList != null) {
|
||||
for (String black : blackList) {
|
||||
if (tags.contains(black)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public interface PocketGeneratorType<T extends PocketGenerator> {
|
||||
PocketGeneratorType<SchematicGenerator> SCHEMATIC = register(new Identifier("dimdoors", SchematicGenerator.KEY), SchematicGenerator::new);
|
||||
PocketGeneratorType<ChunkGenerator> CHUNK = register(new Identifier("dimdoors", ChunkGenerator.KEY), ChunkGenerator::new);
|
||||
PocketGeneratorType<VoidGenerator> VOID = register(new Identifier("dimdoors", VoidGenerator.KEY), VoidGenerator::new);
|
||||
|
||||
PocketGenerator fromTag(CompoundTag tag);
|
||||
|
||||
CompoundTag toTag(CompoundTag tag);
|
||||
|
||||
static void register() {
|
||||
}
|
||||
|
||||
static <U extends PocketGenerator> PocketGeneratorType<U> register(Identifier id, Supplier<U> constructor) {
|
||||
return Registry.register(REGISTRY, id, new PocketGeneratorType<U>() {
|
||||
@Override
|
||||
public PocketGenerator fromTag(CompoundTag tag) {
|
||||
return constructor.get().fromTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag.putString("type", id.toString());
|
||||
return tag;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package org.dimdev.dimdoors.pockets.generator;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.pockets.PocketTemplateV2;
|
||||
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.math.Equation;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SchematicGenerator extends PocketGenerator {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final String KEY = "schematic";
|
||||
|
||||
/*
|
||||
public static final Codec<SchematicGenerator> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.INT.fieldOf("size").forGetter(SchematicGenerator::getSize),
|
||||
Codec.STRING.fieldOf("id").forGetter(SchematicGenerator::getName),
|
||||
Codec.INT.optionalFieldOf("weight", 5).forGetter(schematicGenerator -> schematicGenerator.getWeight(null))
|
||||
).apply(instance, SchematicGenerator::new));
|
||||
*/
|
||||
|
||||
private String id;
|
||||
private Identifier templateID;
|
||||
|
||||
private Equation lengthEquation;
|
||||
private String offsetX;
|
||||
private Equation offsetXEquation;
|
||||
private String offsetY;
|
||||
private Equation offsetYEquation;
|
||||
private String offsetZ;
|
||||
private Equation offsetZEquation;
|
||||
|
||||
public SchematicGenerator() {
|
||||
}
|
||||
|
||||
public SchematicGenerator(String id) {
|
||||
this.id = id;
|
||||
|
||||
this.templateID = new Identifier("dimdoors", id);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Identifier getTemplateID() {
|
||||
return templateID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGenerator fromTag(CompoundTag tag) {
|
||||
super.fromTag(tag);
|
||||
|
||||
this.id = tag.getString("id");
|
||||
this.templateID = new Identifier("dimdoors", id);
|
||||
|
||||
SchematicV2Handler.getInstance().loadSchematic(templateID, id);
|
||||
|
||||
try {
|
||||
offsetX = tag.contains("offset_x") ? tag.getString("offset_x") : "0";
|
||||
offsetXEquation = Equation.parse(offsetX);
|
||||
offsetY = tag.contains("offset_y") ? tag.getString("offset_y") : "0";
|
||||
offsetYEquation = Equation.parse(offsetY);
|
||||
offsetZ = tag.contains("offset_z") ? tag.getString("offset_z") : "0";
|
||||
offsetZEquation = Equation.parse(offsetZ);
|
||||
} catch (Equation.EquationParseException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
|
||||
tag.putString("id", this.id);
|
||||
|
||||
if (!offsetX.equals("0")) tag.putString("offset_x", offsetX);
|
||||
if (!offsetY.equals("0")) tag.putString("offset_y", offsetY);
|
||||
if (!offsetZ.equals("0")) tag.putString("offset_z", offsetZ);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pocket prepareAndPlacePocket(PocketGenerationParameters parameters) {
|
||||
ServerWorld world = parameters.getWorld();
|
||||
Map<String, Double> variableMap = parameters.toVariableMap(new HashMap<>());
|
||||
|
||||
PocketTemplateV2 template = SchematicV2Handler.getInstance().getTemplates().get(templateID);
|
||||
if (template == null) throw new RuntimeException("Pocket template of id " + templateID + " not found!");
|
||||
|
||||
Pocket pocket = DimensionalRegistry.getPocketDirectory(world.getRegistryKey()).newPocket();
|
||||
LOGGER.info("Generating pocket from template " + template.getId() + " at location " + pocket.getOrigin());
|
||||
|
||||
pocket.offsetOrigin((int) offsetXEquation.apply(variableMap), (int) offsetYEquation.apply(variableMap), (int) offsetZEquation.apply(variableMap));
|
||||
|
||||
template.place(pocket);
|
||||
|
||||
return pocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGeneratorType<? extends PocketGenerator> getType() {
|
||||
return PocketGeneratorType.SCHEMATIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package org.dimdev.dimdoors.pockets.generator;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.math.Equation;
|
||||
import org.dimdev.dimdoors.util.math.Equation.EquationParseException;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class VoidGenerator extends PocketGenerator {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final String KEY = "void";
|
||||
private String width;
|
||||
private Equation heightEquation;
|
||||
private String height;
|
||||
private Equation widthEquation;
|
||||
private String length;
|
||||
private Equation lengthEquation;
|
||||
private String offsetX;
|
||||
private Equation offsetXEquation;
|
||||
private String offsetY;
|
||||
private Equation offsetYEquation;
|
||||
private String offsetZ;
|
||||
private Equation offsetZEquation;
|
||||
|
||||
@Override
|
||||
public Pocket prepareAndPlacePocket(PocketGenerationParameters parameters) {
|
||||
Pocket pocket = DimensionalRegistry.getPocketDirectory(parameters.getWorld().getRegistryKey()).newPocket();
|
||||
Map<String, Double> variableMap = parameters.toVariableMap(new HashMap<>());
|
||||
pocket.setSize((int) widthEquation.apply(variableMap), (int) heightEquation.apply(variableMap), (int) lengthEquation.apply(variableMap));
|
||||
pocket.offsetOrigin((int) offsetXEquation.apply(variableMap), (int) offsetYEquation.apply(variableMap), (int) offsetZEquation.apply(variableMap));
|
||||
|
||||
return pocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGeneratorType<? extends PocketGenerator> getType() {
|
||||
return PocketGeneratorType.VOID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGenerator fromTag(CompoundTag tag) {
|
||||
super.fromTag(tag);
|
||||
|
||||
try {
|
||||
width = tag.getString("width");
|
||||
widthEquation = Equation.parse(width);
|
||||
height = tag.getString("height");
|
||||
heightEquation = Equation.parse(height);
|
||||
length = tag.getString("length");
|
||||
lengthEquation = Equation.parse(length);
|
||||
|
||||
offsetX = tag.contains("offset_x") ? tag.getString("offset_x") : "0";
|
||||
offsetXEquation = Equation.parse(offsetX);
|
||||
offsetY = tag.contains("offset_y") ? tag.getString("offset_y") : "0";
|
||||
offsetYEquation = Equation.parse(offsetY);
|
||||
offsetZ = tag.contains("offset_z") ? tag.getString("offset_z") : "0";
|
||||
offsetZEquation = Equation.parse(offsetZ);
|
||||
} catch (EquationParseException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
|
||||
tag.putString("width", width);
|
||||
tag.putString("height", height);
|
||||
tag.putString("length", length);
|
||||
|
||||
if (!offsetX.equals("0")) tag.putString("offset_x", offsetX);
|
||||
if (!offsetY.equals("0")) tag.putString("offset_y", offsetY);
|
||||
if (!offsetZ.equals("0")) tag.putString("offset_z", offsetZ);
|
||||
|
||||
return tag;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package org.dimdev.dimdoors.pockets.modifier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.enums.DoubleBlockHalf;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.block.DimensionalDoorBlock;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity;
|
||||
import org.dimdev.dimdoors.block.entity.ModBlockEntityTypes;
|
||||
import org.dimdev.dimdoors.block.entity.RiftData;
|
||||
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
||||
import org.dimdev.dimdoors.rift.targets.IdMarker;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.TagEquations;
|
||||
import org.dimdev.dimdoors.util.math.Equation;
|
||||
import org.dimdev.dimdoors.util.math.Equation.EquationParseException;
|
||||
|
||||
public class DimensionalDoorModifier implements Modifier {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final String KEY = "door";
|
||||
|
||||
private Direction facing;
|
||||
private String doorTypeString;
|
||||
private DimensionalDoorBlock doorType;
|
||||
private CompoundTag doorData;
|
||||
private String doorDataReference;
|
||||
|
||||
private String x;
|
||||
private String y;
|
||||
private String z;
|
||||
private Equation xEquation;
|
||||
private Equation yEquation;
|
||||
private Equation zEquation;
|
||||
|
||||
|
||||
@Override
|
||||
public Modifier fromTag(CompoundTag tag) {
|
||||
String facingString = tag.getString("facing");
|
||||
facing = Direction.byName(tag.getString("facing"));
|
||||
if (facing == null || facing.getAxis().isVertical()) {
|
||||
LOGGER.error("Could not interpret facing direction \"" + facingString + "\"");
|
||||
facing = Direction.NORTH;
|
||||
}
|
||||
|
||||
doorTypeString = tag.getString("door_type");
|
||||
Block doorBlock = Registry.BLOCK.get(Identifier.tryParse(doorTypeString));
|
||||
if (!(doorBlock instanceof DimensionalDoorBlock)) {
|
||||
LOGGER.error("Could not interpret door type \"" + doorTypeString + "\"");
|
||||
doorBlock = ModBlocks.IRON_DIMENSIONAL_DOOR;
|
||||
}
|
||||
doorType = (DimensionalDoorBlock) doorBlock;
|
||||
|
||||
if (tag.getType("rift_data") == NbtType.STRING) {
|
||||
doorDataReference = tag.getString("rift_data");
|
||||
doorData = (CompoundTag) SchematicV2Handler.getInstance().readNbtFromJson(doorDataReference);
|
||||
}
|
||||
else if (tag.getType("rift_data") == NbtType.COMPOUND) doorData = tag.getCompound("rift_data");
|
||||
|
||||
try {
|
||||
x = tag.getString("x");
|
||||
y = tag.getString("y");
|
||||
z = tag.getString("z");
|
||||
|
||||
xEquation = Equation.parse(x);
|
||||
yEquation = Equation.parse(y);
|
||||
zEquation = Equation.parse(z);
|
||||
} catch (EquationParseException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
Modifier.super.toTag(tag);
|
||||
|
||||
tag.putString("facing", facing.asString());
|
||||
tag.putString("door_type", doorTypeString);
|
||||
if (doorDataReference != null) tag.putString("rift_data", doorDataReference);
|
||||
else if (doorData != null) tag.put("rift_data", doorData);
|
||||
tag.putString("x", x);
|
||||
tag.putString("y", y);
|
||||
tag.putString("z", z);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModifierType<? extends Modifier> getType() {
|
||||
return ModifierType.DIMENSIONAL_DOOR_MODIFIER_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PocketGenerationParameters parameters, RiftManager manager) {
|
||||
Map<String, Double> variableMap = manager.getPocket().toVariableMap(new HashMap<>());
|
||||
BlockPos pocketOrigin = manager.getPocket().getOrigin();
|
||||
BlockPos pos = new BlockPos(xEquation.apply(variableMap) + pocketOrigin.getX(), yEquation.apply(variableMap) + pocketOrigin.getY(), zEquation.apply(variableMap) + pocketOrigin.getZ());
|
||||
|
||||
ServerWorld world = parameters.getWorld();
|
||||
BlockState lower = doorType.getDefaultState().with(DimensionalDoorBlock.HALF, DoubleBlockHalf.LOWER).with(DimensionalDoorBlock.FACING, facing);
|
||||
world.setBlockState(pos, lower);
|
||||
world.setBlockState(pos.up(), doorType.getDefaultState().with(DimensionalDoorBlock.HALF, DoubleBlockHalf.UPPER).with(DimensionalDoorBlock.FACING, facing));
|
||||
|
||||
EntranceRiftBlockEntity rift = ModBlockEntityTypes.ENTRANCE_RIFT.instantiate();
|
||||
|
||||
if (doorData == null) {
|
||||
rift.setDestination(new IdMarker(manager.nextId()));
|
||||
} else {
|
||||
CompoundTag solvedDoorData = TagEquations.solveCompoundTagEquations(doorData, variableMap);
|
||||
rift.setData(RiftData.fromTag(solvedDoorData));
|
||||
}
|
||||
|
||||
manager.add(rift);
|
||||
|
||||
world.setBlockEntity(pos, rift);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package org.dimdev.dimdoors.pockets.modifier;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.block.entity.RiftData;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface Modifier {
|
||||
Registry<ModifierType<? extends Modifier>> REGISTRY = FabricRegistryBuilder.from(new SimpleRegistry<ModifierType<? extends Modifier>>(RegistryKey.ofRegistry(new Identifier("dimdoors", "modifier_type")), Lifecycle.stable())).buildAndRegister();
|
||||
|
||||
|
||||
static Modifier deserialize(CompoundTag tag) {
|
||||
Identifier id = Identifier.tryParse(tag.getString("type")); // TODO: return some NONE Modifier if type cannot be found or deserialization fails.
|
||||
return REGISTRY.get(id).fromTag(tag);
|
||||
}
|
||||
|
||||
static CompoundTag serialize(Modifier modifier) {
|
||||
return modifier.toTag(new CompoundTag());
|
||||
}
|
||||
|
||||
|
||||
Modifier fromTag(CompoundTag tag);
|
||||
|
||||
default CompoundTag toTag(CompoundTag tag) {
|
||||
return this.getType().toTag(tag);
|
||||
}
|
||||
|
||||
ModifierType<? extends Modifier> getType();
|
||||
|
||||
String getKey();
|
||||
|
||||
void apply(PocketGenerationParameters parameters, RiftManager manager);
|
||||
|
||||
interface ModifierType<T extends Modifier> {
|
||||
ModifierType<ShellModifier> SHELL_MODIFIER_TYPE = register(new Identifier("dimdoors", ShellModifier.KEY), ShellModifier::new);
|
||||
ModifierType<DimensionalDoorModifier> DIMENSIONAL_DOOR_MODIFIER_TYPE = register(new Identifier("dimdoors", DimensionalDoorModifier.KEY), DimensionalDoorModifier::new);
|
||||
ModifierType<PocketEntranceModifier> PUBLIC_MODIFIER_TYPE = register(new Identifier("dimdoors", PocketEntranceModifier.KEY), PocketEntranceModifier::new);
|
||||
ModifierType<RiftDataModifier> RIFT_DATA_MODIFIER_TYPE = register(new Identifier("dimdoors", RiftDataModifier.KEY), RiftDataModifier::new);
|
||||
ModifierType<RelativeReferenceModifier> RELATIVE_REFERENCE_MODIFIER_TYPE = register(new Identifier("dimdoors", RelativeReferenceModifier.KEY), RelativeReferenceModifier::new);
|
||||
Modifier fromTag(CompoundTag tag);
|
||||
|
||||
CompoundTag toTag(CompoundTag tag);
|
||||
|
||||
static void register() {
|
||||
}
|
||||
|
||||
static <U extends Modifier> ModifierType<U> register(Identifier id, Supplier<U> constructor) {
|
||||
return Registry.register(REGISTRY, id, new ModifierType<U>() {
|
||||
@Override
|
||||
public Modifier fromTag(CompoundTag tag) {
|
||||
return constructor.get().fromTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag.putString("type", id.toString());
|
||||
return tag;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package org.dimdev.dimdoors.pockets.modifier;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.rift.registry.PocketEntrancePointer;
|
||||
import org.dimdev.dimdoors.rift.targets.PocketEntranceMarker;
|
||||
import org.dimdev.dimdoors.rift.targets.PocketExitMarker;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
public class PocketEntranceModifier implements Modifier {
|
||||
public static final String KEY = "pocket_entrance";
|
||||
|
||||
private int id;
|
||||
|
||||
public PocketEntranceModifier(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public PocketEntranceModifier() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifier fromTag(CompoundTag tag) {
|
||||
return new PocketEntranceModifier(tag.getInt("id"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
Modifier.super.toTag(tag);
|
||||
|
||||
tag.putInt("id", id);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ModifierType<? extends Modifier> getType() {
|
||||
return ModifierType.PUBLIC_MODIFIER_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PocketGenerationParameters parameters, RiftManager manager) {
|
||||
manager.consume(id, rift -> {
|
||||
rift.setDestination(PocketEntranceMarker.builder().ifDestination(new PocketExitMarker()).weight(1.0f).build());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package org.dimdev.dimdoors.pockets.modifier;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.rift.targets.LocalReference;
|
||||
import org.dimdev.dimdoors.rift.targets.RiftReference;
|
||||
import org.dimdev.dimdoors.util.Location;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
|
||||
public class RelativeReferenceModifier implements Modifier {
|
||||
public static final String KEY = "relative";
|
||||
|
||||
private int point_a, point_b;
|
||||
|
||||
@Override
|
||||
public Modifier fromTag(CompoundTag tag) {
|
||||
point_a = tag.getInt("point_a");
|
||||
point_b = tag.getInt("point_b");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
Modifier.super.toTag(tag);
|
||||
tag.putInt("point_a", point_a);
|
||||
tag.putInt("point_b", point_b);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModifierType<? extends Modifier> getType() {
|
||||
return ModifierType.RELATIVE_REFERENCE_MODIFIER_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PocketGenerationParameters parameters, RiftManager manager) {
|
||||
Optional<Location> riftA = manager.get(point_a).map(rift -> new Location((ServerWorld) rift.getWorld(), rift.getPos()));
|
||||
Optional<Location> riftB = manager.get(point_b).map(rift -> new Location((ServerWorld) rift.getWorld(), rift.getPos()));
|
||||
|
||||
if(riftA.isPresent() && riftB.isPresent()) {
|
||||
RiftReference link1 = LocalReference.tryMakeRelative(riftA.get(), riftB.get());
|
||||
RiftReference link2 = LocalReference.tryMakeRelative(riftB.get(), riftA.get());
|
||||
|
||||
manager.consume(point_a, rift -> addLink(rift, link1));
|
||||
manager.consume(point_b, rift -> addLink(rift, link2));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean addLink(RiftBlockEntity rift, RiftReference link) {
|
||||
rift.setDestination(link);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package org.dimdev.dimdoors.pockets.modifier;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.block.entity.RiftData;
|
||||
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.TagEquations;
|
||||
|
||||
public class RiftDataModifier implements Modifier {
|
||||
public static final String KEY = "rift_data";
|
||||
|
||||
private CompoundTag doorData;
|
||||
private String doorDataReference;
|
||||
private List<Integer> ids;
|
||||
|
||||
@Override
|
||||
public Modifier fromTag(CompoundTag tag) {
|
||||
if (tag.getType("rift_data") == NbtType.STRING) {
|
||||
doorDataReference = tag.getString("rift_data");
|
||||
doorData = (CompoundTag) SchematicV2Handler.getInstance().readNbtFromJson(doorDataReference);
|
||||
}
|
||||
else if (tag.getType("rift_data") == NbtType.COMPOUND) doorData = tag.getCompound("rift_data");
|
||||
|
||||
ids = stream(tag.getByteArray("ids")).boxed().collect(Collectors.toList());
|
||||
return this;
|
||||
}
|
||||
|
||||
public static IntStream stream(byte[] bytes) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
||||
return IntStream.generate(buffer::get).limit(buffer.remaining());
|
||||
}
|
||||
|
||||
private static byte[] toByteArray(int[] ints) {
|
||||
byte[] bytes = new byte[ints.length];
|
||||
for (int i = 0; i < ints.length; i++) {
|
||||
bytes[i] = (byte) ints[i];
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
Modifier.super.toTag(tag);
|
||||
|
||||
if (doorDataReference != null) tag.putString("rift_data", doorDataReference);
|
||||
else if (doorData != null) tag.put("rift_data", doorData);
|
||||
tag.putByteArray("ids", toByteArray(ids.stream().mapToInt(Integer::intValue).toArray()));
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModifierType<? extends Modifier> getType() {
|
||||
return ModifierType.RIFT_DATA_MODIFIER_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PocketGenerationParameters parameters, RiftManager manager) {
|
||||
Map<String, Double> variableMap = manager.getPocket().toVariableMap(new HashMap<>());
|
||||
|
||||
Consumer<RiftBlockEntity> riftBlockEntityConsumer;
|
||||
|
||||
if (doorData == null) {
|
||||
riftBlockEntityConsumer = rift -> rift.setDestination(VirtualTarget.NoneTarget.INSTANCE);
|
||||
} else {
|
||||
CompoundTag solvedDoorData = TagEquations.solveCompoundTagEquations(doorData, variableMap);
|
||||
|
||||
riftBlockEntityConsumer = rift -> rift.setData(RiftData.fromTag(solvedDoorData));
|
||||
}
|
||||
|
||||
manager.foreachConsume((id, rift) -> {
|
||||
if(ids.contains(id)) {
|
||||
riftBlockEntityConsumer.accept(rift);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package org.dimdev.dimdoors.pockets.modifier;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.rift.targets.IdMarker;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
public class RiftManager {
|
||||
private final Map<Integer, RiftBlockEntity> map;
|
||||
private final Pocket pocket;
|
||||
private int maxId;
|
||||
|
||||
public RiftManager(Pocket pocket) {
|
||||
this.pocket = pocket;
|
||||
map = pocket.getBlockEntities().values().stream()
|
||||
.filter(RiftBlockEntity.class::isInstance).map(RiftBlockEntity.class::cast)
|
||||
.filter(a -> a.getData().getDestination() instanceof IdMarker)
|
||||
.filter(a -> ((IdMarker) a.getData().getDestination()).getId() >= 0)
|
||||
.collect(Collectors.toMap(rift -> ((IdMarker) rift.getData().getDestination()).getId(), rift -> rift));
|
||||
maxId = map.keySet().stream()
|
||||
.mapToInt(a -> a)
|
||||
.max()
|
||||
.orElse(-1);
|
||||
}
|
||||
|
||||
//TODO add javadocs
|
||||
public boolean add(RiftBlockEntity rift) {
|
||||
if(rift.getData().getDestination() instanceof IdMarker) {
|
||||
int id = ((IdMarker) rift.getData().getDestination()).getId();
|
||||
|
||||
if(id < 0) return false;
|
||||
|
||||
map.put(id, rift);
|
||||
|
||||
maxId = Math.max(id, maxId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean consume(int id, Predicate<RiftBlockEntity> consumer) {
|
||||
if (map.containsKey(id) && consumer.test(map.get(id))) {
|
||||
map.remove(id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Pocket getPocket() {
|
||||
return pocket;
|
||||
}
|
||||
|
||||
public int nextId() {
|
||||
return maxId + 1;
|
||||
}
|
||||
|
||||
public boolean available(int id) { // TODO: remove? method is likely redundant
|
||||
return !map.containsKey(id);
|
||||
}
|
||||
|
||||
public void foreachConsume(BiPredicate<Integer, RiftBlockEntity> consumer) {
|
||||
for(int id : new HashSet<>(map.keySet())) {
|
||||
if(consumer.test(id, map.get(id))) {
|
||||
map.remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<RiftBlockEntity> get(int id) {
|
||||
return Optional.ofNullable(map.get(id));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package org.dimdev.dimdoors.pockets.modifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockBox;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.math.Equation;
|
||||
import org.dimdev.dimdoors.util.schematic.v2.SchematicBlockPalette;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
public class ShellModifier implements Modifier{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final String KEY = "shell";
|
||||
|
||||
private final List<Layer> layers = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
Modifier.super.toTag(tag);
|
||||
|
||||
ListTag layersTag = new ListTag();
|
||||
for (Layer layer : layers) {
|
||||
layersTag.add(layer.toTag());
|
||||
}
|
||||
tag.put("layers", layersTag);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifier fromTag(CompoundTag tag) {
|
||||
for (Tag layerTag : tag.getList("layers", NbtType.COMPOUND)) {
|
||||
CompoundTag compoundTag = (CompoundTag) layerTag;
|
||||
try {
|
||||
Layer layer = Layer.fromTag(compoundTag);
|
||||
layers.add(layer);
|
||||
} catch (CommandSyntaxException e) {
|
||||
LOGGER.error("could not parse Layer: " + compoundTag.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModifierType<? extends Modifier> getType() {
|
||||
return ModifierType.SHELL_MODIFIER_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PocketGenerationParameters parameters, RiftManager manager) {
|
||||
layers.forEach(layer -> drawLayer(layer, manager.getPocket(), parameters.getWorld()));
|
||||
}
|
||||
|
||||
private void drawLayer(Layer layer, Pocket pocket, ServerWorld world) {
|
||||
int thickness = layer.getThickness(pocket.toVariableMap(new HashMap<>()));
|
||||
final BlockState blockState = layer.getBlockState();
|
||||
BlockBox pocketBox = pocket.getBox();
|
||||
|
||||
// x-planes
|
||||
BlockPos.stream(BlockBox.create(pocketBox.maxX + 1, pocketBox.minY - thickness, pocketBox.minZ - thickness, pocketBox.maxX + thickness, pocketBox.maxY + thickness, pocketBox.maxZ + thickness))
|
||||
.forEach(blockPos -> world.setBlockState(blockPos, blockState));
|
||||
BlockPos.stream(BlockBox.create(pocketBox.minX - 1, pocketBox.minY - thickness, pocketBox.minZ - thickness, pocketBox.minX - thickness, pocketBox.maxY + thickness, pocketBox.maxZ + thickness))
|
||||
.forEach(blockPos -> world.setBlockState(blockPos, blockState));
|
||||
|
||||
// y-planes
|
||||
BlockPos.stream(BlockBox.create(pocketBox.minX, pocketBox.maxY + 1, pocketBox.minZ - thickness, pocketBox.maxX, pocketBox.maxY + thickness, pocketBox.maxZ + thickness))
|
||||
.forEach(blockPos -> world.setBlockState(blockPos, blockState));
|
||||
BlockPos.stream(BlockBox.create(pocketBox.minX, pocketBox.minY - 1, pocketBox.minZ - thickness, pocketBox.maxX, pocketBox.minY - thickness, pocketBox.maxZ + thickness))
|
||||
.forEach(blockPos -> world.setBlockState(blockPos, blockState));
|
||||
|
||||
// z-planes
|
||||
BlockPos.stream(BlockBox.create(pocketBox.minX, pocketBox.minY, pocketBox.minZ - 1, pocketBox.maxX, pocketBox.maxY, pocketBox.minZ - thickness))
|
||||
.forEach(blockPos -> world.setBlockState(blockPos, blockState));
|
||||
BlockPos.stream(BlockBox.create(pocketBox.minX, pocketBox.minY, pocketBox.maxZ + 1, pocketBox.maxX, pocketBox.maxY, pocketBox.maxZ + thickness))
|
||||
.forEach(blockPos -> world.setBlockState(blockPos, blockState));
|
||||
|
||||
pocket.expand(thickness);
|
||||
}
|
||||
|
||||
public static class Layer {
|
||||
private final String blockStateString;
|
||||
private final String thickness;
|
||||
private Equation thicknessEquation;
|
||||
private final BlockState blockState;
|
||||
|
||||
public Layer(String blockStateString, String thickness) {
|
||||
this.blockStateString = blockStateString;
|
||||
this.thickness = thickness;
|
||||
try {
|
||||
this.thicknessEquation = Equation.parse(thickness);
|
||||
} catch (Equation.EquationParseException e) {
|
||||
LOGGER.error("Could not parse layer thickness equation");
|
||||
this.thicknessEquation = variableMap -> 1d;
|
||||
}
|
||||
|
||||
this.blockState = SchematicBlockPalette.Entry.to(blockStateString).getOrThrow(false, LOGGER::error);
|
||||
}
|
||||
|
||||
public BlockState getBlockState() {
|
||||
return blockState;
|
||||
}
|
||||
|
||||
public int getThickness(Map<String, Double> variableMap) {
|
||||
return (int) thicknessEquation.apply(variableMap);
|
||||
}
|
||||
|
||||
public CompoundTag toTag() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putString("block_state", blockStateString);
|
||||
tag.putString("thickness", thickness);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static Layer fromTag(CompoundTag tag) throws CommandSyntaxException {
|
||||
return new Layer(tag.getString("block_state"), tag.getString("thickness"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package org.dimdev.dimdoors.pockets.virtual;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import org.dimdev.dimdoors.pockets.virtual.reference.PocketGeneratorReference;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.Weighted;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
public interface VirtualPocket extends Weighted<PocketGenerationParameters> {
|
||||
|
||||
static VirtualPocket deserialize(Tag tag) {
|
||||
if (tag.getType() == 9) { // ListTag
|
||||
return VirtualPocketList.deserialize((ListTag) tag);
|
||||
}
|
||||
return VirtualSingularPocket.deserialize((CompoundTag) tag); // should be CompoundTag
|
||||
}
|
||||
|
||||
static Tag serialize(VirtualPocket virtualPocket) {
|
||||
if (virtualPocket instanceof VirtualPocketList) {
|
||||
return VirtualPocketList.serialize((VirtualPocketList) virtualPocket);
|
||||
}
|
||||
return VirtualSingularPocket.serialize((VirtualSingularPocket) virtualPocket);
|
||||
}
|
||||
|
||||
|
||||
Pocket prepareAndPlacePocket(PocketGenerationParameters parameters);
|
||||
|
||||
PocketGeneratorReference getNextPocketGeneratorReference(PocketGenerationParameters parameters);
|
||||
|
||||
PocketGeneratorReference peekNextPocketGeneratorReference(PocketGenerationParameters parameters);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package org.dimdev.dimdoors.pockets.virtual;
|
||||
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import org.dimdev.dimdoors.pockets.virtual.reference.PocketGeneratorReference;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.WeightedList;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
// TODO: add weight tha
|
||||
public class VirtualPocketList extends WeightedList<VirtualPocket, PocketGenerationParameters> implements VirtualPocket {
|
||||
|
||||
public static VirtualPocketList deserialize(ListTag tag) {
|
||||
return new VirtualPocketList().fromTag(tag);
|
||||
}
|
||||
|
||||
public static ListTag serialize(VirtualPocketList virtualPocketList) {
|
||||
return virtualPocketList.toTag(new ListTag());
|
||||
}
|
||||
|
||||
|
||||
public VirtualPocketList() {
|
||||
super();
|
||||
}
|
||||
|
||||
public VirtualPocketList fromTag(ListTag tag) { // Keep in mind, this would add onto the list instead of overwriting it if called multiple times.
|
||||
for (net.minecraft.nbt.Tag value : tag) {
|
||||
this.add(VirtualPocket.deserialize(value));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ListTag toTag(ListTag tag) {
|
||||
for(VirtualPocket virtualPocket : this) {
|
||||
tag.add(VirtualPocket.serialize(virtualPocket));
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pocket prepareAndPlacePocket(PocketGenerationParameters parameters) {
|
||||
return getNextPocketGeneratorReference(parameters).prepareAndPlacePocket(parameters);
|
||||
}
|
||||
|
||||
public PocketGeneratorReference getNextPocketGeneratorReference(PocketGenerationParameters parameters) {
|
||||
return getNextRandomWeighted(parameters).getNextPocketGeneratorReference(parameters);
|
||||
}
|
||||
|
||||
public PocketGeneratorReference peekNextPocketGeneratorReference(PocketGenerationParameters parameters) {
|
||||
return peekNextRandomWeighted(parameters).peekNextPocketGeneratorReference(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWeight(PocketGenerationParameters parameters) {
|
||||
return peekNextRandomWeighted(parameters).getWeight(parameters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package org.dimdev.dimdoors.pockets.virtual;
|
||||
|
||||
import com.mojang.serialization.*;
|
||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import org.dimdev.dimdoors.pockets.virtual.reference.IdReference;
|
||||
import org.dimdev.dimdoors.pockets.virtual.reference.TagReference;
|
||||
import org.dimdev.dimdoors.pockets.virtual.selection.ConditionalSelector;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
||||
// TODO: do something about getting correct Pocket sizes
|
||||
public abstract class VirtualSingularPocket implements VirtualPocket {
|
||||
public static final Registry<VirtualSingularPocketType<? extends VirtualSingularPocket>> REGISTRY = FabricRegistryBuilder.from(new SimpleRegistry<VirtualSingularPocketType<? extends VirtualSingularPocket>>(RegistryKey.ofRegistry(new Identifier("dimdoors", "virtual_pocket_type")), Lifecycle.stable())).buildAndRegister();
|
||||
/*
|
||||
public static final Codec<VirtualPocket> CODEC = new Codec<VirtualPocket>() {
|
||||
@Override
|
||||
public <T> DataResult<Pair<VirtualPocket, T>> decode(DynamicOps<T> dynamicOps, T input) {
|
||||
Identifier id = new Identifier("dimdoors", Codec.STRING.decode(dynamicOps, dynamicOps.get(input, "virtual_type").getOrThrow(false, System.err::println)).getOrThrow(false, System.err::println).getFirst());
|
||||
return REGISTRY.get(id).getCodec().decode(dynamicOps, input).map(pair -> pair.mapFirst(virtualPocket -> (VirtualPocket) virtualPocket));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DataResult<T> encode(VirtualPocket input, DynamicOps<T> ops, T prefix) {
|
||||
return null; // TODO: write encode function
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
public static VirtualSingularPocket deserialize(CompoundTag tag) {
|
||||
Identifier id = Identifier.tryParse(tag.getString("type")); // TODO: return some NONE VirtualPocket if type cannot be found or deserialization fails.
|
||||
return REGISTRY.get(id).fromTag(tag);
|
||||
}
|
||||
|
||||
public static CompoundTag serialize(VirtualSingularPocket virtualSingularPocket) {
|
||||
return virtualSingularPocket.toTag(new CompoundTag());
|
||||
}
|
||||
|
||||
public abstract VirtualSingularPocket fromTag(CompoundTag tag);
|
||||
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
return this.getType().toTag(tag);
|
||||
}
|
||||
|
||||
public abstract VirtualSingularPocketType<? extends VirtualSingularPocket> getType();
|
||||
|
||||
public abstract String getKey();
|
||||
|
||||
|
||||
public interface VirtualSingularPocketType<T extends VirtualSingularPocket> {
|
||||
VirtualSingularPocketType<IdReference> ID_REFERENCE = register(new Identifier("dimdoors", IdReference.KEY), IdReference::new);
|
||||
VirtualSingularPocketType<TagReference> TAG_REFERENCE = register(new Identifier("dimdoors", TagReference.KEY), TagReference::new);
|
||||
|
||||
VirtualSingularPocketType<ConditionalSelector> DEPTH_DEPENDENT_SELECTOR = register(new Identifier("dimdoors", ConditionalSelector.KEY), ConditionalSelector::new);
|
||||
|
||||
|
||||
VirtualSingularPocket fromTag(CompoundTag tag);
|
||||
|
||||
CompoundTag toTag(CompoundTag tag);
|
||||
|
||||
static void register() {
|
||||
}
|
||||
|
||||
static <U extends VirtualSingularPocket> VirtualSingularPocketType<U> register(Identifier id, Supplier<U> constructor) {
|
||||
return Registry.register(REGISTRY, id, new VirtualSingularPocketType<U>() {
|
||||
@Override
|
||||
public VirtualSingularPocket fromTag(CompoundTag tag) {
|
||||
return constructor.get().fromTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag.putString("type", id.toString());
|
||||
return tag;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.dimdev.dimdoors.pockets.virtual.reference;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
||||
import org.dimdev.dimdoors.pockets.generator.PocketGenerator;
|
||||
import org.dimdev.dimdoors.pockets.virtual.VirtualSingularPocket;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
|
||||
public class IdReference extends PocketGeneratorReference {
|
||||
public static final String KEY = "id";
|
||||
|
||||
private String id;
|
||||
|
||||
@Override
|
||||
public VirtualSingularPocket fromTag(CompoundTag tag) {
|
||||
super.fromTag(tag);
|
||||
|
||||
id = tag.getString("id");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
|
||||
tag.putString("id", id);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGenerator peekReferencedPocketGenerator(PocketGenerationParameters parameters) {
|
||||
return getReferencedPocketGenerator(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGenerator getReferencedPocketGenerator(PocketGenerationParameters parameters) {
|
||||
return SchematicV2Handler.getInstance().getGenerator(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualSingularPocketType<? extends VirtualSingularPocket> getType() {
|
||||
return VirtualSingularPocketType.ID_REFERENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package org.dimdev.dimdoors.pockets.virtual.reference;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import org.dimdev.dimdoors.pockets.generator.PocketGenerator;
|
||||
import org.dimdev.dimdoors.pockets.modifier.Modifier;
|
||||
import org.dimdev.dimdoors.pockets.modifier.RiftManager;
|
||||
import org.dimdev.dimdoors.pockets.virtual.VirtualSingularPocket;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.math.Equation;
|
||||
import org.dimdev.dimdoors.util.math.Equation.EquationParseException;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PocketGeneratorReference extends VirtualSingularPocket {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final String defaultWeightEquation = "5"; // TODO: make config
|
||||
private static final int fallbackWeight = 5; // TODO: make config
|
||||
|
||||
private String weight;
|
||||
private Equation weightEquation;
|
||||
private Boolean setupLoot;
|
||||
private final List<Modifier> modifierList = Lists.newArrayList();
|
||||
|
||||
|
||||
private void parseWeight() {
|
||||
try {
|
||||
this.weightEquation = Equation.parse(weight);
|
||||
} catch (EquationParseException e) {
|
||||
LOGGER.error("Could not parse weight equation \"" + weight + "\", defaulting to default weight equation \"" + defaultWeightEquation + "\"", e);
|
||||
try {
|
||||
this.weightEquation = Equation.parse(defaultWeightEquation);
|
||||
} catch (EquationParseException equationParseException) {
|
||||
LOGGER.error("Could not parse default weight equation \"" + defaultWeightEquation + "\", defaulting to fallback weight \"" + fallbackWeight + "\"", equationParseException);
|
||||
this.weightEquation = stringDoubleMap -> fallbackWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualSingularPocket fromTag(CompoundTag tag) {
|
||||
if (tag.contains("weight")) { // override referenced pockets weight
|
||||
this.weight = tag.getString("weight");
|
||||
parseWeight();
|
||||
}
|
||||
|
||||
if (tag.contains("setup_loot")) setupLoot = tag.getBoolean("setup_loot");
|
||||
|
||||
if (tag.contains("modifiers")) {
|
||||
ListTag modifiersTag = tag.getList("modifiers", 10);
|
||||
for (int i = 0; i < modifiersTag.size(); i++) {
|
||||
modifierList.add(Modifier.deserialize(modifiersTag.getCompound(i)));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
|
||||
if (weight != null) tag.putString("weight", weight);
|
||||
|
||||
if (setupLoot != null) tag.putBoolean("setup_loot", setupLoot);
|
||||
|
||||
ListTag modifiersTag = new ListTag();
|
||||
for (Modifier modifier : modifierList) {
|
||||
modifiersTag.add(modifier.toTag(new CompoundTag()));
|
||||
}
|
||||
if (modifiersTag.size() > 0) tag.put("modifiers", modifiersTag);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWeight(PocketGenerationParameters parameters) {
|
||||
return weightEquation != null ? this.weightEquation.apply(parameters.toVariableMap(Maps.newHashMap())) : peekReferencedPocketGenerator(parameters).getWeight(parameters);
|
||||
}
|
||||
|
||||
public void applyModifiers(PocketGenerationParameters parameters, RiftManager manager) {
|
||||
for (Modifier modifier : modifierList) {
|
||||
modifier.apply(parameters, manager);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pocket prepareAndPlacePocket(PocketGenerationParameters parameters) {
|
||||
PocketGenerator generator = getReferencedPocketGenerator(parameters);
|
||||
Pocket pocket = generator.prepareAndPlacePocket(parameters);
|
||||
|
||||
RiftManager manager = new RiftManager(pocket);
|
||||
|
||||
generator.applyModifiers(parameters, manager);
|
||||
|
||||
this.applyModifiers(parameters, manager);
|
||||
generator.setup(pocket, parameters, setupLoot != null ? setupLoot : true);
|
||||
return pocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGeneratorReference peekNextPocketGeneratorReference(PocketGenerationParameters parameters) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGeneratorReference getNextPocketGeneratorReference(PocketGenerationParameters parameters) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract PocketGenerator peekReferencedPocketGenerator(PocketGenerationParameters parameters);
|
||||
|
||||
public abstract PocketGenerator getReferencedPocketGenerator(PocketGenerationParameters parameters);
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package org.dimdev.dimdoors.pockets.virtual.reference;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
||||
import org.dimdev.dimdoors.pockets.generator.PocketGenerator;
|
||||
import org.dimdev.dimdoors.pockets.virtual.VirtualSingularPocket;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.WeightedList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TagReference extends PocketGeneratorReference{
|
||||
public static final String KEY = "tag";
|
||||
|
||||
private final List<String> required = new ArrayList<>();
|
||||
private final List<String> blackList = new ArrayList<>();
|
||||
private Boolean exact;
|
||||
|
||||
private WeightedList<PocketGenerator, PocketGenerationParameters> pockets;
|
||||
|
||||
@Override
|
||||
public VirtualSingularPocket fromTag(CompoundTag tag) {
|
||||
super.fromTag(tag);
|
||||
|
||||
if (tag.contains("required")) {
|
||||
ListTag listTag = tag.getList("required", NbtType.STRING);
|
||||
for (int i = 0; i < listTag.size(); i++) {
|
||||
required.add(listTag.getString(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (tag.contains("blackList")) {
|
||||
ListTag listTag = tag.getList("blackList", NbtType.STRING);
|
||||
for (int i = 0; i < listTag.size(); i++) {
|
||||
blackList.add(listTag.getString(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (tag.contains("exact")) exact = tag.getBoolean("exact");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
|
||||
if (required.size() > 0) {
|
||||
ListTag listTag = new ListTag();
|
||||
for (String tagString : required) {
|
||||
listTag.add(StringTag.of(tagString));
|
||||
}
|
||||
tag.put("required", listTag);
|
||||
}
|
||||
|
||||
if (blackList.size() > 0) {
|
||||
ListTag listTag = new ListTag();
|
||||
for (String tagString : blackList) {
|
||||
listTag.add(StringTag.of(tagString));
|
||||
}
|
||||
tag.put("blackList", listTag);
|
||||
}
|
||||
|
||||
if (exact != null) {
|
||||
tag.putBoolean("exact", exact);
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VirtualSingularPocketType<? extends VirtualSingularPocket> getType() {
|
||||
return VirtualSingularPocketType.TAG_REFERENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
// TODO: this will break if pockets change in between (which they could if we add a tool for creating pocket json config stuff ingame)
|
||||
@Override
|
||||
public PocketGenerator peekReferencedPocketGenerator(PocketGenerationParameters parameters) {
|
||||
if (pockets == null) pockets = SchematicV2Handler.getInstance().getPocketsMatchingTags(required, blackList, exact);
|
||||
return pockets.peekNextRandomWeighted(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGenerator getReferencedPocketGenerator(PocketGenerationParameters parameters) {
|
||||
if (pockets == null) pockets = SchematicV2Handler.getInstance().getPocketsMatchingTags(required, blackList, exact);
|
||||
return pockets.getNextRandomWeighted(parameters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package org.dimdev.dimdoors.pockets.virtual.selection;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.pockets.virtual.VirtualPocket;
|
||||
import org.dimdev.dimdoors.pockets.virtual.VirtualSingularPocket;
|
||||
import org.dimdev.dimdoors.pockets.virtual.reference.PocketGeneratorReference;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.math.Equation;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConditionalSelector extends VirtualSingularPocket {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final String KEY = "conditional";
|
||||
/*
|
||||
private static final Codec<Pair<String, VirtualPocket>> PAIR_CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.STRING.fieldOf("regex").forGetter(Pair::getLeft),
|
||||
VirtualPocket.CODEC.fieldOf("pocket").forGetter(Pair::getRight)
|
||||
).apply(instance, Pair::new));
|
||||
|
||||
public static final Codec<DepthDependentSelector> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.STRING.fieldOf("id").forGetter(DepthDependentSelector::getName),
|
||||
PAIR_CODEC.listOf().fieldOf("pockets").forGetter(DepthDependentSelector::getPocketList)
|
||||
).apply(instance, DepthDependentSelector::new));
|
||||
*/
|
||||
|
||||
|
||||
|
||||
private LinkedHashMap<String, VirtualPocket> pocketMap = Maps.newLinkedHashMap();
|
||||
private LinkedHashMap<String, Equation> equationMap = Maps.newLinkedHashMap();
|
||||
|
||||
public ConditionalSelector() {
|
||||
}
|
||||
|
||||
public ConditionalSelector(LinkedHashMap<String, VirtualPocket> pocketMap) {
|
||||
this.pocketMap = pocketMap;
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, VirtualPocket> getPocketMap() {
|
||||
return pocketMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualSingularPocket fromTag(CompoundTag tag) {
|
||||
ListTag conditionalPockets = tag.getList("pockets", 10);
|
||||
for (int i = 0; i < conditionalPockets.size(); i++) {
|
||||
CompoundTag pocket = conditionalPockets.getCompound(i);
|
||||
String condition = pocket.getString("condition");
|
||||
if (pocketMap.containsKey(condition)) continue;
|
||||
try {
|
||||
equationMap.put(condition, Equation.parse(condition));
|
||||
pocketMap.put(condition, VirtualPocket.deserialize(pocket.get("pocket")));
|
||||
} catch (Equation.EquationParseException e) {
|
||||
LOGGER.error("Could not parse pocket condition equation!", e);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
|
||||
ListTag conditionalPockets = new ListTag();
|
||||
pocketMap.forEach((condition, pocket) -> {
|
||||
CompoundTag compound = new CompoundTag();
|
||||
compound.putString("condition", condition);
|
||||
compound.put("pocket", VirtualPocket.serialize(pocket));
|
||||
conditionalPockets.add(compound);
|
||||
});
|
||||
tag.put("pockets", conditionalPockets);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pocket prepareAndPlacePocket(PocketGenerationParameters parameters) {
|
||||
return getNextPocket(parameters).prepareAndPlacePocket(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGeneratorReference getNextPocketGeneratorReference(PocketGenerationParameters parameters) {
|
||||
return getNextPocket(parameters).getNextPocketGeneratorReference(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketGeneratorReference peekNextPocketGeneratorReference(PocketGenerationParameters parameters) {
|
||||
return getNextPocket(parameters).peekNextPocketGeneratorReference(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualSingularPocketType<? extends VirtualSingularPocket> getType() {
|
||||
return VirtualSingularPocketType.DEPTH_DEPENDENT_SELECTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWeight(PocketGenerationParameters parameters) {
|
||||
return getNextPocket(parameters).getWeight(parameters);
|
||||
}
|
||||
|
||||
private VirtualPocket getNextPocket(PocketGenerationParameters parameters) {
|
||||
for (Map.Entry<String, VirtualPocket> entry : pocketMap.entrySet()) {
|
||||
if (equationMap.get(entry.getKey()).asBoolean(parameters.toVariableMap(new HashMap<>()))) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return pocketMap.values().stream().findFirst().get(); // TODO: orElse() with some NONE VirtualPocket
|
||||
}
|
||||
}
|
|
@ -13,9 +13,10 @@ import org.apache.logging.log4j.Logger;
|
|||
|
||||
import org.dimdev.dimdoors.util.GraphUtils;
|
||||
import org.dimdev.dimdoors.util.Location;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.PocketDirectory;
|
||||
import org.dimdev.dimdoors.world.pocket.PrivatePocketData;
|
||||
import org.dimdev.dimdoors.world.pocket.PrivateRegistry;
|
||||
import org.jgrapht.graph.DefaultDirectedGraph;
|
||||
import org.jgrapht.graph.DefaultEdge;
|
||||
|
||||
|
@ -308,7 +309,7 @@ public class RiftRegistry {
|
|||
if (entrance != null) return entrance.location;
|
||||
|
||||
// If there was no last used private entrance, get the first player's private pocket entrance
|
||||
return this.getPocketEntrance(PrivatePocketData.instance().getPrivatePocket(playerUUID));
|
||||
return this.getPocketEntrance(DimensionalRegistry.getPrivateRegistry().getPrivatePocket(playerUUID));
|
||||
}
|
||||
|
||||
private void setPlayerRiftPointer(UUID playerUUID, Location rift, Map<UUID, PlayerRiftPointer> map) {
|
||||
|
|
|
@ -26,7 +26,7 @@ public class GlobalReference extends RiftReference {
|
|||
|
||||
public static CompoundTag toTag(GlobalReference virtualTarget) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.put("target", Location.toTag(virtualTarget.location));
|
||||
tag.put("target", Location.toTag(virtualTarget.getReferencedLocation()));
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
|
41
src/main/java/org/dimdev/dimdoors/rift/targets/IdMarker.java
Normal file
41
src/main/java/org/dimdev/dimdoors/rift/targets/IdMarker.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import org.dimdev.dimdoors.util.EntityUtils;
|
||||
import org.dimdev.dimdoors.util.Location;
|
||||
|
||||
public class IdMarker extends VirtualTarget implements EntityTarget {
|
||||
private final int id;
|
||||
|
||||
public IdMarker(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualTargetType<? extends VirtualTarget> getType() {
|
||||
return VirtualTargetType.ID_MARKER;
|
||||
}
|
||||
|
||||
public static CompoundTag toTag(IdMarker target) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt("id", target.id);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static IdMarker fromTag(CompoundTag nbt) {
|
||||
return new IdMarker(nbt.getInt("id"));
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean receiveEntity(Entity entity, float yawOffset) {
|
||||
EntityUtils.chat(entity, Text.of("This rift is configured for pocket dungeons. Its id is " + id));
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ public class PocketEntranceMarker extends VirtualTarget implements EntityTarget
|
|||
private VirtualTarget ifDestination = NoneTarget.INSTANCE;
|
||||
private VirtualTarget otherwiseDestination = NoneTarget.INSTANCE;
|
||||
|
||||
PocketEntranceMarkerBuilder() {
|
||||
private PocketEntranceMarkerBuilder() {
|
||||
}
|
||||
|
||||
public PocketEntranceMarker.PocketEntranceMarkerBuilder weight(float weight) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.dimdev.dimdoors.util.RGBA;
|
|||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.PocketDirectory;
|
||||
import org.dimdev.dimdoors.world.pocket.PrivatePocketData;
|
||||
import org.dimdev.dimdoors.world.pocket.PrivateRegistry;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
@ -30,8 +30,8 @@ public class PrivatePocketExitTarget extends VirtualTarget implements EntityTarg
|
|||
UUID uuid = EntityUtils.getOwner(entity).getUuid();
|
||||
if (uuid != null) {
|
||||
destLoc = DimensionalRegistry.getRiftRegistry().getPrivatePocketExit(uuid);
|
||||
Pocket pocket = PrivatePocketData.instance().getPrivatePocket(uuid);
|
||||
if (ModDimensions.isPocketDimension(this.location.getWorld()) && pocket != null && DimensionalRegistry.getPocketDirectory(pocket.world).getPocketAt(this.location.pos).equals(pocket)) {
|
||||
Pocket pocket = DimensionalRegistry.getPrivateRegistry().getPrivatePocket(uuid);
|
||||
if (ModDimensions.isPersonalPocketDimension(this.location.getWorld()) && pocket != null && DimensionalRegistry.getPocketDirectory(pocket.world).getPocketAt(this.location.pos).equals(pocket)) {
|
||||
DimensionalRegistry.getRiftRegistry().setLastPrivatePocketEntrance(uuid, this.location); // Remember which exit was used for next time the pocket is entered
|
||||
}
|
||||
if (destLoc == null || !(destLoc.getBlockEntity() instanceof RiftBlockEntity)) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.dimdev.dimdoors.util.EntityUtils;
|
|||
import org.dimdev.dimdoors.util.Location;
|
||||
import org.dimdev.dimdoors.util.RGBA;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.PrivatePocketData;
|
||||
import org.dimdev.dimdoors.world.pocket.PrivateRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.VirtualLocation;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
|
@ -33,12 +33,12 @@ public class PrivatePocketTarget extends VirtualTarget implements EntityTarget {
|
|||
UUID uuid = EntityUtils.getOwner(entity).getUuid();
|
||||
VirtualLocation virtualLocation = VirtualLocation.fromLocation(this.location);
|
||||
if (uuid != null) {
|
||||
Pocket pocket = PrivatePocketData.instance().getPrivatePocket(uuid);
|
||||
Pocket pocket = DimensionalRegistry.getPrivateRegistry().getPrivatePocket(uuid);
|
||||
if (pocket == null) { // generate the private pocket and get its entrances
|
||||
// set to where the pocket was first created
|
||||
pocket = PocketGenerator.generatePrivatePocketV2(new VirtualLocation(virtualLocation.getWorld(), virtualLocation.getX(), virtualLocation.getZ(), -1));
|
||||
|
||||
PrivatePocketData.instance().setPrivatePocketID(uuid, pocket);
|
||||
DimensionalRegistry.getPrivateRegistry().setPrivatePocketID(uuid, pocket);
|
||||
BlockEntity be = DimensionalRegistry.getRiftRegistry().getPocketEntrance(pocket).getBlockEntity();
|
||||
this.processEntity(pocket, be, entity, uuid, yawOffset);
|
||||
} else {
|
||||
|
@ -49,7 +49,7 @@ public class PrivatePocketTarget extends VirtualTarget implements EntityTarget {
|
|||
LOGGER.info("All entrances are gone, creating a new private pocket!");
|
||||
pocket = PocketGenerator.generatePrivatePocketV2(new VirtualLocation(virtualLocation.getWorld(), virtualLocation.getX(), virtualLocation.getZ(), -1));
|
||||
|
||||
PrivatePocketData.instance().setPrivatePocketID(uuid, pocket);
|
||||
DimensionalRegistry.getPrivateRegistry().setPrivatePocketID(uuid, pocket);
|
||||
destLoc = DimensionalRegistry.getRiftRegistry().getPocketEntrance(pocket);
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,11 @@ public class PrivatePocketTarget extends VirtualTarget implements EntityTarget {
|
|||
Item item = ((ItemEntity) entity).getStack().getItem();
|
||||
|
||||
if (item instanceof DyeItem) {
|
||||
pocket.addDye(EntityUtils.getOwner(entity), ((DyeItem) item).getColor());
|
||||
entity.remove();
|
||||
if(pocket.addDye(EntityUtils.getOwner(entity), ((DyeItem) item).getColor())) {
|
||||
entity.remove();
|
||||
} else {
|
||||
((EntityTarget) blockEntity).receiveEntity(entity, relativeYaw);
|
||||
}
|
||||
} else {
|
||||
((EntityTarget) blockEntity).receiveEntity(entity, relativeYaw);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public class PublicPocketTarget extends RestoringTarget {
|
|||
public Location makeLinkTarget() {
|
||||
VirtualLocation riftVirtualLocation = VirtualLocation.fromLocation(this.location);
|
||||
VirtualLocation newVirtualLocation;
|
||||
int depth = Math.max(riftVirtualLocation.getDepth(), 1);
|
||||
int depth = riftVirtualLocation.getDepth()+1;
|
||||
newVirtualLocation = new VirtualLocation(riftVirtualLocation.getWorld(), riftVirtualLocation.getX(), riftVirtualLocation.getZ(), depth);
|
||||
Pocket pocket = PocketGenerator.generatePublicPocketV2(newVirtualLocation, new GlobalReference(this.location), null);
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ public class RandomTarget extends VirtualTarget { // TODO: Split into DungeonTar
|
|||
// Make a new dungeon pocket
|
||||
RiftBlockEntity thisRift = (RiftBlockEntity) this.location.getBlockEntity();
|
||||
LinkProperties newLink = thisRift.getProperties() != null ? thisRift.getProperties().toBuilder().linksRemaining(0).build() : null;
|
||||
Pocket pocket = PocketGenerator.generateDungeonPocket(virtualLocation, new GlobalReference(!this.noLinkBack ? this.location : null), newLink); // TODO make the generated dungeon of the same type, but in the overworld
|
||||
Pocket pocket = PocketGenerator.generateDungeonPocketV2(virtualLocation, new GlobalReference(!this.noLinkBack ? this.location : null), newLink); // TODO make the generated dungeon of the same type, but in the overworld
|
||||
|
||||
// Link the rift if necessary and teleport the entity
|
||||
if (!this.noLink) linkRifts(this.location, DimensionalRegistry.getRiftRegistry().getPocketEntrance(pocket));
|
||||
|
|
|
@ -11,14 +11,13 @@ public abstract class RestoringTarget extends VirtualTarget {
|
|||
@Override
|
||||
public Target receiveOther() {
|
||||
if (this.getTarget() != null) {
|
||||
this.getTarget().location = this.location;
|
||||
return this.getTarget();
|
||||
}
|
||||
|
||||
Location linkTarget = this.makeLinkTarget();
|
||||
if (linkTarget != null) {
|
||||
this.setTarget(RiftReference.tryMakeLocal(this.location, linkTarget));
|
||||
this.getTarget().setLocation(this.location);
|
||||
this.getTarget().setLocation(linkTarget);
|
||||
this.getTarget().register();
|
||||
|
||||
return this.getTarget();
|
||||
|
|
|
@ -88,6 +88,7 @@ public abstract class VirtualTarget implements Target {
|
|||
VirtualTargetType<PrivatePocketTarget> PRIVATE = register("dimdoors:private", a -> new PrivatePocketTarget(), a -> new CompoundTag(), PrivatePocketExitTarget.COLOR);
|
||||
VirtualTargetType<PrivatePocketExitTarget> PRIVATE_POCKET_EXIT = register("dimdoors:private_pocket_exit", a -> new PrivatePocketExitTarget(), a -> new CompoundTag(), PrivatePocketExitTarget.COLOR);
|
||||
VirtualTargetType<RelativeReference> RELATIVE = register("dimdoors:relative", RelativeReference::fromTag, RelativeReference::toTag, VirtualTarget.COLOR);
|
||||
VirtualTargetType<IdMarker> ID_MARKER = register("dimdoors:id_marker", IdMarker::fromTag, IdMarker::toTag, VirtualTarget.COLOR);
|
||||
VirtualTargetType<NoneTarget> NONE = register("dimdoors:none", tag -> NoneTarget.INSTANCE, i -> new CompoundTag(), COLOR);
|
||||
|
||||
T fromTag(CompoundTag tag);
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package org.dimdev.dimdoors.util;
|
||||
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.ModConfig;
|
||||
import org.dimdev.dimdoors.rift.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.VirtualLocation;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PocketGenerationParameters {
|
||||
private final ServerWorld world;
|
||||
private final String group;
|
||||
private final VirtualLocation sourceVirtualLocation;
|
||||
private final VirtualTarget linkTo;
|
||||
private final LinkProperties linkProperties;
|
||||
|
||||
public PocketGenerationParameters(ServerWorld world, String group, VirtualLocation sourceVirtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
this.world = world;
|
||||
this.group = group;
|
||||
this.sourceVirtualLocation = sourceVirtualLocation;
|
||||
this.linkTo = linkTo;
|
||||
this.linkProperties = linkProperties;
|
||||
}
|
||||
|
||||
public ServerWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public VirtualLocation getSourceVirtualLocation() {
|
||||
return sourceVirtualLocation;
|
||||
}
|
||||
|
||||
public VirtualTarget getLinkTo() {
|
||||
return linkTo;
|
||||
}
|
||||
|
||||
public LinkProperties getLinkProperties() {
|
||||
return linkProperties;
|
||||
}
|
||||
|
||||
public Map<String, Double> toVariableMap(Map<String, Double> stringDoubleMap) {
|
||||
stringDoubleMap.put("depth", (double) this.sourceVirtualLocation.getDepth());
|
||||
stringDoubleMap.put("public_size", (double) DimensionalDoorsInitializer.CONFIG.getPocketsConfig().publicPocketSize);
|
||||
stringDoubleMap.put("private_size", (double) DimensionalDoorsInitializer.CONFIG.getPocketsConfig().privatePocketSize);
|
||||
return stringDoubleMap;
|
||||
}
|
||||
}
|
67
src/main/java/org/dimdev/dimdoors/util/TagEquations.java
Normal file
67
src/main/java/org/dimdev/dimdoors/util/TagEquations.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
package org.dimdev.dimdoors.util;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.util.math.Equation;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TagEquations {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static CompoundTag solveCompoundTagEquations(CompoundTag tag, Map<String, Double> variableMap) {
|
||||
CompoundTag solved = new CompoundTag();
|
||||
for (String key : tag.getKeys()) {
|
||||
if (tag.getType(key) == NbtType.STRING && key.startsWith("equation_")){
|
||||
try {
|
||||
double solution = Equation.parse(tag.getString(key)).apply(variableMap);
|
||||
key = key.substring(9);
|
||||
if (key.startsWith("int_")) {
|
||||
key = key.substring(4);
|
||||
solved.putInt(key, (int) solution);
|
||||
}
|
||||
else if (key.startsWith("boolean_")) {
|
||||
key = key.substring(8);
|
||||
solved.putBoolean(key, Equation.toBoolean(solution));
|
||||
}
|
||||
else if (key.startsWith("double_")) {
|
||||
key = key.substring(7);
|
||||
solved.putDouble(key, solution);
|
||||
}
|
||||
else {
|
||||
solved.putDouble(key, solution);
|
||||
}
|
||||
} catch (Equation.EquationParseException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
} else if (tag.getType(key) == NbtType.COMPOUND) {
|
||||
solved.put(key, solveCompoundTagEquations(tag.getCompound(key), variableMap));
|
||||
} else if (tag.getType(key) == NbtType.LIST) {
|
||||
solved.put(key, solveListTagEquations((ListTag) tag.get(key), variableMap));
|
||||
}
|
||||
else {
|
||||
solved.put(key, tag.get(key));
|
||||
}
|
||||
}
|
||||
return solved;
|
||||
}
|
||||
|
||||
public static ListTag solveListTagEquations(ListTag listTag, Map<String, Double> variableMap) {
|
||||
ListTag solved = new ListTag();
|
||||
for(Tag tag : listTag) {
|
||||
if (tag.getType() == NbtType.LIST) {
|
||||
solved.add(solveListTagEquations((ListTag) tag, variableMap));
|
||||
}
|
||||
else if (tag.getType() == NbtType.COMPOUND) {
|
||||
solved.add(solveCompoundTagEquations((CompoundTag) tag, variableMap));
|
||||
}
|
||||
else {
|
||||
solved.add(tag);
|
||||
}
|
||||
}
|
||||
return solved;
|
||||
}
|
||||
}
|
9
src/main/java/org/dimdev/dimdoors/util/Weighted.java
Normal file
9
src/main/java/org/dimdev/dimdoors/util/Weighted.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
package org.dimdev.dimdoors.util;
|
||||
|
||||
public interface Weighted<P> {
|
||||
/*
|
||||
Should always return the same number if the same parameters are provided.
|
||||
returned number should always be >= 0
|
||||
*/
|
||||
double getWeight(P parameters);
|
||||
}
|
52
src/main/java/org/dimdev/dimdoors/util/WeightedList.java
Normal file
52
src/main/java/org/dimdev/dimdoors/util/WeightedList.java
Normal file
|
@ -0,0 +1,52 @@
|
|||
package org.dimdev.dimdoors.util;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class WeightedList<T extends Weighted<P>, P> extends ArrayList<T> {
|
||||
private final Random random = new Random();
|
||||
private T peekedRandom;
|
||||
private boolean peeked = false;
|
||||
|
||||
public WeightedList() { }
|
||||
|
||||
public WeightedList(Collection<? extends T> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
public T getNextRandomWeighted(P parameters) {
|
||||
return getNextRandomWeighted(parameters, false);
|
||||
}
|
||||
|
||||
public T peekNextRandomWeighted(P parameters) {
|
||||
return getNextRandomWeighted(parameters, true);
|
||||
}
|
||||
|
||||
private T getNextRandomWeighted(P parameters, boolean peek) {
|
||||
if (!peeked) {
|
||||
double totalWeight = stream().mapToDouble(weighted -> weighted.getWeight(parameters)).sum();
|
||||
double cursor = random.nextDouble() * totalWeight;
|
||||
if (cursor == 0) {
|
||||
for (T weighted : this) {
|
||||
if (weighted.getWeight(parameters) != 0) return weighted;
|
||||
}
|
||||
}
|
||||
for (T weighted : this) {
|
||||
cursor -= weighted.getWeight(parameters);
|
||||
if (cursor <= 0) {
|
||||
if (peek) {
|
||||
peekedRandom = weighted;
|
||||
peeked = true;
|
||||
}
|
||||
return weighted; // should never return an entry with weight 0, unless there are only weight 0 entries
|
||||
}
|
||||
}
|
||||
if (peek) {
|
||||
peekedRandom = null;
|
||||
peeked = true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (!peek) peeked = false;
|
||||
return peekedRandom;
|
||||
}
|
||||
}
|
213
src/main/java/org/dimdev/dimdoors/util/math/Equation.java
Normal file
213
src/main/java/org/dimdev/dimdoors/util/math/Equation.java
Normal file
|
@ -0,0 +1,213 @@
|
|||
package org.dimdev.dimdoors.util.math;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public interface Equation {
|
||||
double FALSE = 0d;
|
||||
double TRUE = 1d;
|
||||
|
||||
double apply(Map<String, Double> variableMap);
|
||||
|
||||
default boolean asBoolean(Map<String, Double> variableMap) {
|
||||
return toBoolean(apply(variableMap));
|
||||
}
|
||||
|
||||
static Equation parse(String equationString) throws EquationParseException {
|
||||
return StringEquationParser.INSTANCE.parse(equationString);
|
||||
}
|
||||
|
||||
static double toDouble(boolean value) {
|
||||
return value ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static boolean toBoolean(double value) {
|
||||
return value != FALSE;
|
||||
}
|
||||
|
||||
class StringEquationParser {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static StringEquationParser INSTANCE = new StringEquationParser();
|
||||
private final static List<EquationParser> parseRules = new ArrayList<>();
|
||||
|
||||
static {
|
||||
// Parenthesis
|
||||
parseRules.add(toParse -> {
|
||||
if (!toParse.startsWith("(") || !toParse.endsWith(")")) return Optional.empty();
|
||||
return Optional.of(Equation.parse(toParse.substring(1, toParse.length() - 1)));
|
||||
});
|
||||
|
||||
// try to parse as Double
|
||||
parseRules.add(toParse -> {
|
||||
try {
|
||||
Double result = Double.parseDouble(toParse);
|
||||
return Optional.of(stringDoubleMap -> result);
|
||||
} catch (NumberFormatException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
});
|
||||
|
||||
// some logic first
|
||||
// ||
|
||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> or = new HashMap<>();
|
||||
or.put("||", (stringDoubleMap, first, second) -> toDouble(first.asBoolean(stringDoubleMap) || second.asBoolean(stringDoubleMap)));
|
||||
parseRules.add(new SplitterParser(or));
|
||||
|
||||
// &&
|
||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> and = new HashMap<>();
|
||||
and.put("&&", (stringDoubleMap, first, second) -> toDouble(first.asBoolean(stringDoubleMap) || second.asBoolean(stringDoubleMap)));
|
||||
parseRules.add(new SplitterParser(and));
|
||||
|
||||
// ==, <=, >=, <, >
|
||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> comparators = new HashMap<>();
|
||||
comparators.put("==", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) == second.apply(stringDoubleMap)));
|
||||
comparators.put("<=", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) <= second.apply(stringDoubleMap)));
|
||||
comparators.put(">=", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) >= second.apply(stringDoubleMap)));
|
||||
comparators.put("<", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) < second.apply(stringDoubleMap)));
|
||||
comparators.put(">", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) > second.apply(stringDoubleMap)));
|
||||
parseRules.add(new SplitterParser(comparators));
|
||||
|
||||
// +, -
|
||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> sumOperations = new HashMap<>();
|
||||
sumOperations.put("+", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) + second.apply(stringDoubleMap));
|
||||
sumOperations.put("-", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) - second.apply(stringDoubleMap));
|
||||
parseRules.add(new SplitterParser(sumOperations));
|
||||
|
||||
// *, /, %
|
||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> dotOperations = new HashMap<>();
|
||||
dotOperations.put("*", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) * second.apply(stringDoubleMap));
|
||||
dotOperations.put("/", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) / second.apply(stringDoubleMap));
|
||||
dotOperations.put("%", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) % second.apply(stringDoubleMap));
|
||||
parseRules.add(new SplitterParser(dotOperations));
|
||||
|
||||
// x^y
|
||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> exponentOperations = new HashMap<>();
|
||||
exponentOperations.put("^", (stringDoubleMap, first, second) -> Math.pow(first.apply(stringDoubleMap), second.apply(stringDoubleMap)));
|
||||
parseRules.add(new SplitterParser(exponentOperations));
|
||||
|
||||
// H with H(0) = 1: https://en.wikipedia.org/wiki/Heaviside_step_function
|
||||
parseRules.add(new FunctionParser("H", 1, 1, ((stringDoubleMap, equations) -> equations[0].apply(stringDoubleMap) >= 0 ? 1d : 0d)));
|
||||
|
||||
// floor
|
||||
parseRules.add(new FunctionParser("floor", 1, 1, ((stringDoubleMap, equations) -> Math.floor(equations[0].apply(stringDoubleMap)))));
|
||||
|
||||
// ceil
|
||||
parseRules.add(new FunctionParser("ceil", 1, 1, ((stringDoubleMap, equations) -> Math.ceil(equations[0].apply(stringDoubleMap)))));
|
||||
|
||||
// max
|
||||
parseRules.add(new FunctionParser("max", 2, -1, ((stringDoubleMap, equations) -> {
|
||||
Double max = equations[0].apply(stringDoubleMap);
|
||||
for (int i = 1; i < equations.length; i++) {
|
||||
max = Math.max(max, equations[i].apply(stringDoubleMap));
|
||||
}
|
||||
return max;
|
||||
})));
|
||||
|
||||
// min
|
||||
parseRules.add(new FunctionParser("min", 2, -1, ((stringDoubleMap, equations) -> {
|
||||
Double min = equations[0].apply(stringDoubleMap);
|
||||
for (int i = 1; i < equations.length; i++) {
|
||||
min = Math.min(min, equations[i].apply(stringDoubleMap));
|
||||
}
|
||||
return min;
|
||||
})));
|
||||
|
||||
// variable replacer
|
||||
parseRules.add(new VariableReplacer());
|
||||
}
|
||||
|
||||
public Equation parse(String equationString) throws EquationParseException {
|
||||
equationString = equationString.replaceAll("\\s", "");
|
||||
for (EquationParser parser : parseRules) {
|
||||
Optional<Equation> equation = parser.tryParse(equationString);
|
||||
if (equation.isPresent()) return equation.get();
|
||||
}
|
||||
throw new EquationParseException("\"" + equationString + "\" could not be parsed");
|
||||
}
|
||||
|
||||
|
||||
private interface EquationParser {
|
||||
Optional<Equation> tryParse(String toParse) throws EquationParseException;
|
||||
}
|
||||
|
||||
private static class VariableReplacer implements EquationParser {
|
||||
@Override
|
||||
public Optional<Equation> tryParse(String toParse) {
|
||||
if (!toParse.matches("[a-zA-Z_][a-zA-Z0-9_]*")) return Optional.empty();
|
||||
return Optional.of(stringDoubleMap -> {
|
||||
if (stringDoubleMap != null && stringDoubleMap.containsKey(toParse)) return stringDoubleMap.get(toParse);
|
||||
LOGGER.error("Variable \"" + toParse + "\" was not passed to equation! Returning 0 as fallback.");
|
||||
return 0d;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class SplitterParser implements EquationParser {
|
||||
private final Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> operations;
|
||||
|
||||
public SplitterParser(Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> operations) {
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Equation> tryParse(String toParse) throws EquationParseException {
|
||||
int depth = 0;
|
||||
for (int i = toParse.length() - 1; i >= 1 ; i--) {
|
||||
String substring = toParse.substring(i);
|
||||
if (substring.startsWith(")")) depth++;
|
||||
else if (substring.startsWith("(")) depth--;
|
||||
for(String symbol : operations.keySet()) {
|
||||
if (substring.startsWith(symbol) && depth == 0) {
|
||||
final TriFunction<Map<String, Double>, Equation, Equation, Double> operation = operations.get(symbol);
|
||||
final Equation first = Equation.parse(toParse.substring(0,i));
|
||||
final Equation second = Equation.parse(toParse.substring(i+1));
|
||||
return Optional.of(stringDoubleMap -> operation.apply(stringDoubleMap, first, second));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static class FunctionParser implements EquationParser {
|
||||
private final String functionString;
|
||||
private final int minArguments;
|
||||
private final int maxArguments;
|
||||
private final BiFunction<Map<String, Double>, Equation[], Double> function;
|
||||
|
||||
public FunctionParser(String functionString, int minArguments, int maxArguments, BiFunction<Map<String, Double>, Equation[], Double> function) {
|
||||
this.functionString = functionString + "(";
|
||||
this.minArguments = minArguments;
|
||||
this.maxArguments = maxArguments;
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Equation> tryParse(String toParse) throws EquationParseException {
|
||||
if (!toParse.startsWith(functionString) || !toParse.endsWith(")")) return Optional.empty();
|
||||
String[] arguments = toParse.substring(functionString.length(), toParse.length()-1).split(",");
|
||||
if (minArguments > arguments.length || (maxArguments < arguments.length && maxArguments != -1)) return Optional.empty();
|
||||
final Equation[] argumentEquations = new Equation[arguments.length];
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
argumentEquations[i] = Equation.parse(arguments[i]);
|
||||
}
|
||||
return Optional.of(stringDoubleMap -> function.apply(stringDoubleMap, argumentEquations));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private interface TriFunction<T, U, V, R> {
|
||||
R apply(T t, U u, V v);
|
||||
}
|
||||
}
|
||||
|
||||
class EquationParseException extends Exception {
|
||||
public EquationParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,9 +50,11 @@ public final class ModDimensions {
|
|||
return isPocketDimension(world.getRegistryKey());
|
||||
}
|
||||
|
||||
public static boolean isPocketDimension(RegistryKey<World> type) {
|
||||
System.out.println("Type: " + type);
|
||||
public static boolean isPersonalPocketDimension(World world) {
|
||||
return world != null && world == PERSONAL_POCKET_DIMENSION;
|
||||
}
|
||||
|
||||
public static boolean isPocketDimension(RegistryKey<World> type) {
|
||||
return Objects.equals(type, PERSONAL) || Objects.equals(type, PUBLIC) || Objects.equals(type, DUNGEON);
|
||||
}
|
||||
|
||||
|
|
50
src/main/java/org/dimdev/dimdoors/world/level/Counter.java
Normal file
50
src/main/java/org/dimdev/dimdoors/world/level/Counter.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
package org.dimdev.dimdoors.world.level;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import dev.onyxstudios.cca.api.v3.item.ItemComponent;
|
||||
|
||||
public class Counter extends ItemComponent {
|
||||
public Counter(ItemStack stack) {
|
||||
super(stack, DimensionalDoorsComponents.COUNTER_COMPONENT_KEY);
|
||||
if (!this.hasTag("counter"))
|
||||
this.putInt("counter", 0);
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return getInt("counter");
|
||||
}
|
||||
|
||||
public void set(int value) {
|
||||
this.putInt("counter", omitZero(value));
|
||||
}
|
||||
|
||||
public int increment() {
|
||||
int count = count() + 1;
|
||||
this.putInt("counter", count);
|
||||
return count;
|
||||
}
|
||||
|
||||
public static <T> Counter get(T provider) {
|
||||
return DimensionalDoorsComponents.COUNTER_COMPONENT_KEY.get(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putInt(String key, int value) {
|
||||
super.putInt(key, omitZero(value));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getInt(String key) {
|
||||
return withZero(super.getInt(key));
|
||||
}
|
||||
|
||||
private int omitZero(int value) {
|
||||
return value >= 0 ? value + 1 : value;
|
||||
}
|
||||
|
||||
private int withZero(int value) {
|
||||
return value > 0 ? value - 1 : value;
|
||||
}
|
||||
}
|
|
@ -4,14 +4,24 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import dev.onyxstudios.cca.api.v3.component.ComponentKey;
|
||||
import dev.onyxstudios.cca.api.v3.component.ComponentRegistryV3;
|
||||
import dev.onyxstudios.cca.api.v3.item.ItemComponentFactoryRegistry;
|
||||
import dev.onyxstudios.cca.api.v3.item.ItemComponentInitializer;
|
||||
import dev.onyxstudios.cca.api.v3.level.LevelComponentFactoryRegistry;
|
||||
import dev.onyxstudios.cca.api.v3.level.LevelComponentInitializer;
|
||||
import org.dimdev.dimdoors.item.ModItems;
|
||||
|
||||
public class DimensionalDoorsComponents implements LevelComponentInitializer {
|
||||
public class DimensionalDoorsComponents implements LevelComponentInitializer, ItemComponentInitializer {
|
||||
public static final ComponentKey<DimensionalRegistry> DIMENSIONAL_REGISTRY_COMPONENT_KEY = ComponentRegistryV3.INSTANCE.getOrCreate(new Identifier("dimdoors:dimensional_registry"), DimensionalRegistry.class);
|
||||
public static final ComponentKey<Counter> COUNTER_COMPONENT_KEY = ComponentRegistryV3.INSTANCE.getOrCreate(new Identifier("dimdoors:counter"), Counter.class);
|
||||
|
||||
|
||||
@Override
|
||||
public void registerLevelComponentFactories(LevelComponentFactoryRegistry registry) {
|
||||
registry.register(DIMENSIONAL_REGISTRY_COMPONENT_KEY, level -> new DimensionalRegistry());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerItemComponentFactories(ItemComponentFactoryRegistry registry) {
|
||||
registry.registerFor(ModItems.RIFT_CONFIGURATION_TOOL, COUNTER_COMPONENT_KEY, Counter::new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,18 +15,20 @@ import dev.onyxstudios.cca.api.v3.component.ComponentV3;
|
|||
import org.dimdev.dimdoors.rift.registry.RiftRegistry;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.pocket.PocketDirectory;
|
||||
import org.dimdev.dimdoors.world.pocket.PrivateRegistry;
|
||||
import static org.dimdev.dimdoors.DimensionalDoorsInitializer.getServer;
|
||||
|
||||
public class DimensionalRegistry implements ComponentV3 {
|
||||
public Map<RegistryKey<World>, PocketDirectory> pocketRegistry = new HashMap<>();
|
||||
RiftRegistry riftRegistry = new RiftRegistry();
|
||||
PrivateRegistry privateRegistry = new PrivateRegistry();
|
||||
|
||||
@Override
|
||||
public void readFromNbt(CompoundTag tag) {
|
||||
CompoundTag pocketRegistryTag = tag.getCompound("pocketRegistry");
|
||||
pocketRegistry = pocketRegistryTag.getKeys().stream().collect(Collectors.toMap(a -> RegistryKey.of(Registry.DIMENSION, new Identifier(a)), a -> PocketDirectory.readFromNbt(a, pocketRegistryTag.getCompound(a))));
|
||||
|
||||
riftRegistry = RiftRegistry.fromTag(pocketRegistry, tag.getCompound("riftRegistry"));
|
||||
privateRegistry.fromTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -36,6 +38,7 @@ public class DimensionalRegistry implements ComponentV3 {
|
|||
|
||||
tag.put("pocketRegistry", pocketRegistryTag);
|
||||
tag.put("riftRegistry", riftRegistry.toTag());
|
||||
privateRegistry.toTag(tag);
|
||||
}
|
||||
|
||||
public static DimensionalRegistry instance() {
|
||||
|
@ -46,6 +49,10 @@ public class DimensionalRegistry implements ComponentV3 {
|
|||
return instance().riftRegistry;
|
||||
}
|
||||
|
||||
public static PrivateRegistry getPrivateRegistry() {
|
||||
return instance().privateRegistry;
|
||||
}
|
||||
|
||||
public static PocketDirectory getPocketDirectory(RegistryKey<World> key) {
|
||||
if (!(ModDimensions.isPocketDimension(key))) {
|
||||
throw new UnsupportedOperationException("PocketRegistry is only available for pocket dimensions!");
|
||||
|
|
|
@ -1,26 +1,39 @@
|
|||
package org.dimdev.dimdoors.world.pocket;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.block.AncientFabricBlock;
|
||||
import org.dimdev.dimdoors.block.FabricBlock;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.util.EntityUtils;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.DyeColor;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockBox;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public final class Pocket {
|
||||
private static final int BLOCKS_PAINTED_PER_DYE = 1106;
|
||||
private static final int BLOCKS_PAINTED_PER_DYE = 1000000;
|
||||
|
||||
// TODO: please someone make all these private and add a getter & setter where needed
|
||||
public final int id;
|
||||
public BlockBox box;
|
||||
public VirtualLocation virtualLocation;
|
||||
|
@ -30,20 +43,21 @@ public final class Pocket {
|
|||
|
||||
public RegistryKey<World> world;
|
||||
|
||||
private Pocket(int id, BlockBox box, VirtualLocation virtualLocation, PocketColor dyeColor, PocketColor nextDyeColor, int count) {
|
||||
private Pocket(int id, BlockBox box, VirtualLocation virtualLocation, PocketColor dyeColor, PocketColor nextDyeColor, int count, RegistryKey<World> world) {
|
||||
this.id = id;
|
||||
this.box = box;
|
||||
this.virtualLocation = virtualLocation;
|
||||
this.dyeColor = dyeColor;
|
||||
this.nextDyeColor = nextDyeColor;
|
||||
this.count = count;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public Pocket(int id, RegistryKey<World> world, int x, int z) {
|
||||
int gridSize = DimensionalRegistry.getPocketDirectory(world).getGridSize() * 16;
|
||||
this.id = id;
|
||||
this.world = world;
|
||||
this.box = new BlockBox(x * gridSize, 0, z * gridSize, (x + 1) * gridSize, 0, (z + 1) * gridSize);
|
||||
this.box = BlockBox.create(x * gridSize, 0, z * gridSize, (x + 1) * gridSize, 0, (z + 1) * gridSize);
|
||||
this.virtualLocation = new VirtualLocation(world, x, z, 0);
|
||||
}
|
||||
|
||||
|
@ -55,6 +69,14 @@ public final class Pocket {
|
|||
return new BlockPos(this.box.minX, this.box.minY, this.box.minZ);
|
||||
}
|
||||
|
||||
public void offsetOrigin(Vec3i vec) {
|
||||
offsetOrigin(vec.getX(), vec.getY(), vec.getZ());
|
||||
}
|
||||
|
||||
public void offsetOrigin(int x, int y, int z) {
|
||||
this.box = box.offset(x, y, z);
|
||||
}
|
||||
|
||||
public boolean addDye(Entity entity, DyeColor dyeColor) {
|
||||
PocketColor color = PocketColor.from(dyeColor);
|
||||
|
||||
|
@ -65,8 +87,9 @@ public final class Pocket {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (this.nextDyeColor != null && this.nextDyeColor == color) {
|
||||
if (this.count + 1 > amountOfDyeRequiredToColor(this)) {
|
||||
if (this.nextDyeColor != PocketColor.NONE && this.nextDyeColor == color) {
|
||||
if (this.count + 1 > maxDye) {
|
||||
repaint(dyeColor);
|
||||
this.dyeColor = color;
|
||||
this.nextDyeColor = PocketColor.NONE;
|
||||
this.count = 0;
|
||||
|
@ -83,41 +106,33 @@ public final class Pocket {
|
|||
return true;
|
||||
}
|
||||
|
||||
// private void repaint(DyeColor dyeColor) {
|
||||
// BlockPos origin = getOrigin();
|
||||
// World world = WorldUtils.getWorld(dim);
|
||||
// BlockState innerWall = ModBlocks.getDefaultState()..withProperty(..., dyeColor); // <-- forgot the exact name of the color property
|
||||
// BlockState outerWall = ModBlocks.ETERNAL_FABRIC.getDefaultState().withProperty(..., dyeColor);
|
||||
//
|
||||
// for (int x = origin.getX(); x < origin.getX() + size; x++) {
|
||||
// for (int y = origin.getY(); y < origin.getY() + size; y++) {
|
||||
// for (int z = origin.getZ(); z < origin.getZ() + size; z++) {
|
||||
// int layer = Collections.min(Arrays.asList(x, y, z, size - 1 - x, size - 1 - y, size - 1 - z));
|
||||
// if (layer == 0) {
|
||||
// if (world.getBlockState(x, y, z).getBlock() == ModBlocks.ETERNAL_FABRIC) {
|
||||
// world.setBlockState(x, y, z, outerWall);
|
||||
// }
|
||||
// } else if (layer < 5) {
|
||||
// if (world.getBlockState(x, y, z).getBlock() == ModBlocks.FABRIC) {
|
||||
// world.setBlockState(x, y, z, innerWall);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return schematic;
|
||||
// }
|
||||
private void repaint(DyeColor dyeColor) {
|
||||
ServerWorld serverWorld = DimensionalDoorsInitializer.getWorld(world);
|
||||
BlockState innerWall = ModBlocks.fabricFromDye(dyeColor).getDefaultState();
|
||||
BlockState outerWall = ModBlocks.ancientFabricFromDye(dyeColor).getDefaultState();
|
||||
|
||||
BlockPos.stream(box).forEach(pos -> {
|
||||
if (serverWorld.getBlockState(pos).getBlock() instanceof AncientFabricBlock) {
|
||||
serverWorld.setBlockState(pos, outerWall);
|
||||
} else if (serverWorld.getBlockState(pos).getBlock() instanceof FabricBlock) {
|
||||
serverWorld.setBlockState(pos, innerWall);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static int amountOfDyeRequiredToColor(Pocket pocket) {
|
||||
int outerVolume = pocket.box.getBlockCountX() * pocket.box.getBlockCountY() * pocket.box.getBlockCountZ();
|
||||
int innerVolume = (pocket.box.getBlockCountX() - 5) * (pocket.box.getBlockCountY() - 5) * (pocket.box.getBlockCountZ() - 5);
|
||||
|
||||
return (outerVolume - innerVolume) / BLOCKS_PAINTED_PER_DYE;
|
||||
return Math.max((outerVolume - innerVolume) / BLOCKS_PAINTED_PER_DYE, 1);
|
||||
}
|
||||
|
||||
public void setSize(Vec3i size) {
|
||||
setSize(size.getX(), size.getY(), size.getZ());
|
||||
}
|
||||
|
||||
public void setSize(int x, int y, int z) {
|
||||
this.box = new BlockBox(this.box.minX, this.box.minY, this.box.minZ, this.box.minX + x, this.box.minY + y, this.box.minZ + z);
|
||||
this.box = BlockBox.create(this.box.minX, this.box.minY, this.box.minZ, this.box.minX + x - 1, this.box.minY + y - 1, this.box.minZ + z - 1);
|
||||
}
|
||||
|
||||
public Vector3i getSize() {
|
||||
|
@ -133,6 +148,7 @@ public final class Pocket {
|
|||
tag.putInt("dyeColor", this.dyeColor.getId());
|
||||
tag.putInt("nextDyeColor", this.nextDyeColor.getId());
|
||||
tag.putInt("count", this.count);
|
||||
tag.putString("world", world.getValue().toString());
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@ -144,7 +160,8 @@ public final class Pocket {
|
|||
VirtualLocation.fromTag(tag.getCompound("virtualLocation")),
|
||||
PocketColor.from(tag.getInt("dyeColor")),
|
||||
PocketColor.from(tag.getInt("nextDyeColor")),
|
||||
tag.getInt("count")
|
||||
tag.getInt("count"),
|
||||
RegistryKey.of(Registry.DIMENSION, new Identifier(tag.getString("world")))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -205,4 +222,34 @@ public final class Pocket {
|
|||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<BlockPos, BlockEntity> getBlockEntities() {
|
||||
ServerWorld serverWorld = DimensionalDoorsInitializer.getWorld(this.world);
|
||||
Map<BlockPos, BlockEntity> blockEntities = new HashMap<>();
|
||||
ChunkPos.stream(new ChunkPos(new BlockPos(box.minX, box.minY, box.minZ)), new ChunkPos(new BlockPos(box.maxX, box.maxY, box.maxZ))).forEach(chunkPos -> serverWorld.getChunk(chunkPos.x, chunkPos.z).getBlockEntities().forEach((blockPos, blockEntity) -> {
|
||||
if (this.box.contains(blockPos)) blockEntities.put(blockPos, blockEntity);
|
||||
}));
|
||||
return blockEntities;
|
||||
}
|
||||
|
||||
public BlockBox getBox() {
|
||||
return box;
|
||||
}
|
||||
|
||||
public Map<String, Double> toVariableMap(Map<String, Double> stringDoubleMap) {
|
||||
stringDoubleMap.put("originX", (double) this.box.minX);
|
||||
stringDoubleMap.put("originY", (double) this.box.minY);
|
||||
stringDoubleMap.put("originZ", (double) this.box.minZ);
|
||||
stringDoubleMap.put("width", (double) this.box.getDimensions().getX());
|
||||
stringDoubleMap.put("height", (double) this.box.getDimensions().getY());
|
||||
stringDoubleMap.put("length", (double) this.box.getDimensions().getZ());
|
||||
stringDoubleMap.put("depth", (double) this.virtualLocation.getDepth());
|
||||
stringDoubleMap.put("id", (double) this.id); // don't really know why you would need this but it's there if needed
|
||||
return stringDoubleMap;
|
||||
}
|
||||
|
||||
public void expand(int amount) {
|
||||
if (amount == 0) return;
|
||||
this.box = BlockBox.create(box.minX - amount, box.minY - amount, box.minZ - amount, box.maxX + amount, box.maxY + amount, box.maxZ + amount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.util.UUID;
|
|||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
|
||||
import dev.onyxstudios.cca.api.v3.component.ComponentV3;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
|
||||
|
@ -17,7 +19,7 @@ import net.minecraft.world.World;
|
|||
|
||||
import static net.minecraft.world.World.OVERWORLD;
|
||||
|
||||
public class PrivatePocketData extends PersistentState {
|
||||
public class PrivateRegistry {
|
||||
protected static class PocketInfo {
|
||||
public final RegistryKey<World> world;
|
||||
public final int id;
|
||||
|
@ -46,19 +48,9 @@ public class PrivatePocketData extends PersistentState {
|
|||
|
||||
protected BiMap<UUID, PocketInfo> privatePocketMap = HashBiMap.create(); // Player UUID -> Pocket Info TODO: fix AnnotatedNBT and use UUID rather than String
|
||||
|
||||
public PrivatePocketData(String name) {
|
||||
super(name);
|
||||
public PrivateRegistry() {
|
||||
}
|
||||
|
||||
public PrivatePocketData() {
|
||||
super(DATA_NAME);
|
||||
}
|
||||
|
||||
public static PrivatePocketData instance() {
|
||||
return DimensionalDoorsInitializer.getWorld(OVERWORLD).getPersistentStateManager().getOrCreate(PrivatePocketData::new, DATA_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) {
|
||||
CompoundTag tag = nbt.getCompound("privatePocketMap");
|
||||
|
||||
|
@ -69,7 +61,6 @@ public class PrivatePocketData extends PersistentState {
|
|||
this.privatePocketMap = bm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag nbt) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
for (Map.Entry<UUID, PocketInfo> entry : this.privatePocketMap.entrySet()) {
|
||||
|
@ -88,7 +79,6 @@ public class PrivatePocketData extends PersistentState {
|
|||
|
||||
public void setPrivatePocketID(UUID playerUUID, Pocket pocket) {
|
||||
this.privatePocketMap.put(playerUUID, new PocketInfo(pocket.world, pocket.id));
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public UUID getPrivatePocketOwner(Pocket pocket) {
|
|
@ -76,8 +76,7 @@ public class VirtualLocation {
|
|||
if (virtualLocation == null) {
|
||||
return new VirtualLocation(OVERWORLD, location.getX(), location.getZ(), 5);
|
||||
}
|
||||
|
||||
return virtualLocation;
|
||||
return new VirtualLocation(location.getWorldId(), location.getX(), location.getZ(), virtualLocation.getDepth());
|
||||
}
|
||||
|
||||
public Location projectToWorld(boolean acceptLimbo) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"facing=south,half=lower,hinge=left,open=true": { "model": "dimdoors:block/gold_door_bottom_rh", "y": 180 },
|
||||
"facing=west,half=lower,hinge=left,open=true": { "model": "dimdoors:block/gold_door_bottom_rh", "y": 270 },
|
||||
"facing=north,half=lower,hinge=left,open=true": { "model": "dimdoors:block/gold_door_bottom_rh" },
|
||||
"facing=east,half=lower,hinge=right,open=true": { "model": "dimdoors:block/blocks/gold_door_bottom", "y": 270 },
|
||||
"facing=east,half=lower,hinge=right,open=true": { "model": "dimdoors:block/gold_door_bottom", "y": 270 },
|
||||
"facing=south,half=lower,hinge=right,open=true": { "model": "dimdoors:block/gold_door_bottom" },
|
||||
"facing=west,half=lower,hinge=right,open=true": { "model": "dimdoors:block/gold_door_bottom", "y": 90 },
|
||||
"facing=north,half=lower,hinge=right,open=true": { "model": "dimdoors:block/gold_door_bottom", "y": 180 },
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
"item.dimdoors.stabilized_rift_signature.stored": "Location stored",
|
||||
"item.dimdoors.stabilized_rift_signature.created": "Rift created",
|
||||
"item.dimdoors.rift_configuration_tool": "Rift Configuration Tool",
|
||||
"item.dimdoors.rift_configuration_tool.info": "TODO",
|
||||
"item.dimdoors.rift_remover": "Rift Remover",
|
||||
"item.dimdoors.rift_remover.closing": "The rift will close soon",
|
||||
"item.dimdoors.rift_remover.already_closing": "This rift is already closing",
|
||||
|
@ -191,4 +192,4 @@
|
|||
"argument.dimdoors.schematic.invalidNamespace": "Invalid schematic namespace. Expected one of %s, found %s.",
|
||||
"command.dimdoors.schematicv2.unknownSchematic": "Unknown schematic \"%s\" in namespace \"%s\" ",
|
||||
"dimdoors.config.screen.reload": "Reload Config"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"type": "dimdoors:schematic",
|
||||
"id": "v2/custom/purpur_hallway",
|
||||
"modifiers": [
|
||||
{
|
||||
"layers": [
|
||||
{
|
||||
"block_state": "dimdoors:pink_ancient_fabric",
|
||||
"thickness": "1"
|
||||
}
|
||||
],
|
||||
"type": "dimdoors:shell"
|
||||
},
|
||||
{
|
||||
"type": "dimdoors:rift_data",
|
||||
"ids": [0],
|
||||
"rift_data": "rift_data/pocket_entrance"
|
||||
},
|
||||
{
|
||||
"type": "dimdoors:rift_data",
|
||||
"ids": [4],
|
||||
"rift_data": "rift_data/public_entrance"
|
||||
},
|
||||
{
|
||||
"type": "dimdoors:relative",
|
||||
"point_a": 1,
|
||||
"point_b": 7
|
||||
},
|
||||
{
|
||||
"type": "dimdoors:relative",
|
||||
"point_a": 2,
|
||||
"point_b": 6
|
||||
},
|
||||
{
|
||||
"type": "dimdoors:relative",
|
||||
"point_a": 3,
|
||||
"point_b": 5
|
||||
}
|
||||
],
|
||||
"offset_x": "1",
|
||||
"offset_y": "1",
|
||||
"offset_z": "1"
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"width": "5 + 16 * private_size",
|
||||
"length": "5 + 16 * private_size",
|
||||
"type": "dimdoors:void",
|
||||
"modifiers": [
|
||||
{
|
||||
"layers": [
|
||||
{
|
||||
"block_state": "dimdoors:white_fabric",
|
||||
"thickness": "4"
|
||||
},
|
||||
{
|
||||
"block_state": "dimdoors:white_ancient_fabric",
|
||||
"thickness": "1"
|
||||
}
|
||||
],
|
||||
"type": "dimdoors:shell"
|
||||
},
|
||||
{
|
||||
"door_type": "dimdoors:quartz_dimensional_door",
|
||||
"x": "width/2",
|
||||
"facing": "north",
|
||||
"y": "5",
|
||||
"z": "4",
|
||||
"type": "dimdoors:door",
|
||||
"rift_data": {
|
||||
"destination": {
|
||||
"ifDestination": {
|
||||
"type": "dimdoors:private_pocket_exit"
|
||||
},
|
||||
"weight": 1.0,
|
||||
"type": "dimdoors:pocket_entrance"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "dimdoors:pocket_entrance",
|
||||
"id": 0
|
||||
}
|
||||
],
|
||||
"offset_x": "5",
|
||||
"offset_y": "5",
|
||||
"offset_z": "5",
|
||||
"height": "5 + 16 * min(15, private_size)"
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"width": "5 + 16 * public_size",
|
||||
"length": "5 + 16 * public_size",
|
||||
"type": "dimdoors:void",
|
||||
"modifiers": [
|
||||
{
|
||||
"layers": [
|
||||
{
|
||||
"block_state": "dimdoors:black_fabric",
|
||||
"thickness": "4"
|
||||
},
|
||||
{
|
||||
"block_state": "dimdoors:black_ancient_fabric",
|
||||
"thickness": "1"
|
||||
}
|
||||
],
|
||||
"type": "dimdoors:shell"
|
||||
},
|
||||
{
|
||||
"door_type": "dimdoors:iron_dimensional_door",
|
||||
"x": "width/2",
|
||||
"facing": "north",
|
||||
"y": "5",
|
||||
"z": "4",
|
||||
"type": "dimdoors:door",
|
||||
"rift_data": {
|
||||
"destination": {
|
||||
"type": "dimdoors:id_marker",
|
||||
"id": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "dimdoors:pocket_entrance",
|
||||
"id": 0
|
||||
}
|
||||
],
|
||||
"offset_x": "5",
|
||||
"offset_y": "5",
|
||||
"offset_z": "5",
|
||||
"height": "5 + 16 * min(15, public_size)"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"id": "custom/purpur_hallway",
|
||||
"type": "dimdoors:id"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"id": "private/default",
|
||||
"type": "dimdoors:id"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"id": "public/default",
|
||||
"type": "dimdoors:id"
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"destination": {
|
||||
"ifDestination": {
|
||||
"type": "dimdoors:pocket_exit"
|
||||
},
|
||||
"weight": 1.0,
|
||||
"type": "dimdoors:pocket_entrance"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"destination": {
|
||||
"type": "dimdoors:public_pocket"
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"group": "private",
|
||||
"pockets": [
|
||||
{
|
||||
"id": "private_pocket_0",
|
||||
"size": 0,
|
||||
"weight": 20
|
||||
},
|
||||
{
|
||||
"id": "private_pocket_1",
|
||||
"size": 1,
|
||||
"weight": 17
|
||||
},
|
||||
{
|
||||
"id": "private_pocket_2",
|
||||
"size": 2,
|
||||
"weight": 14
|
||||
},
|
||||
{
|
||||
"id": "private_pocket_3",
|
||||
"size": 3,
|
||||
"weight": 11
|
||||
},
|
||||
{
|
||||
"id": "private_pocket_4",
|
||||
"size": 4,
|
||||
"weight": 8
|
||||
},
|
||||
{
|
||||
"id": "private_pocket_5",
|
||||
"size": 5,
|
||||
"weight": 5
|
||||
},
|
||||
{
|
||||
"id": "private_pocket_6",
|
||||
"size": 6,
|
||||
"weight": 3
|
||||
},
|
||||
{
|
||||
"id": "private_pocket_7",
|
||||
"size": 7,
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"group": "public",
|
||||
"pockets": [
|
||||
{
|
||||
"id": "public_pocket_0",
|
||||
"size": 0,
|
||||
"weight": 20
|
||||
},
|
||||
{
|
||||
"id": "public_pocket_1",
|
||||
"size": 1,
|
||||
"weight": 17
|
||||
},
|
||||
{
|
||||
"id": "public_pocket_2",
|
||||
"size": 2,
|
||||
"weight": 14
|
||||
},
|
||||
{
|
||||
"id": "public_pocket_3",
|
||||
"size": 3,
|
||||
"weight": 11
|
||||
},
|
||||
{
|
||||
"id": "public_pocket_4",
|
||||
"size": 4,
|
||||
"weight": 8
|
||||
},
|
||||
{
|
||||
"id": "public_pocket_5",
|
||||
"size": 5,
|
||||
"weight": 5
|
||||
},
|
||||
{
|
||||
"id": "public_pocket_6",
|
||||
"size": 6,
|
||||
"weight": 3
|
||||
},
|
||||
{
|
||||
"id": "public_pocket_7",
|
||||
"size": 7,
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -44,7 +44,8 @@
|
|||
},
|
||||
"custom": {
|
||||
"cardinal-components": [
|
||||
"dimdoors:dimensional_registry"
|
||||
"dimdoors:dimensional_registry",
|
||||
"dimdoors:counter"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
@ -140,18 +143,26 @@ public class Schematic implements BlockView {
|
|||
}
|
||||
|
||||
Block block = Registry.BLOCK.get(new Identifier(id));
|
||||
Fluid fluid = Registry.FLUID.get(new Identifier(id));
|
||||
|
||||
if (block == Blocks.AIR && !"minecraft:air".equals(id)) {
|
||||
BlockState blockstate;
|
||||
if (block == Blocks.AIR && fluid == Fluids.EMPTY && !"minecraft:air".equals(id)) {
|
||||
System.err.println("Missing ID: " + blockStateString);
|
||||
}
|
||||
|
||||
BlockState blockstate = block.getDefaultState();
|
||||
|
||||
if (!state.isEmpty()) {
|
||||
String[] properties = state.split(",");
|
||||
blockstate = getBlockStateWithProperties(block, properties);
|
||||
if (fluid != Fluids.EMPTY) {
|
||||
blockstate = fluid.getDefaultState().getBlockState();
|
||||
if (!state.isEmpty()) {
|
||||
String[] properties = state.split(",");
|
||||
blockstate = getBlockStateWithProperties(blockstate.getBlock(), properties);
|
||||
}
|
||||
}
|
||||
else {
|
||||
blockstate = block.getDefaultState();
|
||||
if (!state.isEmpty()) {
|
||||
String[] properties = state.split(",");
|
||||
blockstate = getBlockStateWithProperties(block, properties);
|
||||
}
|
||||
}
|
||||
|
||||
schematic.palette.add(blockstate); //@todo, can we assume that a schematic file always has all palette integers used from 0 to pallettemax-1?
|
||||
}
|
||||
|
||||
|
@ -184,7 +195,7 @@ public class Schematic implements BlockView {
|
|||
}
|
||||
|
||||
|
||||
SchematicRedstoneFixer.fixRedstone(schematic);
|
||||
SchematicBlockConnectionFixer.fixBlocks(schematic);
|
||||
return schematic;
|
||||
}
|
||||
|
||||
|
@ -261,7 +272,7 @@ public class Schematic implements BlockView {
|
|||
|
||||
for (Entry<String, String> entry : propertyAndBlockStringsMap.entrySet()) {
|
||||
Property<?> property = stateManager.getProperty(entry.getKey());
|
||||
|
||||
if (property == null) LOGGER.info("Missing property " + entry.getKey() + " in: " + chosenState + "[" + propertyAndBlockStringsMap.entrySet().stream().map(mapEntry -> mapEntry.getKey() + "=" + mapEntry.getValue()).collect(Collectors.joining(",")) + "]");
|
||||
if (property != null) {
|
||||
Comparable<?> value = null;
|
||||
for (Comparable<?> object : property.getValues()) {
|
||||
|
@ -409,7 +420,6 @@ public class Schematic implements BlockView {
|
|||
if (x < 0 || x >= this.sizeX || y < 0 || y >= this.sizeY || z < 0 || z >= this.sizeZ) {
|
||||
return Blocks.AIR.getDefaultState();
|
||||
}
|
||||
|
||||
return this.palette.get(this.blockData[x][y][z]);
|
||||
}
|
||||
|
||||
|
@ -455,9 +465,6 @@ public class Schematic implements BlockView {
|
|||
if (setAir || !state.getBlock().equals(Blocks.AIR)) {
|
||||
section.setBlockState(lx, ly, lz, state);
|
||||
|
||||
// BlockPos pos = new BlockPos(originX + x, originY + y, originZ + z);
|
||||
// serverWorld.getChunkManager().markForUpdate(pos);
|
||||
// serverWorld.getLightingProvider().checkBlock(pos);
|
||||
if (y > 255) {
|
||||
System.out.println();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
package org.dimdev.dimdoors.util.schematic;
|
||||
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.enums.DoubleBlockHalf;
|
||||
import net.minecraft.block.enums.StairShape;
|
||||
import org.dimdev.dimdoors.mixin.accessor.RedstoneWireBlockAccessor;
|
||||
|
||||
import net.minecraft.block.enums.WireConnection;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
// TODO: probably need to fix tall_grass -> upper, lower
|
||||
public class SchematicBlockConnectionFixer {
|
||||
public static void fixBlocks(Schematic schematic) {
|
||||
for (int x = 0; x < schematic.sizeX; x++) {
|
||||
for (int y = 0; y < schematic.sizeY; y++) {
|
||||
for (int z = 0; z < schematic.sizeZ; z++) {
|
||||
BlockState state = schematic.getBlockState(x, y, z);
|
||||
if (state != null) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.REDSTONE_WIRE) {
|
||||
int power = state.get(RedstoneWireBlock.POWER);
|
||||
schematic.setBlockState(x, y, z, getRedstonePlacementState(schematic, new BlockPos(x, y, z)).with(RedstoneWireBlock.POWER, power));
|
||||
} else if (block instanceof FenceBlock) {
|
||||
schematic.setBlockState(x, y, z, getFencePlacementState(schematic, new BlockPos(x, y, z), (FenceBlock) block, state));
|
||||
} else if (block instanceof PaneBlock) {
|
||||
schematic.setBlockState(x, y, z, getPanePlacementState(schematic, new BlockPos(x, y, z), (PaneBlock) block, state));
|
||||
} else if (block instanceof DoorBlock && state.get(DoorBlock.HALF).equals(DoubleBlockHalf.UPPER)) {
|
||||
schematic.setBlockState(x, y, z, getUpperDoorHalfPlacementState(schematic, new BlockPos(x, y, z), (DoorBlock) block, state));
|
||||
} else if (block instanceof StairsBlock) {
|
||||
schematic.setBlockState(x, y, z, state.with(StairsBlock.SHAPE, getStairShape(state, schematic, new BlockPos(x, y, z))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static StairShape getStairShape(BlockState state, BlockView world, BlockPos pos) {
|
||||
Direction direction = (Direction)state.get(StairsBlock.FACING);
|
||||
BlockState blockState = world.getBlockState(pos.offset(direction));
|
||||
if (StairsBlock.isStairs(blockState) && state.get(StairsBlock.HALF) == blockState.get(StairsBlock.HALF)) {
|
||||
Direction direction2 = (Direction)blockState.get(StairsBlock.FACING);
|
||||
if (direction2.getAxis() != ((Direction)state.get(StairsBlock.FACING)).getAxis() && method_10678(state, world, pos, direction2.getOpposite())) {
|
||||
if (direction2 == direction.rotateYCounterclockwise()) {
|
||||
return StairShape.OUTER_LEFT;
|
||||
}
|
||||
|
||||
return StairShape.OUTER_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
BlockState blockState2 = world.getBlockState(pos.offset(direction.getOpposite()));
|
||||
if (StairsBlock.isStairs(blockState2) && state.get(StairsBlock.HALF) == blockState2.get(StairsBlock.HALF)) {
|
||||
Direction direction3 = (Direction)blockState2.get(StairsBlock.FACING);
|
||||
if (direction3.getAxis() != ((Direction)state.get(StairsBlock.FACING)).getAxis() && method_10678(state, world, pos, direction3)) {
|
||||
if (direction3 == direction.rotateYCounterclockwise()) {
|
||||
return StairShape.INNER_LEFT;
|
||||
}
|
||||
|
||||
return StairShape.INNER_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
return StairShape.STRAIGHT;
|
||||
}
|
||||
|
||||
private static boolean method_10678(BlockState state, BlockView world, BlockPos pos, Direction dir) {
|
||||
BlockState blockState = world.getBlockState(pos.offset(dir));
|
||||
return !StairsBlock.isStairs(blockState) || blockState.get(StairsBlock.FACING) != state.get(StairsBlock.FACING) || blockState.get(StairsBlock.HALF) != state.get(StairsBlock.HALF);
|
||||
}
|
||||
|
||||
public static BlockState getUpperDoorHalfPlacementState(BlockView world, BlockPos pos, DoorBlock block, BlockState state) {
|
||||
BlockState lower = world.getBlockState(pos.down());
|
||||
return state.with(DoorBlock.FACING, lower.get(DoorBlock.FACING)).with(DoorBlock.HINGE, lower.get(DoorBlock.HINGE)).with(DoorBlock.OPEN, lower.get(DoorBlock.OPEN)).with(DoorBlock.POWERED, lower.get(DoorBlock.POWERED));
|
||||
}
|
||||
|
||||
public static BlockState getPanePlacementState(BlockView world, BlockPos pos, PaneBlock block, BlockState state) {
|
||||
BlockPos blockPos2 = pos.north();
|
||||
BlockPos blockPos3 = pos.east();
|
||||
BlockPos blockPos4 = pos.south();
|
||||
BlockPos blockPos5 = pos.west();
|
||||
BlockState blockState = world.getBlockState(blockPos2);
|
||||
BlockState blockState2 = world.getBlockState(blockPos3);
|
||||
BlockState blockState3 = world.getBlockState(blockPos4);
|
||||
BlockState blockState4 = world.getBlockState(blockPos5);
|
||||
return state
|
||||
.with(HorizontalConnectingBlock.NORTH, block.connectsTo(blockState, blockState.isSideSolidFullSquare(world, blockPos2, Direction.SOUTH)))
|
||||
.with(HorizontalConnectingBlock.EAST, block.connectsTo(blockState2, blockState2.isSideSolidFullSquare(world, blockPos3, Direction.WEST)))
|
||||
.with(HorizontalConnectingBlock.SOUTH, block.connectsTo(blockState3, blockState3.isSideSolidFullSquare(world, blockPos4, Direction.NORTH)))
|
||||
.with(HorizontalConnectingBlock.WEST, block.connectsTo(blockState4, blockState4.isSideSolidFullSquare(world, blockPos5, Direction.EAST)));
|
||||
}
|
||||
|
||||
public static BlockState getFencePlacementState(BlockView world, BlockPos pos, FenceBlock block, BlockState state) {
|
||||
BlockPos blockPos2 = pos.north();
|
||||
BlockPos blockPos3 = pos.east();
|
||||
BlockPos blockPos4 = pos.south();
|
||||
BlockPos blockPos5 = pos.west();
|
||||
BlockState blockState = world.getBlockState(blockPos2);
|
||||
BlockState blockState2 = world.getBlockState(blockPos3);
|
||||
BlockState blockState3 = world.getBlockState(blockPos4);
|
||||
BlockState blockState4 = world.getBlockState(blockPos5);
|
||||
return state
|
||||
.with(HorizontalConnectingBlock.NORTH, block.canConnect(blockState, blockState.isSideSolidFullSquare(world, blockPos2, Direction.SOUTH), Direction.SOUTH))
|
||||
.with(HorizontalConnectingBlock.EAST, block.canConnect(blockState2, blockState2.isSideSolidFullSquare(world, blockPos3, Direction.WEST), Direction.WEST))
|
||||
.with(HorizontalConnectingBlock.SOUTH, block.canConnect(blockState3, blockState3.isSideSolidFullSquare(world, blockPos4, Direction.NORTH), Direction.NORTH))
|
||||
.with(HorizontalConnectingBlock.WEST, block.canConnect(blockState4, blockState4.isSideSolidFullSquare(world, blockPos5, Direction.EAST), Direction.EAST));
|
||||
}
|
||||
|
||||
public static BlockState getRedstonePlacementState(BlockView world, BlockPos pos) {
|
||||
WireConnection west = getRenderConnectionType(world, pos, Direction.WEST);
|
||||
WireConnection east = getRenderConnectionType(world, pos, Direction.EAST);
|
||||
WireConnection north = getRenderConnectionType(world, pos, Direction.NORTH);
|
||||
WireConnection south = getRenderConnectionType(world, pos, Direction.SOUTH);
|
||||
int connectionCount = 0;
|
||||
if (west.isConnected()) connectionCount++;
|
||||
if (east.isConnected()) connectionCount++;
|
||||
if (north.isConnected()) connectionCount++;
|
||||
if (south.isConnected()) connectionCount++;
|
||||
|
||||
switch (connectionCount) {
|
||||
case 0: // should actually connect to all sides, forming a cross
|
||||
return Blocks.REDSTONE_WIRE.getDefaultState()
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_WEST, WireConnection.SIDE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_EAST, WireConnection.SIDE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_NORTH, WireConnection.SIDE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_SOUTH, WireConnection.SIDE);
|
||||
case 1: // should actually connect to the other side as well, forming a line
|
||||
if (west.isConnected()) return Blocks.REDSTONE_WIRE.getDefaultState()
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_WEST, west)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_EAST, WireConnection.SIDE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_NORTH, WireConnection.NONE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_SOUTH, WireConnection.NONE);
|
||||
if (east.isConnected()) return Blocks.REDSTONE_WIRE.getDefaultState()
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_WEST, WireConnection.SIDE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_EAST, east)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_NORTH, WireConnection.NONE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_SOUTH, WireConnection.NONE);
|
||||
if (north.isConnected()) return Blocks.REDSTONE_WIRE.getDefaultState()
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_WEST, WireConnection.NONE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_EAST, WireConnection.NONE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_NORTH, north)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_SOUTH, WireConnection.SIDE);
|
||||
return Blocks.REDSTONE_WIRE.getDefaultState()
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_WEST, WireConnection.NONE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_EAST, WireConnection.NONE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_NORTH, WireConnection.SIDE)
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_SOUTH, south);
|
||||
default:
|
||||
return Blocks.REDSTONE_WIRE.getDefaultState()
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_WEST, getRenderConnectionType(world, pos, Direction.WEST))
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_EAST, getRenderConnectionType(world, pos, Direction.EAST))
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_NORTH, getRenderConnectionType(world, pos, Direction.NORTH))
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_SOUTH, getRenderConnectionType(world, pos, Direction.SOUTH));
|
||||
}
|
||||
}
|
||||
|
||||
private static WireConnection getRenderConnectionType(BlockView world, BlockPos pos, Direction direction) {
|
||||
return ((RedstoneWireBlockAccessor) Blocks.REDSTONE_WIRE).invokeGetRenderConnectionType(world, pos, direction);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,9 @@ import java.util.Map;
|
|||
|
||||
public class SchematicConverter {
|
||||
public static Map<String, String> CONVERSIONS = new HashMap<>();
|
||||
private static final String[] COLORS = new String[]{"white", "orange", "magenta", "light_blue", "yellow", "lime", "pink", "gray", "light_gray", "cyan", "purple", "blue", "brown", "green", "red", "black"};
|
||||
private static final String[] facingStrings = new String[] {"north", "south", "east", "west"};
|
||||
private static final String[] BRICK_VARIANTS = new String[]{"stone_brick", "nether_brick"};
|
||||
|
||||
public static String updateId(String id) {
|
||||
|
||||
|
@ -77,6 +80,8 @@ public class SchematicConverter {
|
|||
CONVERSIONS.put("minecraft:leaves[check_decay=false]", "minecraft:oak_leaves[persistent=true]");
|
||||
|
||||
CONVERSIONS.put("minecraft:leaves[variant=jungle]", "minecraft:jungle_leaves[persistent=true]");
|
||||
CONVERSIONS.put("minecraft:leaves[check_decay=false,variant=spruce]", "minecraft:spruce_leaves[persistent=true]");
|
||||
|
||||
|
||||
|
||||
CONVERSIONS.put("minecraft:powered_repeater", "minecraft:repeater[facing=north,powered=true]");
|
||||
|
@ -200,6 +205,17 @@ public class SchematicConverter {
|
|||
CONVERSIONS.put("minecraft:unpowered_comparator[facing=east,delay=4]", "minecraft:comparator[delay=4,facing=east,powered=false]");
|
||||
CONVERSIONS.put("minecraft:unpowered_comparator[facing=west,delay=4]", "minecraft:comparator[delay=4,facing=west,powered=false]");
|
||||
|
||||
CONVERSIONS.put("minecraft:unpowered_comparator[powered=true]", "minecraft:comparator[facing=north,powered=false,mode=subtract]");
|
||||
CONVERSIONS.put("minecraft:unpowered_comparator[powered=true,facing=north]", "minecraft:comparator[facing=north,powered=false,mode=subtract]");
|
||||
CONVERSIONS.put("minecraft:unpowered_comparator[powered=true,facing=south]", "minecraft:comparator[facing=south,powered=false,mode=subtract]");
|
||||
CONVERSIONS.put("minecraft:unpowered_comparator[powered=true,facing=east]", "minecraft:comparator[facing=east,powered=false,mode=subtract]");
|
||||
CONVERSIONS.put("minecraft:unpowered_comparator[powered=true,facing=west]", "minecraft:comparator[facing=west,powered=false,mode=subtract]");
|
||||
|
||||
CONVERSIONS.put("minecraft:powered_comparator[powered=true]", "minecraft:comparator[facing=north,powered=true,mode=subtract]");
|
||||
CONVERSIONS.put("minecraft:powered_comparator[powered=true,facing=north]", "minecraft:comparator[facing=north,powered=true,mode=subtract]");
|
||||
CONVERSIONS.put("minecraft:powered_comparator[powered=true,facing=south]", "minecraft:comparator[facing=south,powered=true,mode=subtract]");
|
||||
CONVERSIONS.put("minecraft:powered_comparator[powered=true,facing=east]", "minecraft:comparator[facing=east,powered=true,mode=subtract]");
|
||||
CONVERSIONS.put("minecraft:powered_comparator[powered=true,facing=west]", "minecraft:comparator[facing=west,powered=true,mode=subtract]");
|
||||
|
||||
CONVERSIONS.put("minecraft:unpowered_comparator[delay=2,facing=north]", "minecraft:comparator[delay=2,facing=north,powered=false]");
|
||||
CONVERSIONS.put("minecraft:unpowered_comparator[delay=2,facing=south]", "minecraft:comparator[delay=2,facing=south,powered=false]");
|
||||
|
@ -231,6 +247,65 @@ public class SchematicConverter {
|
|||
|
||||
CONVERSIONS.put("minecraft:stonebrick", "minecraft:stone_bricks");
|
||||
CONVERSIONS.put("minecraft:log[axis=z,variant=jungle]", "minecraft:jungle_log[axis=z]");
|
||||
CONVERSIONS.put("minecraft:unlit_redstone_torch", "minecraft:redstone_torch[lit=false]");
|
||||
//CONVERSIONS.put("minecraft:unlit_redstone_torch", "minecraft:redstone_torch[lit=false]");
|
||||
|
||||
for (boolean lit : new boolean[]{false, true}) {
|
||||
CONVERSIONS.put("minecraft:" + (lit ? "" : "unlit_") + "redstone_torch", "minecraft:redstone_torch[lit=" + (lit ? "true" : "false") + "]");
|
||||
for (String facing : facingStrings) {
|
||||
CONVERSIONS.put("minecraft:" + (lit ? "" : "unlit_") + "redstone_torch[facing=" + facing + "]", "minecraft:redstone_wall_torch[facing=" + facing + ",lit=" + (lit ? "true" : "false") + "]");
|
||||
}
|
||||
}
|
||||
|
||||
for (String color : COLORS) {
|
||||
CONVERSIONS.put("minecraft:wool[color=" + color + "]", "minecraft:" + color + "_wool");
|
||||
CONVERSIONS.put("minecraft:stained_hardened_clay[color=" + color + "]", "minecraft:" + color + "_terracotta");
|
||||
}
|
||||
|
||||
for (String facing : facingStrings) {
|
||||
CONVERSIONS.put("minecraft:torch[facing=" + facing + "]", "minecraft:wall_torch[facing=" + facing + "]");
|
||||
}
|
||||
|
||||
CONVERSIONS.put("minecraft:stonebrick[variant=cracked_stonebrick]", "minecraft:cracked_stone_bricks");
|
||||
CONVERSIONS.put("minecraft:stonebrick[variant=chiseled_stonebrick]", "minecraft:chiseled_stone_bricks");
|
||||
CONVERSIONS.put("minecraft:monster_egg[variant=stone_brick]", "minecraft:infested_chiseled_stone_bricks");
|
||||
CONVERSIONS.put("minecraft:nether_brick", "minecraft:nether_bricks");
|
||||
CONVERSIONS.put("minecraft:noteblock", "minecraft:note_block");
|
||||
CONVERSIONS.put("minecraft:quartz_ore", "minecraft:nether_quartz_ore");
|
||||
CONVERSIONS.put("minecraft:grass", "minecraft:grass_block");
|
||||
|
||||
CONVERSIONS.put("minecraft:stone_slab", "minecraft:smooth_stone_slab");
|
||||
CONVERSIONS.put("minecraft:stone_slab[half=top]", "minecraft:smooth_stone_slab[type=top]");
|
||||
CONVERSIONS.put("minecraft:stone_slab[variant=cobblestone]", "minecraft:cobblestone_slab");
|
||||
CONVERSIONS.put("minecraft:stone_slab[half=top,variant=cobblestone]", "minecraft:cobblestone_slab[type=top]");
|
||||
for (String variant : BRICK_VARIANTS) {
|
||||
CONVERSIONS.put("minecraft:stone_slab[variant=" + variant + "]", "minecraft:" + variant + "_slab");
|
||||
CONVERSIONS.put("minecraft:stone_slab[half=top,variant=" + variant + "]", "minecraft:" + variant + "_slab[type=top]");
|
||||
}
|
||||
|
||||
CONVERSIONS.put("minecraft:stone_stairs", "minecraft:cobblestone_stairs");
|
||||
CONVERSIONS.put("minecraft:stone_stairs[half=top]", "minecraft:cobblestone_stairs[half=top]");
|
||||
for(String facing : facingStrings) {
|
||||
CONVERSIONS.put("minecraft:stone_stairs[facing=" + facing + "]", "minecraft:cobblestone_stairs[facing=" + facing + "]");
|
||||
CONVERSIONS.put("minecraft:stone_stairs[facing=" + facing + ",half=top]", "minecraft:cobblestone_stairs[facing=" + facing + ",half=top]");
|
||||
}
|
||||
|
||||
|
||||
CONVERSIONS.put("minecraft:tnt[explode=true]", "minecraft:tnt[unstable=true]");
|
||||
CONVERSIONS.put("minecraft:web", "minecraft:cobweb");
|
||||
|
||||
|
||||
for (int i = 1; i < 16; i++) {
|
||||
CONVERSIONS.put("minecraft:lava[level=" + i + "]", "minecraft:flowing_lava[level=" + i + "]");
|
||||
}
|
||||
|
||||
for (int i = 1; i < 16; i++) {
|
||||
CONVERSIONS.put("minecraft:water[level=" + i + "]", "minecraft:flowing_water[level=" + i + "]");
|
||||
}
|
||||
|
||||
CONVERSIONS.put("minecraft:tallgrass[type=tall_grass]", "minecraft:tall_grass");
|
||||
CONVERSIONS.put("minecraft:stonebrick[variant=mossy_stonebrick]", "minecraft:mossy_stone_bricks");
|
||||
CONVERSIONS.put("minecraft:waterlily", "minecraft:lily_pad");
|
||||
CONVERSIONS.put("minecraft:lit_redstone_lamp", "minecraft:redstone_lamp[lit=true]");
|
||||
CONVERSIONS.put("minecraft:snow_layer", "minecraft:snow");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
package org.dimdev.dimdoors.util.schematic;
|
||||
|
||||
import org.dimdev.dimdoors.mixin.accessor.RedstoneWireBlockAccessor;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.RedstoneWireBlock;
|
||||
import net.minecraft.block.enums.WireConnection;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
public class SchematicRedstoneFixer {
|
||||
public static void fixRedstone(Schematic schematic) {
|
||||
for (int x = 0; x < schematic.sizeX; x++) {
|
||||
for (int y = 0; y < schematic.sizeY; y++) {
|
||||
for (int z = 0; z < schematic.sizeZ; z++) {
|
||||
BlockState state = schematic.getBlockState(x, y, z);
|
||||
if (state != null && state.getBlock() == Blocks.REDSTONE_WIRE) {
|
||||
int power = state.get(RedstoneWireBlock.POWER);
|
||||
schematic.setBlockState(x, y, z, getPlacementState(schematic, new BlockPos(x, y, z)).with(RedstoneWireBlock.POWER, power));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static BlockState getPlacementState(BlockView world, BlockPos pos) {
|
||||
return Blocks.REDSTONE_WIRE.getDefaultState()
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_WEST, getRenderConnectionType(world, pos, Direction.WEST))
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_EAST, getRenderConnectionType(world, pos, Direction.EAST))
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_NORTH, getRenderConnectionType(world, pos, Direction.NORTH))
|
||||
.with(RedstoneWireBlock.WIRE_CONNECTION_SOUTH, getRenderConnectionType(world, pos, Direction.SOUTH));
|
||||
}
|
||||
|
||||
private static WireConnection getRenderConnectionType(BlockView world, BlockPos pos, Direction direction) {
|
||||
return ((RedstoneWireBlockAccessor) Blocks.REDSTONE_WIRE).invokeGetRenderConnectionType(world, pos, direction);
|
||||
}
|
||||
}
|
|
@ -59,9 +59,11 @@ public class RelativeBlockSample implements BlockView, ModifiableWorld {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
this.biomeContainer.put(new BlockPos(x, 0, z), this.biomePalette.inverse().get(this.biomeData[x][z]));
|
||||
if (hasBiomes()) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
this.biomeContainer.put(new BlockPos(x, 0, z), this.biomePalette.inverse().get(this.biomeData[x][z]));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (CompoundTag blockEntityTag : schematic.getBlockEntities()) {
|
||||
|
@ -103,7 +105,13 @@ public class RelativeBlockSample implements BlockView, ModifiableWorld {
|
|||
BlockPos pos = entry.getKey();
|
||||
BlockPos actualPos = origin.add(entry.getKey());
|
||||
|
||||
BlockEntity blockEntity = BlockEntity.createFromTag(this.getBlockState(pos), entry.getValue());
|
||||
CompoundTag tag = entry.getValue();
|
||||
if(tag.contains("Id")) {
|
||||
tag.put("id", tag.get("Id")); // boogers
|
||||
tag.remove("Id");
|
||||
}
|
||||
|
||||
BlockEntity blockEntity = BlockEntity.createFromTag(this.getBlockState(pos), tag);
|
||||
if (blockEntity != null) {
|
||||
world.toServerWorld().setBlockEntity(actualPos, blockEntity);
|
||||
}
|
||||
|
@ -152,4 +160,8 @@ public class RelativeBlockSample implements BlockView, ModifiableWorld {
|
|||
public boolean breakBlock(BlockPos pos, boolean drop, @Nullable Entity breakingEntity, int maxUpdateDepth) {
|
||||
return this.setBlockState(pos, Blocks.AIR.getDefaultState(), 2);
|
||||
}
|
||||
|
||||
public boolean hasBiomes() {
|
||||
return biomeData.length != 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ public final class SchematicPlacer {
|
|||
int width = schematic.getWidth();
|
||||
int length = schematic.getLength();
|
||||
byte[] biomeDataArray = schematic.getBiomeData().array();
|
||||
if (biomeDataArray.length == 0) return new int[0][0];
|
||||
int[][] biomeData = new int[width][length];
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
|
|
Loading…
Reference in a new issue