PocketAddon rework
pockets now generate in center of assigned grid
This commit is contained in:
parent
875bef25b6
commit
053dbb4f42
44 changed files with 1302 additions and 344 deletions
|
@ -1,15 +1,13 @@
|
|||
package org.dimdev.dimdoors;
|
||||
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
||||
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.ClientPacketHandler;
|
||||
import org.dimdev.dimdoors.network.ExtendedClientPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.particle.ModParticleTypes;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
|
@ -19,9 +17,6 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
|||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class DimensionalDoorsClientInitializer implements ClientModInitializer {
|
||||
private static ClientPacketHandler clientPacketHandler;
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ModEntityTypes.initClient();
|
||||
|
@ -37,11 +32,10 @@ public class DimensionalDoorsClientInitializer implements ClientModInitializer {
|
|||
}
|
||||
|
||||
private void registerListeners() {
|
||||
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> clientPacketHandler = new ClientPacketHandler(handler, client));
|
||||
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> ((ExtendedClientPlayNetworkHandler) handler).getDimDoorsPacketHandler().init());
|
||||
|
||||
ClientPlayConnectionEvents.DISCONNECT.register(((handler, client) -> {
|
||||
clientPacketHandler.unregister();
|
||||
clientPacketHandler = null;
|
||||
((ExtendedClientPlayNetworkHandler) handler).getDimDoorsPacketHandler().unregister();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
package org.dimdev.dimdoors;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
|
||||
import me.sargunvohra.mcmods.autoconfig1u.ConfigHolder;
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
|
||||
import me.sargunvohra.mcmods.autoconfig1u.serializer.JanksonConfigSerializer;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.block.entity.ModBlockEntityTypes;
|
||||
import org.dimdev.dimdoors.command.ModCommands;
|
||||
import org.dimdev.dimdoors.entity.ModEntityTypes;
|
||||
import org.dimdev.dimdoors.entity.stat.ModStats;
|
||||
import org.dimdev.dimdoors.event.UseItemOnBlockCallback;
|
||||
import org.dimdev.dimdoors.fluid.ModFluids;
|
||||
import org.dimdev.dimdoors.item.ModItems;
|
||||
import org.dimdev.dimdoors.listener.AttackBlockCallbackListener;
|
||||
import org.dimdev.dimdoors.network.ServerPacketHandler;
|
||||
import org.dimdev.dimdoors.listener.pocket.*;
|
||||
import org.dimdev.dimdoors.network.ExtendedServerPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.particle.ModParticleTypes;
|
||||
import org.dimdev.dimdoors.pockets.SchematicHandler;
|
||||
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
||||
|
@ -32,9 +32,8 @@ import org.dimdev.dimdoors.sound.ModSoundEvents;
|
|||
import org.dimdev.dimdoors.world.ModBiomes;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.feature.ModFeatures;
|
||||
import org.dimdev.dimdoors.world.pocket.PocketDirectory;
|
||||
import org.dimdev.dimdoors.world.pocket.type.AbstractPocket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.PocketAddon;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
@ -49,7 +48,6 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
|||
public class DimensionalDoorsInitializer implements ModInitializer {
|
||||
public static final Identifier MONOLITH_PARTICLE_PACKET = new Identifier("dimdoors", "monolith_particle_packet");
|
||||
public static final ConfigHolder<ModConfig> CONFIG_MANAGER = AutoConfig.register(ModConfig.class, JanksonConfigSerializer::new);
|
||||
private static final Map<UUID, ServerPacketHandler> UUID_SERVER_PACKET_HANDLER_MAP = new HashMap<>();
|
||||
private static MinecraftServer server;
|
||||
|
||||
@NotNull
|
||||
|
@ -93,60 +91,31 @@ public class DimensionalDoorsInitializer implements ModInitializer {
|
|||
Modifier.ModifierType.register();
|
||||
PocketGenerator.PocketGeneratorType.register();
|
||||
AbstractPocket.AbstractPocketType.register();
|
||||
PocketAddon.PocketAddonType.register();
|
||||
|
||||
SchematicV2Handler.getInstance().load();
|
||||
SchematicHandler.INSTANCE.loadSchematics();
|
||||
|
||||
registerListeners();
|
||||
|
||||
//newPocketTest();
|
||||
}
|
||||
|
||||
private void registerListeners() {
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
UUID_SERVER_PACKET_HANDLER_MAP.put(handler.player.getUuid(), new ServerPacketHandler(handler, server));
|
||||
((ExtendedServerPlayNetworkHandler) handler).getDimDoorsPacketHandler().init();
|
||||
});
|
||||
|
||||
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
|
||||
UUID_SERVER_PACKET_HANDLER_MAP.remove(handler.player.getUuid()).unregister();
|
||||
((ExtendedServerPlayNetworkHandler) handler).getDimDoorsPacketHandler().unregister();
|
||||
});
|
||||
|
||||
|
||||
AttackBlockCallback.EVENT.register(new AttackBlockCallbackListener());
|
||||
|
||||
|
||||
AttackBlockCallback.EVENT.register(new PocketAttackBlockCallbackListener());
|
||||
PlayerBlockBreakEvents.BEFORE.register(new PlayerBlockBreakEventBeforeListener());
|
||||
UseItemCallback.EVENT.register(new UseItemCallbackListener());
|
||||
UseItemOnBlockCallback.EVENT.register(new UseItemOnBlockCallbackListener());
|
||||
UseBlockCallback.EVENT.register(new UseBlockCallbackListener());
|
||||
}
|
||||
|
||||
/*
|
||||
void newPocketTest() {
|
||||
PocketDirectory directory = new PocketDirectory(ModDimensions.DUNGEON, 512);
|
||||
|
||||
Pocket.PocketBuilder<?, ?> builder = Pocket.builder().expand(new Vec3i(1, 1, 1));
|
||||
|
||||
|
||||
System.out.println(0 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(1 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(2 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(3 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(4 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(5 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(6 + ", " + directory.newPocket(builder).getId());
|
||||
|
||||
|
||||
|
||||
builder = Pocket.builder().expand(new Vec3i(directory.getGridSize() + 1, directory.getGridSize() + 1, directory.getGridSize() + 1));
|
||||
System.out.println(9 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(18 + ", " + directory.newPocket(builder).getId());
|
||||
|
||||
builder = Pocket.builder().expand(new Vec3i(3 * directory.getGridSize() + 1, 3 * directory.getGridSize() + 1, 3 * directory.getGridSize() + 1));
|
||||
System.out.println(81 + ", " + directory.newPocket(builder).getId());
|
||||
|
||||
|
||||
|
||||
builder = Pocket.builder().expand(new Vec3i(directory.getGridSize() + 1, directory.getGridSize() + 1, directory.getGridSize() + 1));
|
||||
System.out.println(27 + ", " + directory.newPocket(builder).getId());
|
||||
|
||||
builder = Pocket.builder().expand(new Vec3i(1, 1, 1));
|
||||
System.out.println(7 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(8 + ", " + directory.newPocket(builder).getId());
|
||||
System.out.println(36 + ", " + directory.newPocket(builder).getId());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -23,28 +23,12 @@ public class FabricBlock extends Block {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"deprecation"})
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
ItemStack heldStack = hand == Hand.MAIN_HAND ? player.getMainHandStack() : player.getOffHandStack();
|
||||
Block heldBlock = Block.getBlockFromItem(heldStack.getItem());
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (context.getPlayer().isSneaking()) return false;
|
||||
Block heldBlock = Block.getBlockFromItem(context.getPlayer().getStackInHand(context.getHand()).getItem());
|
||||
if (!heldBlock.getDefaultState().isFullCube(context.getWorld(), context.getBlockPos())) return false;
|
||||
if (heldBlock instanceof BlockEntityProvider || heldBlock instanceof FabricBlock) return false;
|
||||
|
||||
if (world.canPlayerModifyAt(player, pos) &&
|
||||
player.canPlaceOn(pos, hit.getSide(), heldStack) &&
|
||||
heldBlock.getDefaultState().isFullCube(world, pos) &&
|
||||
!(heldBlock instanceof BlockEntityProvider) &&
|
||||
heldBlock != this &&
|
||||
!player.isSneaking() &&
|
||||
!(heldBlock instanceof FabricBlock)
|
||||
) {
|
||||
|
||||
if (!player.isCreative()) {
|
||||
heldStack.decrement(1);
|
||||
}
|
||||
|
||||
world.setBlockState(pos, heldBlock.getPlacementState(new ItemPlacementContext(new ItemUsageContext(player, hand, hit))));
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package org.dimdev.dimdoors.event;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface UseItemOnBlockCallback {
|
||||
Event<UseItemOnBlockCallback> EVENT = EventFactory.createArrayBacked(UseItemOnBlockCallback.class,
|
||||
listeners -> (player, world, hand, hitresult) -> {
|
||||
for (UseItemOnBlockCallback event : listeners) {
|
||||
ActionResult result = event.useItemOnBlock(player, world, hand, hitresult);
|
||||
|
||||
if (result != ActionResult.PASS) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
);
|
||||
|
||||
ActionResult useItemOnBlock(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult);
|
||||
}
|
|
@ -6,6 +6,7 @@ import java.util.List;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
|
||||
import org.dimdev.dimdoors.network.ServerPacketHandler;
|
||||
import org.dimdev.dimdoors.network.s2c.PlayerInventorySlotUpdateS2CPacket;
|
||||
import org.dimdev.dimdoors.rift.targets.IdMarker;
|
||||
import org.dimdev.dimdoors.util.EntityUtils;
|
||||
|
@ -119,18 +120,11 @@ public class RiftConfigurationToolItem extends ModItem {
|
|||
// TODO: put in ServerPacketHandler
|
||||
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);
|
||||
ServerPacketHandler.sendPacket(serverPlayer, new PlayerInventorySlotUpdateS2CPacket(45, stack));
|
||||
} else {
|
||||
packet = new PlayerInventorySlotUpdateS2CPacket(serverPlayer.getInventory().selectedSlot, stack);
|
||||
}
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
try {
|
||||
packet.write(buf);
|
||||
ServerPlayNetworking.send(serverPlayer, PlayerInventorySlotUpdateS2CPacket.ID, buf);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
ServerPacketHandler.sendPacket(serverPlayer, new PlayerInventorySlotUpdateS2CPacket(serverPlayer.getInventory().selectedSlot, stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package org.dimdev.dimdoors.listener;
|
||||
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.ActionResult;
|
||||
|
@ -11,15 +9,11 @@ import net.minecraft.util.TypedActionResult;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.item.ModItem;
|
||||
import org.dimdev.dimdoors.network.ClientPacketHandler;
|
||||
import org.dimdev.dimdoors.network.c2s.HitBlockWithItemC2SPacket;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class AttackBlockCallbackListener implements AttackBlockCallback {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public ActionResult interact(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) {
|
||||
|
@ -30,11 +24,7 @@ public class AttackBlockCallbackListener implements AttackBlockCallback {
|
|||
}
|
||||
TypedActionResult<Boolean> result = ((ModItem) item).onAttackBlock(world, player, hand, pos, direction);
|
||||
if (result.getValue()) {
|
||||
try {
|
||||
ClientPlayNetworking.send(HitBlockWithItemC2SPacket.ID,
|
||||
new HitBlockWithItemC2SPacket(hand, pos, direction).write(PacketByteBufs.create()));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
if (!ClientPacketHandler.sendPacket(new HitBlockWithItemC2SPacket(hand, pos, direction))) {
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package org.dimdev.dimdoors.listener.pocket;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerBlockBreakEventBeforeListener implements PlayerBlockBreakEvents.Before {
|
||||
@Override
|
||||
public boolean beforeBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, BlockEntity blockEntity) {
|
||||
List<PlayerBlockBreakEvents.Before> applicableAddons;
|
||||
if (world.isClient) applicableAddons = PocketListenerUtil.applicableAddonsClient(PlayerBlockBreakEvents.Before.class, world, player.getBlockPos());
|
||||
else applicableAddons = PocketListenerUtil.applicableAddons(PlayerBlockBreakEvents.Before.class, world, player.getBlockPos());
|
||||
|
||||
for (PlayerBlockBreakEvents.Before listener : applicableAddons) {
|
||||
if (!listener.beforeBlockBreak(world, player, pos, state, blockEntity)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.dimdev.dimdoors.listener.pocket;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PocketAttackBlockCallbackListener implements AttackBlockCallback {
|
||||
@Override
|
||||
public ActionResult interact(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) {
|
||||
List<AttackBlockCallback> applicableAddons;
|
||||
if (world.isClient) applicableAddons = PocketListenerUtil.applicableAddonsClient(AttackBlockCallback.class, world, pos);
|
||||
else applicableAddons = PocketListenerUtil.applicableAddons(AttackBlockCallback.class, world, pos);
|
||||
|
||||
ActionResult result;
|
||||
for (AttackBlockCallback listener : applicableAddons) {
|
||||
result = listener.interact(player, world, hand, pos, direction);
|
||||
if (result != ActionResult.PASS) return result;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package org.dimdev.dimdoors.listener.pocket;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.network.ClientPacketHandler;
|
||||
import org.dimdev.dimdoors.network.ExtendedClientPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.util.math.GridUtil;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.type.Pocket;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PocketListenerUtil {
|
||||
public static <T> List<T> applicableAddons(Class<T> clazz, World world, BlockPos pos) {
|
||||
if (world.isClient) throw new UnsupportedOperationException("Cannot call this method on the Client.");
|
||||
if (!ModDimensions.isPocketDimension(world)) return Collections.emptyList();
|
||||
Pocket pocket = DimensionalRegistry.getPocketDirectory(world.getRegistryKey()).getPocketAt(pos);
|
||||
if (pocket == null) return Collections.emptyList();;
|
||||
return pocket.getAddonsInstanceOf(clazz);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static <T> List<T> applicableAddonsClient(Class<T> clazz, World world, BlockPos pos) {
|
||||
ClientPacketHandler packetHandler = ((ExtendedClientPlayNetworkHandler) MinecraftClient.getInstance().getNetworkHandler()).getDimDoorsPacketHandler();
|
||||
|
||||
if (!world.getRegistryKey().equals(packetHandler.getPocketWorld())) return Collections.emptyList();
|
||||
|
||||
int pocketId = GridUtil.gridPosToID(new GridUtil.GridPos(pos, packetHandler.getGridSize()));
|
||||
if (pocketId < packetHandler.getPocketId() || pocketId >= packetHandler.getPocketId() + packetHandler.getPocketRange()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return packetHandler.getAddons().stream().filter(clazz::isInstance).map(clazz::cast).collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.dimdev.dimdoors.listener.pocket;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UseBlockCallbackListener implements UseBlockCallback {
|
||||
@Override
|
||||
public ActionResult interact(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
|
||||
List<UseBlockCallback> applicableAddons;
|
||||
if (world.isClient) applicableAddons = PocketListenerUtil.applicableAddonsClient(UseBlockCallback.class, world, player.getBlockPos());
|
||||
else applicableAddons = PocketListenerUtil.applicableAddons(UseBlockCallback.class, world, player.getBlockPos());
|
||||
|
||||
for (UseBlockCallback listener : applicableAddons) {
|
||||
ActionResult result = listener.interact(player, world, hand, hitResult);
|
||||
if (result != ActionResult.PASS) return result;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.dimdev.dimdoors.listener.pocket;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UseItemCallbackListener implements UseItemCallback {
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> interact(PlayerEntity player, World world, Hand hand) {
|
||||
List<UseItemCallback> applicableAddons;
|
||||
if (world.isClient) applicableAddons = PocketListenerUtil.applicableAddonsClient(UseItemCallback.class, world, player.getBlockPos());
|
||||
else applicableAddons = PocketListenerUtil.applicableAddons(UseItemCallback.class, world, player.getBlockPos());
|
||||
|
||||
for (UseItemCallback listener : applicableAddons) {
|
||||
TypedActionResult<ItemStack> result = listener.interact(player, world, hand);
|
||||
if (result.getResult() != ActionResult.PASS) return result;
|
||||
}
|
||||
return TypedActionResult.pass(player.getStackInHand(hand));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.dimdev.dimdoors.listener.pocket;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.event.UseItemOnBlockCallback;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UseItemOnBlockCallbackListener implements UseItemOnBlockCallback {
|
||||
@Override
|
||||
public ActionResult useItemOnBlock(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
|
||||
List<UseItemOnBlockCallback> applicableAddons;
|
||||
if (world.isClient) applicableAddons = PocketListenerUtil.applicableAddonsClient(UseItemOnBlockCallback.class, world, player.getBlockPos());
|
||||
else applicableAddons = PocketListenerUtil.applicableAddons(UseItemOnBlockCallback.class, world, player.getBlockPos());
|
||||
|
||||
for (UseItemOnBlockCallback listener : applicableAddons) {
|
||||
ActionResult result = listener.useItemOnBlock(player, world, hand, hitResult);
|
||||
if (result != ActionResult.PASS) return result;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.dimdev.dimdoors.mixin;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.network.ExtendedServerPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.network.ServerPacketHandler;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(ServerPlayNetworkHandler.class)
|
||||
public class ExtendedServerPlayNetworkhandlerMixin implements ExtendedServerPlayNetworkHandler {
|
||||
@Final @Shadow
|
||||
private MinecraftServer server;
|
||||
private final ServerPacketHandler dimdoorsServerPacketHandler = new ServerPacketHandler((ServerPlayNetworkHandler) (Object) this);
|
||||
|
||||
@Override
|
||||
public ServerPacketHandler getDimDoorsPacketHandler() {
|
||||
return dimdoorsServerPacketHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftServer dimdoorsGetServer() {
|
||||
return server;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.dimdev.dimdoors.mixin;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerInteractionManager;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.event.UseItemOnBlockCallback;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ServerPlayerInteractionManager.class)
|
||||
public class ServerPlayerInteractionManagerMixin {
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerInteractionManager;isCreative()Z", ordinal = 0), method = "interactBlock", cancellable = true)
|
||||
public void useItemOnBlock(ServerPlayerEntity player, World world, ItemStack stack, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable<ActionResult> info) {
|
||||
ActionResult result = UseItemOnBlockCallback.EVENT.invoker().useItemOnBlock(player, world, hand, hitResult);
|
||||
if (result != ActionResult.PASS) {
|
||||
info.setReturnValue(result);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.dimdev.dimdoors.mixin.client;
|
||||
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.network.ClientPlayerInteractionManager;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import org.dimdev.dimdoors.event.UseItemOnBlockCallback;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ClientPlayerInteractionManager.class)
|
||||
public class ClientPlayerInteractionManagerMixin {
|
||||
|
||||
@Inject(method = "interactBlock", cancellable = true, at = @At(value = "INVOKE", ordinal = 2, target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V"))
|
||||
public void useItemOnBlock(ClientPlayerEntity player, ClientWorld world, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable<ActionResult> info) {
|
||||
ActionResult result = UseItemOnBlockCallback.EVENT.invoker().useItemOnBlock(player, world, hand, hitResult);
|
||||
if (result != ActionResult.PASS) {
|
||||
info.setReturnValue(result);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.dimdev.dimdoors.mixin.client;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.network.ClientPacketHandler;
|
||||
import org.dimdev.dimdoors.network.ExtendedClientPlayNetworkHandler;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Mixin(ClientPlayNetworkHandler.class)
|
||||
public class ExtendedClientPlayNetworkHandlerMixin implements ExtendedClientPlayNetworkHandler {
|
||||
@Final @Shadow
|
||||
private MinecraftClient client;
|
||||
private final ClientPacketHandler dimdoors_PacketHandler = new ClientPacketHandler((ClientPlayNetworkHandler) (Object) this);
|
||||
|
||||
@Unique
|
||||
public ClientPacketHandler getDimDoorsPacketHandler() {
|
||||
return dimdoors_PacketHandler;
|
||||
}
|
||||
|
||||
@Unique
|
||||
public MinecraftClient dimdoorsGetClient() {
|
||||
return client;
|
||||
}
|
||||
}
|
|
@ -3,18 +3,27 @@ package org.dimdev.dimdoors.network;
|
|||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
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.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.network.c2s.NetworkHandlerInitializedC2SPacket;
|
||||
import org.dimdev.dimdoors.network.s2c.PlayerInventorySlotUpdateS2CPacket;
|
||||
import org.dimdev.dimdoors.network.s2c.SyncPocketAddonsS2CPacket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.AutoSyncedAddon;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -24,17 +33,38 @@ public class ClientPacketHandler {
|
|||
|
||||
private final ClientPlayNetworkHandler networkHandler;
|
||||
private final MinecraftClient client;
|
||||
private boolean initialized = false;
|
||||
|
||||
private final Set<Identifier> registeredChannels = new HashSet<>();
|
||||
|
||||
private void registerModReceivers() {
|
||||
private RegistryKey<World> pocketWorld;
|
||||
private int gridSize = 1;
|
||||
private int pocketId = Integer.MIN_VALUE;
|
||||
private int pocketRange = 1;
|
||||
private List<AutoSyncedAddon> addons = new ArrayList<>();
|
||||
|
||||
public void init() {
|
||||
if (initialized) throw new RuntimeException("ClientPacketHandler has already been initialized.");
|
||||
initialized = true;
|
||||
registerReceiver(PlayerInventorySlotUpdateS2CPacket.ID, PlayerInventorySlotUpdateS2CPacket::new);
|
||||
registerReceiver(SyncPocketAddonsS2CPacket.ID, SyncPocketAddonsS2CPacket::new);
|
||||
|
||||
sendPacket(new NetworkHandlerInitializedC2SPacket());
|
||||
}
|
||||
|
||||
public ClientPacketHandler(ClientPlayNetworkHandler networkHandler, MinecraftClient client) {
|
||||
public static boolean sendPacket(SimplePacket<?> packet) {
|
||||
try {
|
||||
ClientPlayNetworking.send(packet.channelId(), packet.write(PacketByteBufs.create()));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ClientPacketHandler(ClientPlayNetworkHandler networkHandler) {
|
||||
this.networkHandler = networkHandler;
|
||||
this.client = client;
|
||||
registerModReceivers();
|
||||
this.client = ((ExtendedClientPlayNetworkHandler) networkHandler).dimdoorsGetClient();
|
||||
}
|
||||
|
||||
private void registerReceiver(Identifier channelName, Supplier<? extends SimplePacket<ClientPacketHandler>> supplier) {
|
||||
|
@ -58,10 +88,37 @@ public class ClientPacketHandler {
|
|||
new HashSet<>(registeredChannels).forEach(this::unregisterReceiver);
|
||||
}
|
||||
|
||||
public void onSyncPocketAddons(RegistryKey<World> world, int gridSize, int pocketId, int pocketRange, List<AutoSyncedAddon> addons) {
|
||||
this.pocketWorld = world;
|
||||
this.gridSize = gridSize;
|
||||
this.pocketId = pocketId;
|
||||
this.pocketRange = pocketRange;
|
||||
this.addons = addons;
|
||||
}
|
||||
|
||||
public void onPlayerInventorySlotUpdate(int slot, ItemStack stack) {
|
||||
if (client.player != null) {
|
||||
this.client.player.getInventory().setStack(slot, stack);
|
||||
client.player.getInventory().setStack(slot, stack);
|
||||
}
|
||||
}
|
||||
|
||||
public RegistryKey<World> getPocketWorld() {
|
||||
return pocketWorld;
|
||||
}
|
||||
|
||||
public int getGridSize() {
|
||||
return gridSize;
|
||||
}
|
||||
|
||||
public int getPocketId() {
|
||||
return pocketId;
|
||||
}
|
||||
|
||||
public int getPocketRange() {
|
||||
return pocketRange;
|
||||
}
|
||||
|
||||
public List<AutoSyncedAddon> getAddons() {
|
||||
return addons;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package org.dimdev.dimdoors.network;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ExtendedClientPlayNetworkHandler {
|
||||
ClientPacketHandler getDimDoorsPacketHandler();
|
||||
|
||||
MinecraftClient dimdoorsGetClient();
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.dimdev.dimdoors.network;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public interface ExtendedServerPlayNetworkHandler {
|
||||
ServerPacketHandler getDimDoorsPacketHandler();
|
||||
|
||||
MinecraftServer dimdoorsGetServer();
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.dimdev.dimdoors.network;
|
||||
|
||||
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.item.Item;
|
||||
|
@ -11,14 +12,22 @@ import net.minecraft.util.Hand;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.item.ModItem;
|
||||
import org.dimdev.dimdoors.network.c2s.HitBlockWithItemC2SPacket;
|
||||
import org.dimdev.dimdoors.network.c2s.NetworkHandlerInitializedC2SPacket;
|
||||
import org.dimdev.dimdoors.network.s2c.SyncPocketAddonsS2CPacket;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.PocketDirectory;
|
||||
import org.dimdev.dimdoors.world.pocket.type.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.AutoSyncedAddon;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
// each client has their own corresponding ServerPacketHandler, so feel free to add client specific data in here
|
||||
|
@ -28,16 +37,32 @@ public class ServerPacketHandler {
|
|||
private final ServerPlayNetworkHandler networkHandler;
|
||||
private final MinecraftServer server;
|
||||
private final Set<Identifier> registeredChannels = new HashSet<>();
|
||||
private boolean initialized = false;
|
||||
|
||||
private void registerModReceivers() {
|
||||
private RegistryKey<World> lastSyncedPocketWorld;
|
||||
private int lastSyncedPocketId = Integer.MIN_VALUE;
|
||||
private boolean pocketSyncDirty = true;
|
||||
|
||||
public void init() {
|
||||
if (initialized) throw new RuntimeException("ServerPacketHandler has already been initialized.");
|
||||
initialized = true;
|
||||
registerReceiver(NetworkHandlerInitializedC2SPacket.ID, NetworkHandlerInitializedC2SPacket::new);
|
||||
registerReceiver(HitBlockWithItemC2SPacket.ID, HitBlockWithItemC2SPacket::new);
|
||||
}
|
||||
|
||||
public static boolean sendPacket(ServerPlayerEntity player, SimplePacket<?> packet) {
|
||||
try {
|
||||
ServerPlayNetworking.send(player, packet.channelId(), packet.write(PacketByteBufs.create()));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ServerPacketHandler(ServerPlayNetworkHandler networkHandler, MinecraftServer server) {
|
||||
public ServerPacketHandler(ServerPlayNetworkHandler networkHandler) {
|
||||
this.networkHandler = networkHandler;
|
||||
this.server = server;
|
||||
registerModReceivers();
|
||||
this.server = ((ExtendedServerPlayNetworkHandler) networkHandler).dimdoorsGetServer();
|
||||
}
|
||||
|
||||
private void registerReceiver(Identifier channelName, Supplier<? extends SimplePacket<ServerPacketHandler>> supplier) {
|
||||
|
@ -73,4 +98,26 @@ public class ServerPacketHandler {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onNetworkHandlerInitialized() {
|
||||
syncPocketAddonsIfNeeded(getPlayer().world, getPlayer().getBlockPos());
|
||||
}
|
||||
|
||||
// TODO: attach this to some event to detect other kinds teleportation
|
||||
public void syncPocketAddonsIfNeeded(World world, BlockPos pos) {
|
||||
if (!ModDimensions.isPocketDimension(world)) return;
|
||||
PocketDirectory directory = DimensionalRegistry.getPocketDirectory(world.getRegistryKey());
|
||||
Pocket pocket = directory.getPocketAt(pos);
|
||||
if (pocket == null) return;
|
||||
if ((pocketSyncDirty || pocket.getId() != lastSyncedPocketId || !world.getRegistryKey().getValue().equals(lastSyncedPocketWorld.getValue()))) {
|
||||
pocketSyncDirty = false;
|
||||
lastSyncedPocketId = pocket.getId();
|
||||
lastSyncedPocketWorld = world.getRegistryKey();
|
||||
sendPacket(getPlayer(), new SyncPocketAddonsS2CPacket(world.getRegistryKey(), directory.getGridSize(), pocket.getId(), pocket.getRange(), pocket.getAddonsInstanceOf(AutoSyncedAddon.class)));
|
||||
}
|
||||
}
|
||||
|
||||
public void markPocketSyncDirty(int id) {
|
||||
if (lastSyncedPocketId == id) pocketSyncDirty = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.dimdev.dimdoors.network;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -10,4 +11,6 @@ public interface SimplePacket<T> {
|
|||
PacketByteBuf write(PacketByteBuf buf) throws IOException;
|
||||
|
||||
void apply(T listener);
|
||||
|
||||
Identifier channelId();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.dimdev.dimdoors.network.SimplePacket;
|
|||
import java.io.IOException;
|
||||
|
||||
public class HitBlockWithItemC2SPacket implements SimplePacket<ServerPacketHandler> {
|
||||
public static final Identifier ID = new Identifier("dimdoors:hit_block");
|
||||
public static final Identifier ID = new Identifier("dimdoors", "hit_block_with_item");
|
||||
|
||||
private Hand hand;
|
||||
private BlockPos pos;
|
||||
|
@ -49,4 +49,9 @@ public class HitBlockWithItemC2SPacket implements SimplePacket<ServerPacketHandl
|
|||
public void apply(ServerPacketHandler listener) {
|
||||
listener.onAttackBlock(hand, pos, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier channelId() {
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package org.dimdev.dimdoors.network.c2s;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.dimdev.dimdoors.network.ServerPacketHandler;
|
||||
import org.dimdev.dimdoors.network.SimplePacket;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class NetworkHandlerInitializedC2SPacket implements SimplePacket<ServerPacketHandler> {
|
||||
public static final Identifier ID = new Identifier("dimdoors", "network_handler_initialized");
|
||||
|
||||
@Override
|
||||
public SimplePacket<ServerPacketHandler> read(PacketByteBuf buf) throws IOException {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketByteBuf write(PacketByteBuf buf) throws IOException {
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ServerPacketHandler listener) {
|
||||
listener.onNetworkHandlerInitialized();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier channelId() {
|
||||
return ID;
|
||||
}
|
||||
}
|
|
@ -44,4 +44,9 @@ public class PlayerInventorySlotUpdateS2CPacket implements SimplePacket<ClientPa
|
|||
public void apply(ClientPacketHandler listener) {
|
||||
listener.onPlayerInventorySlotUpdate(slot, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier channelId() {
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package org.dimdev.dimdoors.network.s2c;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.network.ClientPacketHandler;
|
||||
import org.dimdev.dimdoors.network.SimplePacket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.AutoSyncedAddon;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class SyncPocketAddonsS2CPacket implements SimplePacket<ClientPacketHandler> {
|
||||
public static final Identifier ID = new Identifier("dimdoors:sync_pocket_addons");
|
||||
|
||||
private RegistryKey<World> world;
|
||||
private int gridSize;
|
||||
private int pocketId;
|
||||
private int pocketRange;
|
||||
private List<AutoSyncedAddon> addons;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public SyncPocketAddonsS2CPacket() {
|
||||
}
|
||||
|
||||
public SyncPocketAddonsS2CPacket(RegistryKey<World> world, int gridSize, int pocketId, int pocketRange, List<AutoSyncedAddon> addons) {
|
||||
this.world = world;
|
||||
this.gridSize = gridSize;
|
||||
this.pocketId = pocketId;
|
||||
this.pocketRange = pocketRange;
|
||||
this.addons = addons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimplePacket<ClientPacketHandler> read(PacketByteBuf buf) throws IOException {
|
||||
this.world = RegistryKey.of(Registry.DIMENSION, buf.readIdentifier());
|
||||
this.gridSize = buf.readInt();
|
||||
this.pocketId = buf.readInt();
|
||||
this.pocketRange = buf.readInt();
|
||||
this.addons = AutoSyncedAddon.readAutoSyncedAddonList(buf);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketByteBuf write(PacketByteBuf buf) throws IOException {
|
||||
buf.writeIdentifier(world.getValue());
|
||||
buf.writeInt(gridSize);
|
||||
buf.writeInt(pocketId);
|
||||
buf.writeInt(pocketRange);
|
||||
AutoSyncedAddon.writeAutoSyncedAddonList(buf, addons);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ClientPacketHandler listener) {
|
||||
listener.onSyncPocketAddons(world, gridSize, pocketId, pocketRange, addons);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier channelId() {
|
||||
return ID;
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ public abstract class PocketGenerator implements Weighted<PocketGenerationParame
|
|||
private static final int fallbackWeight = 5; // TODO: make config
|
||||
private final List<Modifier> modifierList = new ArrayList<>();
|
||||
|
||||
private String builderType;
|
||||
private CompoundTag builderTag;
|
||||
protected String weight;
|
||||
protected Equation weightEquation;
|
||||
protected Boolean setupLoot;
|
||||
|
@ -84,7 +84,7 @@ public abstract class PocketGenerator implements Weighted<PocketGenerationParame
|
|||
}
|
||||
|
||||
public PocketGenerator fromTag(CompoundTag tag) {
|
||||
if (tag.contains("builder", NbtType.STRING)) builderType = tag.getString("builder");
|
||||
if (tag.contains("builder", NbtType.COMPOUND)) builderTag = tag.getCompound("builder");
|
||||
|
||||
this.weight = tag.contains("weight") ? tag.getString("weight") : defaultWeightEquation;
|
||||
parseWeight();
|
||||
|
@ -110,7 +110,7 @@ public abstract class PocketGenerator implements Weighted<PocketGenerationParame
|
|||
public CompoundTag toTag(CompoundTag tag) {
|
||||
this.getType().toTag(tag);
|
||||
|
||||
if (builderType != null) tag.putString("builder", builderType);
|
||||
if (builderTag != null) tag.put("builder", builderTag);
|
||||
|
||||
if (!weight.equals("5")) tag.putString("weight", weight);
|
||||
|
||||
|
@ -203,11 +203,11 @@ public abstract class PocketGenerator implements Weighted<PocketGenerationParame
|
|||
}
|
||||
|
||||
public Pocket.PocketBuilder<?, ?> pocketBuilder(PocketGenerationParameters parameters) { // TODO: PocketBuilder from json
|
||||
if (builderType == null){
|
||||
if (builderTag == null){
|
||||
return Pocket.builder()
|
||||
.expand(getSize(parameters));
|
||||
}
|
||||
AbstractPocket.AbstractPocketBuilder<?, ?> abstractBuilder = AbstractPocket.REGISTRY.get(new Identifier(builderType)).builder();
|
||||
AbstractPocket.AbstractPocketBuilder<?, ?> abstractBuilder = AbstractPocket.deserializeBuilder(builderTag);
|
||||
if (! (abstractBuilder instanceof Pocket.PocketBuilder)) {
|
||||
return Pocket.builder()
|
||||
.expand(getSize(parameters));
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package org.dimdev.dimdoors.pockets.virtual.reference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.pockets.generator.PocketGenerator;
|
||||
|
@ -27,6 +29,7 @@ public abstract class PocketGeneratorReference extends VirtualSingularPocket {
|
|||
protected Equation weightEquation;
|
||||
protected Boolean setupLoot;
|
||||
protected final List<Modifier> modifierList = Lists.newArrayList();
|
||||
protected final List<CompoundTag> addons = new ArrayList<>();
|
||||
|
||||
private void parseWeight() {
|
||||
try {
|
||||
|
@ -58,7 +61,14 @@ public abstract class PocketGeneratorReference extends VirtualSingularPocket {
|
|||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
if (tag.contains("addons", NbtType.LIST)) {
|
||||
ListTag modifiersTag = tag.getList("addons", 10);
|
||||
for (int i = 0; i < modifiersTag.size(); i++) {
|
||||
addons.add(modifiersTag.getCompound(i));
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,6 +85,10 @@ public abstract class PocketGeneratorReference extends VirtualSingularPocket {
|
|||
}
|
||||
if (modifiersTag.size() > 0) tag.put("modifiers", modifiersTag);
|
||||
|
||||
ListTag addonsTag = new ListTag();
|
||||
addonsTag.addAll(addons);
|
||||
if (addonsTag.size() > 0) tag.put("addons", addonsTag);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import net.minecraft.entity.ItemEntity;
|
|||
import net.minecraft.item.DyeItem;
|
||||
import net.minecraft.item.Item;
|
||||
import org.dimdev.dimdoors.world.pocket.type.PrivatePocket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.DyeableAddon;
|
||||
|
||||
public class PrivatePocketTarget extends VirtualTarget implements EntityTarget {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
|
|
@ -14,6 +14,8 @@ import net.minecraft.world.TeleportTarget;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.dimension.v1.FabricDimensions;
|
||||
import org.dimdev.dimdoors.network.ExtendedServerPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.network.ServerPacketHandler;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public final class TeleportUtil {
|
||||
|
@ -50,11 +52,15 @@ public final class TeleportUtil {
|
|||
entity.pitch = angle.getPitch();
|
||||
entity.teleport(pos.x, pos.y, pos.z);
|
||||
entity.setVelocity(velocity);
|
||||
|
||||
return entity;
|
||||
} else {
|
||||
entity = FabricDimensions.teleport(entity, (ServerWorld) world, new TeleportTarget(pos, velocity, angle.getYaw(), angle.getPitch()));
|
||||
}
|
||||
|
||||
return FabricDimensions.teleport(entity, (ServerWorld) world, new TeleportTarget(pos, velocity, angle.getYaw(), angle.getPitch()));
|
||||
if (entity instanceof ServerPlayerEntity) {
|
||||
((ExtendedServerPlayNetworkHandler) ((ServerPlayerEntity) entity).networkHandler).getDimDoorsPacketHandler().syncPocketAddonsIfNeeded(world, new BlockPos(pos));
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static <E extends Entity> E teleport(E entity, World world, BlockPos pos, EulerAngle angle, Vec3d velocity) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.dimdev.dimdoors.util.math;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Vector;
|
||||
|
||||
|
@ -13,6 +15,11 @@ public final class GridUtil {
|
|||
this.z = z;
|
||||
}
|
||||
|
||||
public GridPos(BlockPos pos, int gridSize) {
|
||||
this.x = pos.getX() / gridSize / 16;
|
||||
this.z = pos.getZ() / gridSize / 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
|
|
|
@ -106,7 +106,8 @@ public class PocketDirectory {
|
|||
T pocket = builder
|
||||
.id(cursor)
|
||||
.world(worldKey)
|
||||
.offsetOrigin(idToPos(cursor))
|
||||
.range(squaredSize)
|
||||
.offsetOrigin(idToCenteredPos(cursor, base3Size, builder.getExpectedSize()))
|
||||
.build();
|
||||
|
||||
nextIDMap.put(base3Size, cursor + squaredSize);
|
||||
|
@ -120,7 +121,6 @@ public class PocketDirectory {
|
|||
.referencedId(cursor)
|
||||
.build());
|
||||
}
|
||||
|
||||
return pocket;
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,12 @@ public class PocketDirectory {
|
|||
return new BlockPos(pos.x * this.gridSize * 16, 0, pos.z * this.gridSize * 16);
|
||||
}
|
||||
|
||||
public BlockPos idToCenteredPos(int id, int base3Size, Vec3i expectedSize) {
|
||||
GridUtil.GridPos pos = this.idToGridPos(id);
|
||||
// you actually need the "/ 2 * 16" here. "*8" would not work the same since it doesn't guarantee chunk alignment
|
||||
return new BlockPos((pos.x * this.gridSize * 16) + (base3Size * this.gridSize - expectedSize.getX() / 16) / 2 * 16, 0, (pos.z * this.gridSize * 16) + (base3Size * this.gridSize - expectedSize.getZ() / 16) / 2 * 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the ID of a pocket at a certain BlockPos.
|
||||
*
|
||||
|
|
|
@ -36,6 +36,11 @@ public abstract class AbstractPocket<V extends AbstractPocket<V>> {
|
|||
return REGISTRY.get(id).fromTag(tag);
|
||||
}
|
||||
|
||||
public static AbstractPocketBuilder<?, ?> deserializeBuilder(CompoundTag tag) {
|
||||
Identifier id = Identifier.tryParse(tag.getString("type"));
|
||||
return REGISTRY.get(id).builder().fromTag(tag);
|
||||
}
|
||||
|
||||
public static CompoundTag serialize(AbstractPocket<?> pocket) {
|
||||
return pocket.toTag(new CompoundTag());
|
||||
}
|
||||
|
@ -114,12 +119,11 @@ public abstract class AbstractPocket<V extends AbstractPocket<V>> {
|
|||
}
|
||||
|
||||
public static abstract class AbstractPocketBuilder<P extends AbstractPocketBuilder<P, T>, T extends AbstractPocket<?>> {
|
||||
private final AbstractPocketType<T> type;
|
||||
protected final AbstractPocketType<T> type;
|
||||
|
||||
private int id;
|
||||
private RegistryKey<World> world;
|
||||
|
||||
//TODO: fromTag/ toTag for reading builders from json, in subclasses as well
|
||||
protected AbstractPocketBuilder(AbstractPocketType<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
@ -139,12 +143,36 @@ public abstract class AbstractPocket<V extends AbstractPocket<V>> {
|
|||
|
||||
public P id(int id) {
|
||||
this.id = id;
|
||||
return (P) this;
|
||||
return getSelf();
|
||||
}
|
||||
|
||||
public P world(RegistryKey<World> world) {
|
||||
this.world = world;
|
||||
return getSelf();
|
||||
}
|
||||
|
||||
public P getSelf() {
|
||||
return (P) this;
|
||||
}
|
||||
|
||||
abstract public P fromTag(CompoundTag tag);
|
||||
|
||||
abstract public CompoundTag toTag(CompoundTag tag);
|
||||
|
||||
/*
|
||||
public P fromTag(CompoundTag tag) {
|
||||
id = tag.getInt("id");
|
||||
world = RegistryKey.of(Registry.DIMENSION, new Identifier(tag.getString("world")));
|
||||
|
||||
return getSelf();
|
||||
}
|
||||
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag.putInt("id", id);
|
||||
tag.putString("world", world.getValue().toString());
|
||||
|
||||
return tag;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
|
||||
|
@ -41,7 +42,7 @@ public class IdReferencePocket extends AbstractPocket<IdReferencePocket> {
|
|||
}
|
||||
|
||||
public static class IdReferencePocketBuilder extends AbstractPocketBuilder<IdReferencePocketBuilder, IdReferencePocket> {
|
||||
private int referencedId;
|
||||
private int referencedId = Integer.MIN_VALUE;
|
||||
|
||||
protected IdReferencePocketBuilder(AbstractPocketType<IdReferencePocket> type) {
|
||||
super(type);
|
||||
|
@ -54,6 +55,18 @@ public class IdReferencePocket extends AbstractPocket<IdReferencePocket> {
|
|||
return pocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdReferencePocketBuilder fromTag(CompoundTag tag) {
|
||||
if (tag.contains("referenced_id", NbtType.INT)) referencedId = tag.getInt("referenced_id");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
if (referencedId != Integer.MIN_VALUE) tag.putInt("referenced_id", referencedId);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public IdReferencePocketBuilder referencedId(int referencedId) {
|
||||
this.referencedId = referencedId;
|
||||
return this;
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.DyeColor;
|
||||
import net.minecraft.util.math.BlockBox;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
|
@ -20,11 +23,14 @@ import net.minecraft.util.math.Vec3i;
|
|||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.world.pocket.VirtualLocation;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.IHasAddon;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.PocketAddon;
|
||||
|
||||
public class Pocket extends AbstractPocket<Pocket> {
|
||||
public class Pocket extends AbstractPocket<Pocket> implements IHasAddon {
|
||||
public static String KEY = "pocket";
|
||||
|
||||
private final Map<Identifier, PocketAddon> addons = new HashMap<>();
|
||||
private int range = -1;
|
||||
public BlockBox box; // TODO: make protected
|
||||
public VirtualLocation virtualLocation;
|
||||
|
||||
|
@ -39,6 +45,29 @@ public class Pocket extends AbstractPocket<Pocket> {
|
|||
|
||||
}
|
||||
|
||||
public boolean hasAddon(Identifier id) {
|
||||
return addons.containsKey(id);
|
||||
}
|
||||
|
||||
public <C extends PocketAddon> boolean addAddon(C addon) {
|
||||
if (addon.applicable(this)) {
|
||||
addon.addAddon(addons);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public <C extends PocketAddon> C getAddon(Identifier id) {
|
||||
return (C) addons.get(id);
|
||||
}
|
||||
|
||||
public <T> List<T> getAddonsInstanceOf(Class<T> clazz) {
|
||||
return addons.values().stream()
|
||||
.filter(clazz::isInstance)
|
||||
.map(clazz::cast)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public boolean isInBounds(BlockPos pos) {
|
||||
return this.box.contains(pos);
|
||||
}
|
||||
|
@ -63,14 +92,31 @@ public class Pocket extends AbstractPocket<Pocket> {
|
|||
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 void setRange(int range) {
|
||||
if (this.range > 0) throw new UnsupportedOperationException("Cannot set range of Pocket that has already been initialized.");
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public int getRange() {
|
||||
if (range < 1) throw new UnsupportedOperationException("Range of pocket has not been initialized yet.");
|
||||
return range;
|
||||
}
|
||||
|
||||
public Vec3i getSize() {
|
||||
return this.box.getDimensions();
|
||||
}
|
||||
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
|
||||
tag.putInt("range", range);
|
||||
tag.putIntArray("box", IntStream.of(this.box.minX, this.box.minY, this.box.minZ, this.box.maxX, this.box.maxY, this.box.maxZ).toArray());
|
||||
tag.put("virtualLocation", VirtualLocation.toTag(this.virtualLocation));
|
||||
|
||||
ListTag addonsTag = new ListTag();
|
||||
addonsTag.addAll(addons.values().stream().map(addon -> addon.toTag(new CompoundTag())).collect(Collectors.toList()));
|
||||
if (addonsTag.size() > 0) tag.put("addons", addonsTag);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@ -81,71 +127,22 @@ public class Pocket extends AbstractPocket<Pocket> {
|
|||
|
||||
public Pocket fromTag(CompoundTag tag) {
|
||||
super.fromTag(tag);
|
||||
|
||||
this.range = tag.getInt("range");
|
||||
int[] box = tag.getIntArray("box");
|
||||
this.box = new BlockBox(box[0], box[1], box[2], box[3], box[4], box[5]);
|
||||
this.virtualLocation = VirtualLocation.fromTag(tag.getCompound("virtualLocation"));
|
||||
|
||||
if (tag.contains("addons", NbtType.LIST)) {
|
||||
for (Tag addonTag : tag.getList("addons", NbtType.COMPOUND)) {
|
||||
PocketAddon addon = PocketAddon.deserialize((CompoundTag) addonTag);
|
||||
addons.put(addon.getId(), addon);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public enum PocketColor {
|
||||
WHITE(0, DyeColor.WHITE),
|
||||
ORANGE(1, DyeColor.ORANGE),
|
||||
MAGENTA(2, DyeColor.MAGENTA),
|
||||
LIGHT_BLUE(3, DyeColor.LIGHT_BLUE),
|
||||
YELLOW(4, DyeColor.YELLOW),
|
||||
LIME(5, DyeColor.LIME),
|
||||
PINK(6, DyeColor.PINK),
|
||||
GRAY(7, DyeColor.GRAY),
|
||||
LIGHT_GRAY(8, DyeColor.LIGHT_GRAY),
|
||||
CYAN(9, DyeColor.CYAN),
|
||||
PURPLE(10, DyeColor.PURPLE),
|
||||
BLUE(11, DyeColor.BLUE),
|
||||
BROWN(12, DyeColor.BROWN),
|
||||
GREEN(13, DyeColor.GREEN),
|
||||
RED(14, DyeColor.RED),
|
||||
BLACK(15, DyeColor.BLACK),
|
||||
NONE(16, null);
|
||||
|
||||
private final int id;
|
||||
private final DyeColor color;
|
||||
|
||||
public static Codec<PocketColor> CODEC = Codec.INT.xmap(PocketColor::from, PocketColor::getId);
|
||||
|
||||
PocketColor(int id, DyeColor color) {
|
||||
this.id = id;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public DyeColor getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public static PocketColor from(DyeColor color) {
|
||||
for (PocketColor a : PocketColor.values()) {
|
||||
if (color == a.color) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
public static PocketColor from(int id) {
|
||||
for (PocketColor a : PocketColor.values()) {
|
||||
if (id == a.id) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<BlockPos, BlockEntity> getBlockEntities() {
|
||||
ServerWorld serverWorld = DimensionalDoorsInitializer.getWorld(this.getWorld());
|
||||
Map<BlockPos, BlockEntity> blockEntities = new HashMap<>();
|
||||
|
@ -187,32 +184,57 @@ public class Pocket extends AbstractPocket<Pocket> {
|
|||
|
||||
// TODO: flesh this out a bit more, stuff like box() makes little sense in how it is implemented atm
|
||||
public static class PocketBuilder<P extends PocketBuilder<P, T>, T extends Pocket> extends AbstractPocketBuilder<P, T> {
|
||||
private final Map<Class<? extends PocketAddon.PocketBuilderAddon<?>>, PocketAddon.PocketBuilderAddon<?>> addons = new HashMap<>();
|
||||
private final Map<Identifier, PocketAddon.PocketBuilderAddon<?>> addons = new HashMap<>();
|
||||
|
||||
private Vec3i origin = new Vec3i(0, 0, 0);
|
||||
private Vec3i size = new Vec3i(0, 0, 0);
|
||||
private Vec3i expected = new Vec3i(0, 0, 0);
|
||||
private VirtualLocation virtualLocation;
|
||||
private PocketColor dyeColor = PocketColor.NONE;
|
||||
private int range = -1;
|
||||
|
||||
protected PocketBuilder(AbstractPocketType<T> type) {
|
||||
super(type);
|
||||
initAddons();
|
||||
}
|
||||
|
||||
public <C extends PocketAddon.PocketBuilderAddon<X>, X extends PocketAddon<X>> boolean hasAddon(Class<C> addonClass) {
|
||||
return addons.containsKey(addonClass);
|
||||
public void initAddons() {
|
||||
|
||||
}
|
||||
|
||||
protected <C extends PocketAddon.PocketBuilderAddon<X>, X extends PocketAddon<X>> void addAddon(Class<C> addonClass, C addon) {
|
||||
addons.put(addonClass, addon);
|
||||
// TODO: actually utilize fromTag/ toTag methods + implement them
|
||||
public P fromTag(CompoundTag tag) {
|
||||
if (tag.contains("addons", NbtType.LIST)) {
|
||||
for (Tag addonTag : tag.getList("addons", NbtType.COMPOUND)) {
|
||||
PocketAddon.PocketBuilderAddon<?> addon = PocketAddon.deserializeBuilder((CompoundTag) addonTag);
|
||||
addons.put(addon.getId(), addon);
|
||||
}
|
||||
}
|
||||
|
||||
return getSelf();
|
||||
}
|
||||
|
||||
public <C extends PocketAddon.PocketBuilderAddon<X>, X extends PocketAddon<X>> C getAddon(Class<C> addonClass) {
|
||||
return (C) addons.get(addonClass);
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
ListTag addonsTag = new ListTag();
|
||||
addonsTag.addAll(addons.values().stream().map(addon -> addon.toTag(new CompoundTag())).collect(Collectors.toList()));
|
||||
if (addonsTag.size() > 0) tag.put("addons", addonsTag);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public P getSelf() {
|
||||
return (P) this;
|
||||
public boolean hasAddon(Identifier id) {
|
||||
return addons.containsKey(id);
|
||||
}
|
||||
|
||||
protected <C extends PocketAddon.PocketBuilderAddon<?>> boolean addAddon(C addon) {
|
||||
if (addon.applicable(this)) {
|
||||
addon.addAddon(addons);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public <C extends PocketAddon.PocketBuilderAddon<?>> C getAddon(Identifier id) {
|
||||
return (C) addons.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -221,38 +243,43 @@ public class Pocket extends AbstractPocket<Pocket> {
|
|||
}
|
||||
|
||||
public T build() {
|
||||
if (range < 1) throw new RuntimeException("Cannot create pocket with range < 1");
|
||||
|
||||
T instance = super.build();
|
||||
|
||||
instance.setRange(range);
|
||||
instance.box = BlockBox.create(origin.getX(), origin.getY(), origin.getZ(), origin.getX() + size.getX(), origin.getY() + size.getY(), origin.getZ() + size.getZ());
|
||||
instance.virtualLocation = virtualLocation;
|
||||
|
||||
addons.values().forEach(addon -> addon.apply(instance));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public P offsetOrigin(Vec3i offset) {
|
||||
this.origin = new Vec3i(origin.getX() + offset.getX(), origin.getY() + offset.getY(), origin.getZ() + offset.getZ());
|
||||
return (P) this;
|
||||
return getSelf();
|
||||
}
|
||||
|
||||
public P expand(Vec3i expander) {
|
||||
this.size = new Vec3i(size.getX() + expander.getX(), size.getY() + expander.getY(), size.getZ() + expander.getZ());
|
||||
this.expected = new Vec3i(expected.getX() + expander.getX(), expected.getY() + expander.getY(), expected.getZ() + expander.getZ());
|
||||
return (P) this;
|
||||
return getSelf();
|
||||
}
|
||||
|
||||
public P expandExpected(Vec3i expander) {
|
||||
this.expected = new Vec3i(expected.getX() + expander.getX(), expected.getY() + expander.getY(), expected.getZ() + expander.getZ());
|
||||
return (P) this;
|
||||
return getSelf();
|
||||
}
|
||||
|
||||
public P virtualLocation(VirtualLocation virtualLocation) {
|
||||
this.virtualLocation = virtualLocation;
|
||||
return (P) this;
|
||||
return getSelf();
|
||||
}
|
||||
|
||||
public P dyeColor(PocketColor dyeColor) {
|
||||
this.dyeColor = dyeColor;
|
||||
return (P) this;
|
||||
public P range(int range) {
|
||||
this.range = range;
|
||||
return getSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.util.DyeColor;
|
||||
|
||||
public enum PocketColor {
|
||||
WHITE(0, DyeColor.WHITE),
|
||||
ORANGE(1, DyeColor.ORANGE),
|
||||
MAGENTA(2, DyeColor.MAGENTA),
|
||||
LIGHT_BLUE(3, DyeColor.LIGHT_BLUE),
|
||||
YELLOW(4, DyeColor.YELLOW),
|
||||
LIME(5, DyeColor.LIME),
|
||||
PINK(6, DyeColor.PINK),
|
||||
GRAY(7, DyeColor.GRAY),
|
||||
LIGHT_GRAY(8, DyeColor.LIGHT_GRAY),
|
||||
CYAN(9, DyeColor.CYAN),
|
||||
PURPLE(10, DyeColor.PURPLE),
|
||||
BLUE(11, DyeColor.BLUE),
|
||||
BROWN(12, DyeColor.BROWN),
|
||||
GREEN(13, DyeColor.GREEN),
|
||||
RED(14, DyeColor.RED),
|
||||
BLACK(15, DyeColor.BLACK),
|
||||
NONE(16, null);
|
||||
|
||||
private final int id;
|
||||
private final DyeColor color;
|
||||
|
||||
public static Codec<PocketColor> CODEC = Codec.INT.xmap(PocketColor::from, PocketColor::getId);
|
||||
|
||||
PocketColor(int id, DyeColor color) {
|
||||
this.id = id;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public DyeColor getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public static PocketColor from(DyeColor color) {
|
||||
for (PocketColor a : PocketColor.values()) {
|
||||
if (color == a.color) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
public static PocketColor from(int id) {
|
||||
for (PocketColor a : PocketColor.values()) {
|
||||
if (id == a.id) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
return NONE;
|
||||
}
|
||||
}
|
|
@ -1,118 +1,23 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
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.math.BlockPos;
|
||||
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.util.EntityUtils;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.DyeablePocket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.DyeableAddon;
|
||||
|
||||
public class PrivatePocket extends Pocket implements DyeablePocket {
|
||||
public class PrivatePocket extends Pocket implements DyeableAddon.DyeablePocket {
|
||||
public static String KEY = "private_pocket";
|
||||
|
||||
private static final int BLOCKS_PAINTED_PER_DYE = 1000000;
|
||||
|
||||
protected PocketColor dyeColor = PocketColor.WHITE;
|
||||
private PocketColor nextDyeColor = PocketColor.NONE;
|
||||
private int count = 0;
|
||||
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag = super.toTag(tag);
|
||||
|
||||
tag.putInt("dyeColor", this.dyeColor.getId());
|
||||
tag.putInt("nextDyeColor", this.nextDyeColor.getId());
|
||||
tag.putInt("count", this.count);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pocket fromTag(CompoundTag tag) {
|
||||
super.fromTag(tag);
|
||||
|
||||
this.dyeColor = PocketColor.from(tag.getInt("dyeColor"));
|
||||
this.nextDyeColor = PocketColor.from(tag.getInt("nextDyeColor"));
|
||||
this.count = tag.getInt("count");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDyeColor(PocketColor dyeColor) {
|
||||
|
||||
}
|
||||
|
||||
public boolean addDye(Entity entity, DyeColor dyeColor) {
|
||||
PocketColor color = PocketColor.from(dyeColor);
|
||||
|
||||
int maxDye = amountOfDyeRequiredToColor(this);
|
||||
|
||||
if (this.dyeColor == color) {
|
||||
EntityUtils.chat(entity, new TranslatableText("dimdoors.pockets.dyeAlreadyAbsorbed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
EntityUtils.chat(entity, new TranslatableText("dimdoors.pocket.pocketHasBeenDyed", dyeColor));
|
||||
} else {
|
||||
this.count++;
|
||||
EntityUtils.chat(entity, new TranslatableText("dimdoors.pocket.remainingNeededDyes", this.count, maxDye, color));
|
||||
}
|
||||
} else {
|
||||
this.nextDyeColor = color;
|
||||
this.count = 1;
|
||||
EntityUtils.chat(entity, new TranslatableText("dimdoors.pocket.remainingNeededDyes", this.count, maxDye, color));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void repaint(DyeColor dyeColor) {
|
||||
ServerWorld serverWorld = DimensionalDoorsInitializer.getWorld(getWorld());
|
||||
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 Math.max((outerVolume - innerVolume) / BLOCKS_PAINTED_PER_DYE, 1);
|
||||
}
|
||||
|
||||
public static PrivatePocketBuilder<?, PrivatePocket> builderPrivatePocket() {
|
||||
return new PrivatePocketBuilder<>(AbstractPocketType.PRIVATE_POCKET);
|
||||
}
|
||||
|
||||
public static class PrivatePocketBuilder<P extends PrivatePocketBuilder<P, T>, T extends PrivatePocket> extends PocketBuilder<P, T> implements DyeablePocketBuilder<P> {
|
||||
public static class PrivatePocketBuilder<P extends PrivatePocketBuilder<P, T>, T extends PrivatePocket> extends PocketBuilder<P, T> implements DyeableAddon.DyeablePocketBuilder<P> {
|
||||
protected PrivatePocketBuilder(AbstractPocketType<T> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initAddons() {
|
||||
addAddon(DyeableBuilderAddon.class, new DyeableBuilderAddon());
|
||||
super.initAddons();
|
||||
addAddon(new DyeableAddon.DyeableBuilderAddon());
|
||||
this.dyeColor(PocketColor.WHITE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type.addon;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public interface AutoSyncedAddon extends PocketAddon {
|
||||
static <T extends AutoSyncedAddon> List<T> readAutoSyncedAddonList(PacketByteBuf buf) throws IOException {
|
||||
List<T> addons = new ArrayList<>();
|
||||
int addonCount = buf.readInt();
|
||||
try {
|
||||
for (int i = 0; i < addonCount; i++) {
|
||||
addons.add((T) ((AutoSyncedAddon) PocketAddon.REGISTRY.get(buf.readIdentifier()).instance()).read(buf));
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return addons;
|
||||
}
|
||||
|
||||
static PacketByteBuf writeAutoSyncedAddonList(PacketByteBuf buf, List<? extends AutoSyncedAddon> addons) throws IOException {
|
||||
buf.writeInt(addons.size());
|
||||
for (AutoSyncedAddon addon : addons) {
|
||||
buf.writeIdentifier(addon.getType().identifier());
|
||||
addon.write(buf);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
// you can generally use PacketByteBuf#readCompoundTag for reading
|
||||
AutoSyncedAddon read(PacketByteBuf buf) throws IOException;
|
||||
|
||||
// you can generally use PacketByteBuf#writeCompoundTag for writing
|
||||
PacketByteBuf write(PacketByteBuf buf) throws IOException;
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type.addon;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
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.BlockPos;
|
||||
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.util.EntityUtils;
|
||||
import org.dimdev.dimdoors.world.pocket.type.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.PocketColor;
|
||||
import org.dimdev.dimdoors.world.pocket.type.PrivatePocket;
|
||||
|
||||
public class DyeableAddon implements PocketAddon {
|
||||
public static Identifier ID = new Identifier("dimdoors", "dyeable");
|
||||
|
||||
private static final int BLOCKS_PAINTED_PER_DYE = 1000000;
|
||||
|
||||
protected PocketColor dyeColor = PocketColor.WHITE;
|
||||
private PocketColor nextDyeColor = PocketColor.NONE;
|
||||
private int count = 0;
|
||||
|
||||
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 Math.max((outerVolume - innerVolume) / BLOCKS_PAINTED_PER_DYE, 1);
|
||||
}
|
||||
|
||||
private void repaint(Pocket pocket, DyeColor dyeColor) {
|
||||
ServerWorld serverWorld = DimensionalDoorsInitializer.getWorld(pocket.getWorld());
|
||||
BlockState innerWall = ModBlocks.fabricFromDye(dyeColor).getDefaultState();
|
||||
BlockState outerWall = ModBlocks.ancientFabricFromDye(dyeColor).getDefaultState();
|
||||
|
||||
BlockPos.stream(pocket.getBox()).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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean addDye(Pocket pocket, Entity entity, DyeColor dyeColor) {
|
||||
PocketColor color = PocketColor.from(dyeColor);
|
||||
|
||||
int maxDye = amountOfDyeRequiredToColor(pocket);
|
||||
|
||||
if (this.dyeColor == color) {
|
||||
EntityUtils.chat(entity, new TranslatableText("dimdoors.pockets.dyeAlreadyAbsorbed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.nextDyeColor != PocketColor.NONE && this.nextDyeColor == color) {
|
||||
if (this.count + 1 > maxDye) {
|
||||
repaint(pocket, dyeColor);
|
||||
this.dyeColor = color;
|
||||
this.nextDyeColor = PocketColor.NONE;
|
||||
this.count = 0;
|
||||
EntityUtils.chat(entity, new TranslatableText("dimdoors.pocket.pocketHasBeenDyed", dyeColor));
|
||||
} else {
|
||||
this.count++;
|
||||
EntityUtils.chat(entity, new TranslatableText("dimdoors.pocket.remainingNeededDyes", this.count, maxDye, color));
|
||||
}
|
||||
} else {
|
||||
this.nextDyeColor = color;
|
||||
this.count = 1;
|
||||
EntityUtils.chat(entity, new TranslatableText("dimdoors.pocket.remainingNeededDyes", this.count, maxDye, color));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applicable(Pocket pocket) {
|
||||
return pocket instanceof PrivatePocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketAddon fromTag(CompoundTag tag) {
|
||||
|
||||
this.dyeColor = PocketColor.from(tag.getInt("dyeColor"));
|
||||
this.nextDyeColor = PocketColor.from(tag.getInt("nextDyeColor"));
|
||||
this.count = tag.getInt("count");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
PocketAddon.super.toTag(tag);
|
||||
|
||||
tag.putInt("dyeColor", this.dyeColor.getId());
|
||||
tag.putInt("nextDyeColor", this.nextDyeColor.getId());
|
||||
tag.putInt("count", this.count);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketAddonType<? extends PocketAddon> getType() {
|
||||
return PocketAddonType.DYEABLE_ADDON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public interface DyeablePocketBuilder<T extends Pocket.PocketBuilder<T, ?>> extends PocketBuilderExtension<T> {
|
||||
default T dyeColor(PocketColor dyeColor) {
|
||||
|
||||
this.<DyeableBuilderAddon>getAddon(ID).dyeColor = dyeColor;
|
||||
|
||||
return getSelf();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DyeableBuilderAddon implements PocketBuilderAddon<DyeableAddon> {
|
||||
|
||||
private PocketColor dyeColor = PocketColor.NONE;
|
||||
// TODO: add some Pocket#init so that we can have boolean shouldRepaintOnInit
|
||||
|
||||
@Override
|
||||
public void apply(Pocket pocket) {
|
||||
DyeableAddon addon = new DyeableAddon();
|
||||
addon.dyeColor = dyeColor;
|
||||
pocket.addAddon(addon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketBuilderAddon<DyeableAddon> fromTag(CompoundTag tag) {
|
||||
this.dyeColor = PocketColor.from(tag.getInt("dye_color"));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
PocketBuilderAddon.super.toTag(tag);
|
||||
|
||||
tag.putInt("dye_color", dyeColor.getId());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketAddonType<DyeableAddon> getType() {
|
||||
return PocketAddonType.DYEABLE_ADDON;
|
||||
}
|
||||
}
|
||||
|
||||
public interface DyeablePocket extends IHasAddon {
|
||||
default boolean addDye(Entity entity, DyeColor dyeColor) {
|
||||
ensureIsPocket();
|
||||
if (!this.hasAddon(ID)) {
|
||||
DyeableAddon addon = new DyeableAddon();
|
||||
this.addAddon(addon);
|
||||
return addon.addDye((Pocket) this, entity, dyeColor);
|
||||
}
|
||||
return this.<DyeableAddon>getAddon(ID).addDye((Pocket) this, entity, dyeColor);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type.addon;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.DyeColor;
|
||||
import org.dimdev.dimdoors.world.pocket.type.Pocket;
|
||||
|
||||
public interface DyeablePocket extends PocketAddon<DyeablePocket> {
|
||||
|
||||
void setDyeColor(Pocket.PocketColor dyeColor);
|
||||
|
||||
boolean addDye(Entity entity, DyeColor dyeColor);
|
||||
|
||||
interface DyeablePocketBuilder<T extends Pocket.PocketBuilder<T, ? extends DyeablePocket>> extends PocketBuilderExtension<T, DyeablePocket> {
|
||||
default public T dyeColor(Pocket.PocketColor dyeColor) {
|
||||
|
||||
this.getAddon(DyeableBuilderAddon.class).dyeColor = dyeColor;
|
||||
|
||||
return getSelf();
|
||||
}
|
||||
}
|
||||
|
||||
class DyeableBuilderAddon implements PocketBuilderAddon<DyeablePocket> {
|
||||
private Pocket.PocketColor dyeColor = Pocket.PocketColor.NONE;
|
||||
|
||||
@Override
|
||||
public void apply(DyeablePocket pocket) {
|
||||
pocket.setDyeColor(dyeColor);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type.addon;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.dimdev.dimdoors.world.pocket.type.Pocket;
|
||||
|
||||
public interface IHasAddon {
|
||||
<C extends PocketAddon> C getAddon(Identifier id);
|
||||
|
||||
boolean hasAddon(Identifier id);
|
||||
|
||||
<C extends PocketAddon> boolean addAddon(C addon);
|
||||
|
||||
default void ensureIsPocket() {
|
||||
if (! (this instanceof Pocket)) throw new UnsupportedOperationException("Cannot apply pocket addons to non Pocket Object.");
|
||||
}
|
||||
}
|
|
@ -1,19 +1,131 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type.addon;
|
||||
|
||||
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.world.pocket.type.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.blockbreak.BlockBreakContainer;
|
||||
|
||||
public interface PocketAddon<A extends PocketAddon<A>> {
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
interface PocketBuilderExtension<T extends Pocket.PocketBuilder<T, ?>, P extends PocketAddon<P>> {
|
||||
<C extends PocketAddon.PocketBuilderAddon<P>, P extends PocketAddon<P>> C getAddon(Class<C> addonClass);
|
||||
public interface PocketAddon {
|
||||
Registry<PocketAddonType<? extends PocketAddon>> REGISTRY = FabricRegistryBuilder.from(new SimpleRegistry<PocketAddonType<? extends PocketAddon>>(RegistryKey.ofRegistry(new Identifier("dimdoors", "pocket_applicable_addon_type")), Lifecycle.stable())).buildAndRegister();
|
||||
|
||||
void initAddons();
|
||||
static PocketAddon deserialize(CompoundTag tag) {
|
||||
Identifier id = Identifier.tryParse(tag.getString("type")); // TODO: NONE PocketAddon type;
|
||||
return REGISTRY.get(id).fromTag(tag);
|
||||
}
|
||||
|
||||
static PocketBuilderAddon<?> deserializeBuilder(CompoundTag tag) {
|
||||
Identifier id = Identifier.tryParse(tag.getString("type")); // TODO: NONE PocketAddon type;
|
||||
return REGISTRY.get(id).builderAddonInstance().fromTag(tag);
|
||||
}
|
||||
|
||||
static CompoundTag serialize(PocketAddon addon) {
|
||||
return addon.toTag(new CompoundTag());
|
||||
}
|
||||
|
||||
|
||||
default boolean applicable(Pocket pocket) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PocketAddon fromTag(CompoundTag tag);
|
||||
|
||||
default CompoundTag toTag(CompoundTag tag) {
|
||||
return this.getType().toTag(tag);
|
||||
}
|
||||
|
||||
PocketAddonType<? extends PocketAddon> getType();
|
||||
|
||||
Identifier getId();
|
||||
|
||||
default void addAddon(Map<Identifier, PocketAddon> addons) {
|
||||
addons.put(getId(), this);
|
||||
}
|
||||
|
||||
interface PocketBuilderExtension<T extends Pocket.PocketBuilder<T, ?>> {
|
||||
public <C extends PocketBuilderAddon<?>> C getAddon(Identifier id);
|
||||
|
||||
T getSelf();
|
||||
}
|
||||
|
||||
interface PocketBuilderAddon<T extends PocketAddon> {
|
||||
default boolean applicable(Pocket.PocketBuilder<?, ?> builder) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void apply(T pocket);
|
||||
// makes it possible for addons themselves to control how they are added
|
||||
default void addAddon(Map<Identifier, PocketBuilderAddon<?>> addons) {
|
||||
addons.put(getId(), this);
|
||||
}
|
||||
|
||||
void apply(Pocket pocket);
|
||||
|
||||
Identifier getId();
|
||||
|
||||
PocketBuilderAddon<T> fromTag(CompoundTag tag);
|
||||
|
||||
default CompoundTag toTag(CompoundTag tag) {
|
||||
return this.getType().toTag(tag);
|
||||
}
|
||||
|
||||
PocketAddonType<T> getType();
|
||||
}
|
||||
|
||||
interface PocketAddonType<T extends PocketAddon> {
|
||||
PocketAddonType<DyeableAddon> DYEABLE_ADDON = register(DyeableAddon.ID, DyeableAddon::new, DyeableAddon.DyeableBuilderAddon::new);
|
||||
PocketAddonType<PreventBlockModificationAddon> PREVENT_BLOCK_MODIFICATION_ADDON = register(PreventBlockModificationAddon.ID, PreventBlockModificationAddon::new, PreventBlockModificationAddon.PreventBlockModificationBuilderAddon::new);
|
||||
PocketAddonType<BlockBreakContainer> BLOCK_BREAK_CONTAINER = register(BlockBreakContainer.ID, BlockBreakContainer::new, null);
|
||||
|
||||
|
||||
T fromTag(CompoundTag tag);
|
||||
|
||||
CompoundTag toTag(CompoundTag tag);
|
||||
|
||||
T instance();
|
||||
|
||||
PocketBuilderAddon<T> builderAddonInstance();
|
||||
|
||||
Identifier identifier();
|
||||
|
||||
static void register() {
|
||||
}
|
||||
|
||||
static <U extends PocketAddon> PocketAddonType<U> register(Identifier id, Supplier<U> supplier, Supplier<PocketBuilderAddon<U>> addonSupplier) {
|
||||
return Registry.register(REGISTRY, id, new PocketAddonType<U>() {
|
||||
@Override
|
||||
public U fromTag(CompoundTag tag) {
|
||||
return (U) supplier.get().fromTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag.putString("type", id.toString());
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public U instance() {
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketBuilderAddon<U> builderAddonInstance() {
|
||||
if (addonSupplier == null) return null;
|
||||
return addonSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier identifier() {
|
||||
return id;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package org.dimdev.dimdoors.world.pocket.type.addon;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.event.UseItemOnBlockCallback;
|
||||
import org.dimdev.dimdoors.world.pocket.type.Pocket;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PreventBlockModificationAddon implements AutoSyncedAddon, AttackBlockCallback, PlayerBlockBreakEvents.Before, UseItemOnBlockCallback {
|
||||
public static Identifier ID = new Identifier("dimdoors", "prevent_block_modification");
|
||||
|
||||
//AttackBlockCallback
|
||||
@Override
|
||||
public ActionResult interact(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) {
|
||||
if (player.isCreative()) return ActionResult.PASS;
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, BlockEntity blockEntity) {
|
||||
if (player.isCreative()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult useItemOnBlock(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
|
||||
if (player.isCreative()) return ActionResult.PASS;
|
||||
if (player.getStackInHand(hand).getItem() instanceof BlockItem) {
|
||||
BlockPos blockPos = hitResult.getBlockPos();
|
||||
BlockState blockState = world.getBlockState(blockPos);
|
||||
ActionResult result = blockState.onUse(world, player, hand, hitResult);
|
||||
if (result.isAccepted()) return result;
|
||||
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoSyncedAddon read(PacketByteBuf buf) throws IOException {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketByteBuf write(PacketByteBuf buf) throws IOException {
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketAddon fromTag(CompoundTag tag) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketAddonType<? extends PocketAddon> getType() {
|
||||
return PocketAddonType.PREVENT_BLOCK_MODIFICATION_ADDON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public static class PreventBlockModificationBuilderAddon implements PocketBuilderAddon<PreventBlockModificationAddon> {
|
||||
|
||||
@Override
|
||||
public void apply(Pocket pocket) {
|
||||
pocket.addAddon(new PreventBlockModificationAddon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketBuilderAddon<PreventBlockModificationAddon> fromTag(CompoundTag tag) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PocketAddonType<PreventBlockModificationAddon> getType() {
|
||||
return PocketAddonType.PREVENT_BLOCK_MODIFICATION_ADDON;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"builder": "dimdoors:private_pocket",
|
||||
"builder": {
|
||||
"type": "dimdoors:private_pocket"
|
||||
},
|
||||
"width": "5 + 16 * private_size",
|
||||
"length": "5 + 16 * private_size",
|
||||
"type": "dimdoors:void",
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"DefaultBiomeFeaturesMixin",
|
||||
"ExtendedServerPlayNetworkhandlerMixin",
|
||||
"PlayerEntityMixin",
|
||||
"RecipesProviderAccessor",
|
||||
"RegistryKeyMixin",
|
||||
"ServerPlayerEntityMixin",
|
||||
"ServerPlayerInteractionManagerMixin",
|
||||
"accessor.BuiltinBiomesAccessor",
|
||||
"accessor.ChunkGeneratorAccessor",
|
||||
"accessor.ChunkGeneratorSettingsAccessor",
|
||||
|
@ -19,7 +21,9 @@
|
|||
"accessor.StatsAccessor"
|
||||
],
|
||||
"client": [
|
||||
"client.ClientPlayerInteractionManagerMixin",
|
||||
"client.ClientPlayNetworkHandlerMixin",
|
||||
"client.ExtendedClientPlayNetworkHandlerMixin",
|
||||
"client.InGameHudMixin",
|
||||
"client.accessor.GlStateManagerAccessor"
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue