diff --git a/gradle.properties b/gradle.properties index 5cf811f..957400f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx8G org.gradle.daemon=false -my_version=1.3.2.2 +my_version=1.3.3.0 mc_version=1.19.2 forge_version=43.1.32 diff --git a/src/main/java/dev/zontreck/otemod/OTEMod.java b/src/main/java/dev/zontreck/otemod/OTEMod.java index cd490be..74ef349 100644 --- a/src/main/java/dev/zontreck/otemod/OTEMod.java +++ b/src/main/java/dev/zontreck/otemod/OTEMod.java @@ -13,6 +13,7 @@ import java.util.Set; import com.mojang.logging.LogUtils; import com.mojang.serialization.Codec; +import net.minecraft.client.gui.screens.MenuScreens; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -54,6 +55,9 @@ import dev.zontreck.otemod.configs.Profile; import dev.zontreck.otemod.database.Database; import dev.zontreck.otemod.database.Database.DatabaseConnectionException; import dev.zontreck.otemod.events.EventHandler; +import dev.zontreck.otemod.implementation.VaultScreen; +import dev.zontreck.otemod.implementation.VaultWatcher; +import dev.zontreck.otemod.implementation.inits.MenuInitializer; import dev.zontreck.otemod.items.ModItems; import dev.zontreck.otemod.ore.Modifier.ModifierOfBiomes; @@ -98,6 +102,8 @@ public class OTEMod MinecraftForge.EVENT_BUS.register(new EventHandler()); MinecraftForge.EVENT_BUS.register(new ChatServerOverride()); MinecraftForge.EVENT_BUS.register(new CommandRegistry()); + MinecraftForge.EVENT_BUS.register(new VaultWatcher()); + MenuInitializer.CONTAINERS.register(bus); ModBlocks.register(bus); ModItems.register(bus); @@ -206,6 +212,11 @@ public class OTEMod "`prefix_color` varchar(255) not null,"+ "`chat_color` varchar(255) not null)"); + lookup.execute("CREATE TABLE IF NOT EXISTS `vaults` (" + + "`uuid` varchar (128) NOT NULL, " + + "`number` int (11) not null," + + "`data` text not null);"); + con.endRequest(); // Set up the repeating task to expire a TeleportContainer @@ -313,6 +324,8 @@ public class OTEMod // Some client setup code //LOGGER.info("HELLO FROM CLIENT SETUP"); //LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName()); + + MenuScreens.register(MenuInitializer.VAULT.get(), VaultScreen::new); } } diff --git a/src/main/java/dev/zontreck/otemod/commands/teleport/TeleportActioner.java b/src/main/java/dev/zontreck/otemod/commands/teleport/TeleportActioner.java index 2faa025..3f3c1f0 100644 --- a/src/main/java/dev/zontreck/otemod/commands/teleport/TeleportActioner.java +++ b/src/main/java/dev/zontreck/otemod/commands/teleport/TeleportActioner.java @@ -20,8 +20,11 @@ public class TeleportActioner public void run(){ MobEffectInstance inst = new MobEffectInstance(MobEffects.DARKNESS, 200, 1, true, true); - MobEffectInstance regen = new MobEffectInstance(MobEffects.REGENERATION, 200, 1, true, true); - MobEffectInstance invul = new MobEffectInstance(MobEffects.LEVITATION, 75, 1, true, true); + MobEffectInstance regen = new MobEffectInstance(MobEffects.REGENERATION, 200, 2, true, true); + + // 10-05-2022 - Adjusted to 100 on duration due to a small issue where it would sometimes stop levitation prior to the teleport taking effect. + // Small tradeoff is the player now levitates slightly longer at the destination. This is acceptable. Compensated by increasing regen strength by 1 + MobEffectInstance invul = new MobEffectInstance(MobEffects.LEVITATION, 100, 1, true, true); player.addEffect(inst); diff --git a/src/main/java/dev/zontreck/otemod/commands/vaults/VaultCommand.java b/src/main/java/dev/zontreck/otemod/commands/vaults/VaultCommand.java index 3cf54a6..723766e 100644 --- a/src/main/java/dev/zontreck/otemod/commands/vaults/VaultCommand.java +++ b/src/main/java/dev/zontreck/otemod/commands/vaults/VaultCommand.java @@ -1,14 +1,37 @@ package dev.zontreck.otemod.commands.vaults; +import java.util.UUID; + +import javax.annotation.Nullable; + import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.IntegerArgumentType; import dev.zontreck.otemod.chat.ChatColor; import dev.zontreck.otemod.chat.ChatServerOverride; -import dev.zontreck.otemod.containers.VaultContainer; +import dev.zontreck.otemod.implementation.VaultContainer; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; +import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.CompoundContainer; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.SimpleMenuProvider; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ChestMenu; +import net.minecraft.world.inventory.MenuConstructor; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.entity.ChestBlockEntity; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.PlayerContainerEvent; +import net.minecraftforge.network.NetworkConstants; +import net.minecraftforge.network.NetworkHooks; +import net.minecraftforge.network.PlayMessages; public class VaultCommand { @@ -24,10 +47,17 @@ public class VaultCommand { } private static int vault(CommandSourceStack source, int i) { - VaultContainer cont = new VaultContainer(i, source.getPlayer().getUUID()); - cont.startOpen(source.getPlayer()); - - ChatServerOverride.broadcastTo(source.getPlayer().getUUID(), Component.literal(ChatColor.DARK_RED + "Vaults are not yet implemented"), source.getServer()); + //VaultContainer cont = new VaultContainer(i, source.getPlayer().getUUID()); + //cont.startOpen(source.getPlayer()); + + VaultContainer container = new VaultContainer(source.getPlayer(), i); + + NetworkHooks.openScreen(source.getPlayer(), new SimpleMenuProvider(container.serverMenu, Component.literal("Vault "+i))); + + // Add to the master vault registry + if(VaultContainer.VAULT_REGISTRY.containsKey(source.getPlayer().getUUID()))VaultContainer.VAULT_REGISTRY.remove(source.getPlayer().getUUID()); + VaultContainer.VAULT_REGISTRY.put(source.getPlayer().getUUID(), container); + return 0; } } diff --git a/src/main/java/dev/zontreck/otemod/containers/VaultContainer.java b/src/main/java/dev/zontreck/otemod/containers/VaultContainer.java deleted file mode 100644 index f974ee8..0000000 --- a/src/main/java/dev/zontreck/otemod/containers/VaultContainer.java +++ /dev/null @@ -1,87 +0,0 @@ -package dev.zontreck.otemod.containers; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import net.minecraft.world.Container; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.Vec3; - -public class VaultContainer implements Container -{ - public int VaultID; - public UUID VaultOwner; - public ItemStack[] Contents=new ItemStack[64]; - - public VaultContainer(int num, UUID owner) - { - VaultID = num; - VaultOwner = owner; - Contents = new ItemStack[64]; - } - - @Override - public void clearContent() { - for(int i=0; i< Contents.length; i++) - { - Contents[i] = null; - } - } - - @Override - public int getContainerSize() { - return 64; // Double chest - } - - @Override - public boolean isEmpty() { - for(ItemStack is : Contents) - { - if(is == null)continue; - else return false; - } - return true; - } - - @Override - public ItemStack getItem(int p_18941_) { - return Contents[p_18941_]; - } - - @Override - public ItemStack removeItem(int p_18942_, int p_18943_) { - // TODO debug this! - return null; - } - - @Override - public ItemStack removeItemNoUpdate(int p_18951_) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setItem(int p_18944_, ItemStack p_18945_) { - Contents[p_18944_] = p_18945_; - setChanged(); // mark the contents to be uploaded to the server - } - - @Override - public void setChanged() { - // Enqueue upload to the database - } - - @Override - public boolean stillValid(Player p_18946_) { - return true; // The inventory is always valid for this container type. There is no circumstance where the container could be destroyed. - } - - public void downloadContentsToChest(Vec3 pos) - { - // Player is standing on a chest and wants us to download the vault into the chest. - // TODO - } - -} diff --git a/src/main/java/dev/zontreck/otemod/implementation/VaultContainer.java b/src/main/java/dev/zontreck/otemod/implementation/VaultContainer.java new file mode 100644 index 0000000..ac238ee --- /dev/null +++ b/src/main/java/dev/zontreck/otemod/implementation/VaultContainer.java @@ -0,0 +1,97 @@ +package dev.zontreck.otemod.implementation; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.mariadb.jdbc.export.Prepare; + +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import dev.zontreck.otemod.OTEMod; +import dev.zontreck.otemod.chat.ChatColor; +import dev.zontreck.otemod.chat.ChatServerOverride; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.network.chat.Component; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.CompoundContainer; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.inventory.MenuConstructor; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraftforge.items.ItemStackHandler; + +public class VaultContainer +{ + public static Map VAULT_REGISTRY = new HashMap<>(); + public VaultMenu theContainer; + public ItemStackHandler myInventory; + public MenuConstructor serverMenu; + public UUID owner; + private MinecraftServer server; + private final int VAULT_NUMBER; + public final UUID VaultID; + public VaultContainer(ServerPlayer player, int vaultNum) { + myInventory = new ItemStackHandler(54); // Vaults have a fixed size at the same as a double chest + theContainer = new VaultMenu(player.containerCounter+1, player.getInventory(), myInventory, BlockPos.ZERO); + VaultID = theContainer.VaultMenuID; + owner = player.getUUID(); + server=player.server; + serverMenu = theContainer.getServerMenu(myInventory); + VAULT_NUMBER=vaultNum; + + + Connection con = OTEMod.DB.getConnection(); + // Check database for vault + + PreparedStatement pstat; + try { + con.beginRequest(); + pstat = con.prepareStatement("SELECT * FROM `vaults` WHERE `uuid`=? AND `number`=?;"); + pstat.setString(1, player.getStringUUID()); + pstat.setInt(2, vaultNum); + + ResultSet rs = pstat.executeQuery(); + while(rs.next()) + { + // We have a vault, deserialize the container + String data = rs.getString("data"); + CompoundTag inv = NbtUtils.snbtToStructure(data); + myInventory.deserializeNBT(inv); + } + con.endRequest(); + } catch (SQLException | CommandSyntaxException e) { + e.printStackTrace(); + } + // Container is now ready to be sent to the client! + } + + public void commit() + { + CompoundTag saved = myInventory.serializeNBT(); + ChatServerOverride.broadcastToAbove(owner, Component.literal(ChatColor.BOLD+ChatColor.DARK_GREEN+"Saving the vault's contents..."), server); + + String toSave= NbtUtils.structureToSnbt(saved); + + Connection con = OTEMod.DB.getConnection(); + try{ + con.beginRequest(); + PreparedStatement ps = con.prepareStatement("REPLACE INTO `vaults` (uuid, number, data) VALUES (?,?,?);"); + ps.setString(1, owner.toString()); + ps.setInt(2, VAULT_NUMBER); + ps.setString(3, toSave); + + ps.execute(); + con.endRequest(); + }catch(SQLException e){ + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/dev/zontreck/otemod/implementation/VaultMenu.java b/src/main/java/dev/zontreck/otemod/implementation/VaultMenu.java new file mode 100644 index 0000000..d07059c --- /dev/null +++ b/src/main/java/dev/zontreck/otemod/implementation/VaultMenu.java @@ -0,0 +1,110 @@ +package dev.zontreck.otemod.implementation; + +import java.util.Map; +import java.util.UUID; + +import dev.zontreck.otemod.chat.HoverTip; +import dev.zontreck.otemod.implementation.inits.MenuInitializer; +import net.minecraft.core.BlockPos; +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.MenuConstructor; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.SlotItemHandler; + +public class VaultMenu extends AbstractContainerMenu +{ + //private final ContainerLevelAccess containerAccess; + public final UUID VaultMenuID; + + public VaultMenu (int id, Inventory player) + { + this(id, player, new ItemStackHandler(54), BlockPos.ZERO); + } + + public VaultMenu (int id, Inventory player, IItemHandler slots, BlockPos pos) + { + super(MenuInitializer.VAULT.get(), id); + VaultMenuID=UUID.randomUUID(); + //this.containerAccess = ContainerLevelAccess.create(player.player.level, pos); + + final int slotSize = 16; + final int startX = 17; + final int startY = 133; + final int hotbarY = 184; + final int inventoryY = 26; + + for (int row = 0; row < 6; row++) + { + for (int column = 0; column < 9; column++) + { + addSlot(new SlotItemHandler(slots, row*9 + column, startX+column * slotSize , inventoryY + row * slotSize)); + } + } + + for (int row=0;row<3;row++) + { + for(int col = 0; col< 9; col++) + { + addSlot(new Slot(player, 9+row * 9 + col, startX + col * slotSize, startY + row * slotSize)); + } + } + + for(int col = 0; col<9; col++) + { + addSlot(new Slot(player, col, startX + col * slotSize, hotbarY)); + } + } + + @Override + public ItemStack quickMoveStack(Player play, int index) { + ItemStack ret = ItemStack.EMPTY; + final Slot slot = getSlot(index); + if(slot.hasItem()){ + final ItemStack item = slot.getItem(); + ret = item.copy(); + if(index<27) + { + if(!moveItemStackTo(item, 54, this.slots.size(), true)) return ItemStack.EMPTY; + }else if(!moveItemStackTo(item, 0, 54, false)); + + if(item.isEmpty()){ + slot.set(ItemStack.EMPTY); + }else slot.setChanged(); + } + + return ret; + } + + @Override + public boolean stillValid(Player p_38874_) { + return true; // We have no block + } + + public static MenuConstructor getServerMenu (ItemStackHandler inventory){ + return (id, player, play) -> new VaultMenu(id, player, inventory, BlockPos.ZERO); + } + + + public void doCommitAction() + { + + // Locate the Vault in the Vault Registry and commit changes. + // Search for myself! + for(Map.Entry e : VaultContainer.VAULT_REGISTRY.entrySet()) + { + if(e.getValue().VaultID.equals(VaultMenuID)) + { + e.getValue().commit(); + } + } + } + +} diff --git a/src/main/java/dev/zontreck/otemod/implementation/VaultScreen.java b/src/main/java/dev/zontreck/otemod/implementation/VaultScreen.java new file mode 100644 index 0000000..181895b --- /dev/null +++ b/src/main/java/dev/zontreck/otemod/implementation/VaultScreen.java @@ -0,0 +1,63 @@ +package dev.zontreck.otemod.implementation; + +import java.util.UUID; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; + +import dev.zontreck.otemod.OTEMod; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; + +public class VaultScreen extends AbstractContainerScreen +{ + // 176x224 + public final UUID VaultMenuID; + + private static final ResourceLocation TEXTURE = new ResourceLocation(OTEMod.MOD_ID, "textures/gui/vault.png"); + + public VaultScreen(VaultMenu container, Inventory playerInv, Component comp){ + super(container, playerInv, comp); + + this.VaultMenuID = container.VaultMenuID; + this.leftPos = 0; + this.topPos = 0; + + this.imageWidth = 176; + this.imageHeight = 224; + } + + @Override + public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) + { + super.render(stack, mouseX, mouseY, partialTicks); + this.font.draw(stack, this.title, this.leftPos + 17, this.topPos + 15, 0xFFFFFF); + this.font.draw(stack, this.playerInventoryTitle, this.leftPos + 17, this.topPos + 123, 0xFFFFFF); + } + + @Override + protected void init() + { + super.init(); + // This is where custom controls would be added! + } + + @Override + protected void renderBg(PoseStack stack, float mouseX, int mouseY, int partialTicks) + { + renderBackground(stack); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor (1.0f, 1.0f, 1.0f, 1.0f); + RenderSystem.setShaderTexture(0, TEXTURE); + blit(stack, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight); + } + + @Override + protected void renderLabels (PoseStack stack, int mouseX, int mouseY) + { + + } +} diff --git a/src/main/java/dev/zontreck/otemod/implementation/VaultWatcher.java b/src/main/java/dev/zontreck/otemod/implementation/VaultWatcher.java new file mode 100644 index 0000000..89cbac4 --- /dev/null +++ b/src/main/java/dev/zontreck/otemod/implementation/VaultWatcher.java @@ -0,0 +1,38 @@ +package dev.zontreck.otemod.implementation; + +import java.util.Map; +import java.util.UUID; + +import dev.zontreck.otemod.OTEMod; +import net.minecraft.client.gui.components.events.ContainerEventHandler; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.entity.player.PlayerContainerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber(modid=OTEMod.MOD_ID,bus=Mod.EventBusSubscriber.Bus.FORGE) +public class VaultWatcher { + + + @OnlyIn(Dist.DEDICATED_SERVER) + @SubscribeEvent + public void onClosedContainer(PlayerContainerEvent.Close ev) + { + //OTEMod.LOGGER.info("Player closed a container"); + // Player closed the container + // Check if it is a vault Container + if(ev.getContainer() instanceof VaultMenu) + { + // During testing the instance of VaultMenu we get passed back through this method gets a regenerated Vault ID, so our only option is to iterate here and commit a vault based on owner ID + for(Map.Entry entry : VaultContainer.VAULT_REGISTRY.entrySet()){ + if(entry.getKey() == ev.getEntity().getUUID()) + { + entry.getValue().commit(); + } + } + } + } + +} diff --git a/src/main/java/dev/zontreck/otemod/implementation/inits/MenuInitializer.java b/src/main/java/dev/zontreck/otemod/implementation/inits/MenuInitializer.java new file mode 100644 index 0000000..184d214 --- /dev/null +++ b/src/main/java/dev/zontreck/otemod/implementation/inits/MenuInitializer.java @@ -0,0 +1,18 @@ +package dev.zontreck.otemod.implementation.inits; + +import dev.zontreck.otemod.OTEMod; +import dev.zontreck.otemod.implementation.VaultMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public final class MenuInitializer +{ + public static final DeferredRegister> CONTAINERS = DeferredRegister.create(ForgeRegistries.MENU_TYPES, OTEMod.MOD_ID); + + public static final RegistryObject > VAULT = CONTAINERS.register("vault", ()-> new MenuType<>(VaultMenu::new)); + + + private MenuInitializer(){} +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 781ab9b..d62f9a6 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -19,7 +19,7 @@ modId="otemod" #mandatory # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it # ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata # see the associated build.gradle script for how to populate this completely automatically during a build -version="1.3.2.2" #mandatory +version="1.3.3.0" #mandatory # A display name for the mod displayName="OTEMod Resources" #mandatory # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/ diff --git a/src/main/resources/assets/otemod/textures/gui/gui-template.aseprite b/src/main/resources/assets/otemod/textures/gui/gui-template.aseprite new file mode 100644 index 0000000..9d56881 Binary files /dev/null and b/src/main/resources/assets/otemod/textures/gui/gui-template.aseprite differ diff --git a/src/main/resources/assets/otemod/textures/gui/vault.png b/src/main/resources/assets/otemod/textures/gui/vault.png new file mode 100644 index 0000000..ea6861b Binary files /dev/null and b/src/main/resources/assets/otemod/textures/gui/vault.png differ diff --git a/src/main/resources/assets/otemod/textures/gui/vaultmenu.aseprite b/src/main/resources/assets/otemod/textures/gui/vaultmenu.aseprite new file mode 100644 index 0000000..9da8453 Binary files /dev/null and b/src/main/resources/assets/otemod/textures/gui/vaultmenu.aseprite differ