Refactor and rename to Thresholds

This commit is contained in:
zontreck 2024-01-15 22:23:44 -07:00
parent 32a61e7925
commit cd9d548806
568 changed files with 214858 additions and 215029 deletions

View file

@ -0,0 +1,322 @@
package dev.zontreck.thresholds;
import com.mojang.logging.LogUtils;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3;
import dev.zontreck.thresholds.effects.ModEffects;
import dev.zontreck.thresholds.implementation.CreativeModeTabs;
import dev.zontreck.thresholds.implementation.InventoryBackup;
import dev.zontreck.thresholds.implementation.Messages;
import dev.zontreck.thresholds.implementation.PlayerFirstJoinTag;
import dev.zontreck.thresholds.implementation.compressor.CompressionChamberScreen;
import dev.zontreck.thresholds.implementation.vault.*;
import dev.zontreck.thresholds.integrations.KeyBindings;
import dev.zontreck.thresholds.recipe.ModRecipes;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.GameType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.event.entity.item.ItemExpireEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.items.ItemStackHandler;
import org.slf4j.Logger;
import dev.zontreck.thresholds.blocks.ModBlocks;
import dev.zontreck.thresholds.blocks.entity.ModEntities;
import dev.zontreck.thresholds.chat.ChatServerOverride;
import dev.zontreck.thresholds.commands.CommandRegistry;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import dev.zontreck.thresholds.enchantments.ModEnchantments;
import dev.zontreck.thresholds.entities.ModEntityTypes;
import dev.zontreck.thresholds.events.LoreHandlers;
import dev.zontreck.thresholds.implementation.inits.ModMenuTypes;
import dev.zontreck.thresholds.implementation.scrubber.ItemScrubberScreen;
import dev.zontreck.thresholds.implementation.scrubber.MagicalScrubberScreen;
import dev.zontreck.thresholds.items.ModItems;
//import dev.zontreck.otemod.ore.Modifier.ModifierOfBiomes;
import dev.zontreck.thresholds.networking.ModMessages;
// The value here should match an entry in the META-INF/mods.toml file
@Mod(ThresholdsMod.MOD_ID)
public class ThresholdsMod
{
public static final Vector3 ZERO_VECTOR = new Vector3(0,0,0);
// Directly reference a slf4j logger
public static final Logger LOGGER = LogUtils.getLogger();
public static final String MOD_ID = "thresholds";
public static final String MODIFY_BIOMES = "modify_biomes";
public static final ResourceLocation MODIFY_BIOMES_RL = new ResourceLocation(ThresholdsMod.MOD_ID, MODIFY_BIOMES);
//public static List<TeleportContainer> TeleportRegistry = new ArrayList<>();
public static MinecraftServer THE_SERVER;
public static boolean ALIVE=false;
public static boolean HEALER_WAIT=true; // Only on loading finish should this unlock
public static Thread HEALER_THREAD;
public static boolean DEVELOPER=false;
private static Thread MasterThread;
public static String ThresholdsPrefix = "";
public static String ONLY_PLAYER = "";
public static IEventBus bus;
public ThresholdsMod()
{
ThresholdsMod.ThresholdsPrefix = ChatColor.doColors("!dark_gray![!dark_green!!bold!Thresholds!reset!!dark_gray!]!reset!");
ThresholdsMod.ONLY_PLAYER = ChatColor.doColors("!dark_red!Only a player can execute this command");
bus = FMLJavaModLoadingContext.get().getModEventBus();
// Register the setup method for modloading
bus.addListener(this::setup);
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ThresholdsServerConfig.SPEC, "thresholds-server.toml");
// Register ourselves for server and other game events we are interested in
//final DeferredRegister<Codec<? extends BiomeModifier>> serializers = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, OTEMod.MOD_ID);
//serializers.register(bus);
//serializers.register(MODIFY_BIOMES, ModifierOfBiomes::makeCodec);
MinecraftForge.EVENT_BUS.register(this);
MinecraftForge.EVENT_BUS.register(new LoreHandlers());
MinecraftForge.EVENT_BUS.register(new ChatServerOverride());
MinecraftForge.EVENT_BUS.register(new CommandRegistry());
MinecraftForge.EVENT_BUS.register(new VaultWatcher());
MinecraftForge.EVENT_BUS.register(new dev.zontreck.thresholds.zschem.EventHandler());
ModMenuTypes.CONTAINERS.register(bus);
ModBlocks.register(bus);
CreativeModeTabs.REGISTER.register(bus);
ModItems.register(bus);
ModEntities.register(bus);
ModEnchantments.register(bus);
ModEntityTypes.register(bus);
ModRecipes.register(bus);
ModEffects.register(bus);
//MenuInitializer.register(bus);
}
private void setup(final FMLCommonSetupEvent event)
{
ModMessages.register();
}
@SubscribeEvent
public void onGameModeChanged(PlayerEvent.PlayerChangeGameModeEvent event)
{
ServerPlayer player = (ServerPlayer) event.getEntity();
InventoryBackup backup = new InventoryBackup(player, event.getCurrentGameMode());
InventoryBackup restore = new InventoryBackup(player, event.getNewGameMode());
restore.restore();
backup.save();
if(event.getNewGameMode() == GameType.CREATIVE)
{
player.getInventory().clearContent();
return;
}
restore.apply();
}
public static void checkFirstJoin(ServerPlayer p){
try {
Profile prof = Profile.get_profile_of(p.getStringUUID());
ItemStackHandler startKit = StarterProvider.getStarter().getItems();
boolean isEmpty=true;
for(int i = 0;i<startKit.getSlots();i++)
{
ItemStack is = startKit.getStackInSlot(i);
if(!is.is(Items.AIR))
{
isEmpty=false;
}
}
if(isEmpty)return;
PlayerFirstJoinTag tag = PlayerFirstJoinTag.load(prof.NBT);
if(tag == null)
{
tag = PlayerFirstJoinTag.now();
tag.save(prof.NBT);
}else {
Starter data = StarterProvider.getStarter();
if(data.getLastChanged() > tag.LastGiven && ThresholdsServerConfig.GIVE_KIT_EVERY_CHANGE.get())
{
tag = PlayerFirstJoinTag.now();
tag.save(prof.NBT);
}else return;
}
prof.commit();
//p.addTag(OTEMod.FIRST_JOIN_TAG);
ChatHelpers.broadcastTo(p, ChatHelpers.macro(Messages.STARTER_KIT_GIVEN), p.server);
for(int i = 0;i<startKit.getSlots();i++)
{
if(i>=p.getInventory().getContainerSize())
{
break;
} else {
p.getInventory().add(startKit.getStackInSlot(i));
}
}
} catch (UserProfileNotYetExistsException e) {
throw new RuntimeException(e);
} catch (NoMoreVaultException e) {
throw new RuntimeException(e);
}
}
// You can use SubscribeEvent and let the Event Bus discover methods to call
@SubscribeEvent
public void onServerStarting(ServerStartedEvent event)
{
// Changed away from Starting event due to multiple calls
if(ThresholdsMod.ALIVE){
// We were called again?
// Wtf... return
ThresholdsMod.LOGGER.info("/!\\ ALERT /!\\ ServerStartedEvent was called multiple times. This is a bug in MinecraftForge");
return;
}
// Do something when the server starts
//LOGGER.info("HELLO from server starting");
ThresholdsMod.ALIVE=true;
//HealerQueue.Initialize(); // Set up the queue
// Set up the repeating task to expire a TeleportContainer
ThresholdsMod.THE_SERVER = event.getServer();
ThresholdsMod.MasterThread = new Thread(new Runnable(){
public void run()
{
while(ThresholdsMod.ALIVE){
// Check if the teleports have expired
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
//e.printStackTrace();
}
/*Iterator<TeleportContainer> containers = OTEMod.TeleportRegistry.iterator();
while(containers.hasNext())
{
TeleportContainer cont = containers.next();
Component expire = new TextComponent(OTEMod.OTEPrefix + ChatColor.DARK_PURPLE+" Teleport request has expired");
ChatServerOverride.broadcastTo(cont.FromPlayer, expire, OTEMod.THE_SERVER);
ChatServerOverride.broadcastTo(cont.ToPlayer, expire, OTEMod.THE_SERVER);
containers.remove();
}*/
}
ThresholdsMod.LOGGER.info("Tearing down Thresholds teleport queue - The server is going down");
}
});
ThresholdsMod.MasterThread.start();
}
@SubscribeEvent
public void onItemExpire(final ItemExpireEvent ev)
{
if(ev.getEntity().level().isClientSide)return;
if(ThresholdsServerConfig.ITEM_DESPAWN_TIMER.get()<=0)return;
ItemEntity ite = (ItemEntity)ev.getEntity();
if(ite.getAge() != (1200 * 5)) {
//OTEMod.LOGGER.info("Extra life has already been given to item : "+ev.getEntity().getName().getString());
return; // We already gave it extra life, the default is 6000, or 5 minutes
}
//OTEMod.LOGGER.info("Giving extra life to item : "+ev.getEntity().getName().getString() + "; item age [ "+ev.getEntity().getAge()+ " ]");
// 1200 ticks per minute
// OTEMod item despawn amplifier is set in 5 minute intervals
ev.setExtraLife((1200 * 5)+ ((1200 * 5) * ThresholdsServerConfig.ITEM_DESPAWN_TIMER.get())); // reset the life count
//OTEMod.LOGGER.info("Item ["+ev.getEntity().getItem().getDisplayName().getString()+"] was given extra life");
// Hopefully this works?
ev.setCanceled(true);
}
@SubscribeEvent
public void onStop(final ServerStoppingEvent ev)
{
ThresholdsMod.ALIVE=false; // Tear down all looping threads that will watch this
ThresholdsMod.MasterThread.interrupt();
}
// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
@Mod.EventBusSubscriber(modid = ThresholdsMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public static class ClientModEvents
{
@SubscribeEvent
public static void onClientSetup(FMLClientSetupEvent event)
{
// Some client setup code
//LOGGER.info("HELLO FROM CLIENT SETUP");
//LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName());
MinecraftForge.EVENT_BUS.register(new KeyBindings());
MenuScreens.register(ModMenuTypes.VAULT.get(), VaultScreen::new);
MenuScreens.register(ModMenuTypes.SCRUBBER.get(), ItemScrubberScreen::new);
MenuScreens.register(ModMenuTypes.MAGIC_SCRUBBER.get(), MagicalScrubberScreen::new);
MenuScreens.register(ModMenuTypes.COMPRESSION_CHAMBER.get(), CompressionChamberScreen::new);
//ItemBlockRenderTypes.setRenderLayer(ModBlocks.AURORA_DOOR.get(), RenderType.translucent());
//EntityRenderers.register(ModEntityTypes.POSSUM.get(), PossumRenderer::new);
}
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void onRegisterKeybinds(RegisterKeyMappingsEvent ev)
{
ev.register(KeyBindings.OPEN_VAULT);
}
}
}

View file

@ -0,0 +1,23 @@
package dev.zontreck.thresholds.blocks;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.DoorBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.BlockSetType;
public class AuroraDoorBlock extends DoorBlock
{
public static final BlockBehaviour.Properties DOOR_PROPS;
static
{
DOOR_PROPS = BlockBehaviour.Properties.copy(Blocks.IRON_DOOR).requiresCorrectToolForDrops().strength(10, 100000f).sound(SoundType.NETHERITE_BLOCK);
}
public AuroraDoorBlock() {
super(DOOR_PROPS, BlockSetType.IRON);
}
}

View file

@ -0,0 +1,100 @@
package dev.zontreck.thresholds.blocks;
import dev.zontreck.thresholds.blocks.entity.CompressionChamberBlockEntity;
import dev.zontreck.thresholds.blocks.entity.ModEntities;
import dev.zontreck.thresholds.networking.ModMessages;
import dev.zontreck.thresholds.networking.packets.EnergySyncS2CPacket;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.Nullable;
public class CompressionChamberBlock extends HorizontalDirectionalBlock implements EntityBlock
{
public CompressionChamberBlock(Properties pProperties) {
super(pProperties);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
super.createBlockStateDefinition(pBuilder);
pBuilder.add(FACING);
}
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new CompressionChamberBlockEntity(blockPos, blockState);
}
@Override
public RenderShape getRenderShape(BlockState pState) {
return RenderShape.MODEL;
}
@Override
public InteractionResult use(BlockState state, Level lvl, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
if(!lvl.isClientSide())
{
BlockEntity be = lvl.getBlockEntity(pos);
if(be instanceof CompressionChamberBlockEntity)
{
CompressionChamberBlockEntity entity = (CompressionChamberBlockEntity) be;
NetworkHooks.openScreen(((ServerPlayer)player), entity, pos);
ModMessages.sendToPlayer(new EnergySyncS2CPacket(entity.getEnergyStorage().getEnergyStored(), entity.getBlockPos()), (ServerPlayer)player);
}else{
throw new IllegalStateException("Our container is missing!");
}
}
return InteractionResult.sidedSuccess(lvl.isClientSide);
}
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pMovedByPiston) {
if(pState.getBlock() != pNewState.getBlock())
{
BlockEntity be = pLevel.getBlockEntity(pPos);
if(be instanceof CompressionChamberBlockEntity)
{
((CompressionChamberBlockEntity)be).doDrop();
}
}
super.onRemove(pState, pLevel, pPos, pNewState, pMovedByPiston);
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level pLevel, BlockState pState, BlockEntityType<T> pBlockEntityType) {
return createTickerHelper(pBlockEntityType, ModEntities.COMPRESSION_CHAMBER.get(), CompressionChamberBlockEntity::tick);
}
protected static <E extends BlockEntity, A extends BlockEntity> BlockEntityTicker<A> createTickerHelper(BlockEntityType<A> pServerType, BlockEntityType<E> pClientType, BlockEntityTicker<? super E> pTicker) {
return pClientType == pServerType ? (BlockEntityTicker<A>) pTicker : null;
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
return defaultBlockState().setValue(FACING, pContext.getHorizontalDirection());
}
}

View file

@ -0,0 +1,19 @@
package dev.zontreck.thresholds.blocks;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
public class FoiledBlockItem extends BlockItem {
public FoiledBlockItem(Block pBlock, Properties pProperties) {
super(pBlock, pProperties);
// TODO Auto-generated constructor stub
}
@Override
public boolean isFoil(ItemStack pStack) {
return true;
}
}

View file

@ -0,0 +1,101 @@
package dev.zontreck.thresholds.blocks;
import dev.zontreck.thresholds.blocks.entity.ItemScrubberBlockEntity;
import dev.zontreck.thresholds.blocks.entity.ModEntities;
import dev.zontreck.thresholds.networking.ModMessages;
import dev.zontreck.thresholds.networking.packets.EnergySyncS2CPacket;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nullable;
public class ItemScrubberBlock extends HorizontalDirectionalBlock implements EntityBlock
{
public ItemScrubberBlock(Properties p_54120_) {
super(p_54120_);
//registerDefaultState(defaultBlockState().setValue(FACING, Direction.NORTH));
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
super.createBlockStateDefinition(pBuilder);
pBuilder.add(FACING);
}
@Override
public RenderShape getRenderShape(BlockState state)
{
return RenderShape.MODEL;
}
@Override
public void onRemove(BlockState state, Level lvl, BlockPos pos, BlockState newState, boolean isMoving)
{
if(state.getBlock()!=newState.getBlock())
{
BlockEntity bE = lvl.getBlockEntity(pos);
if(bE instanceof ItemScrubberBlockEntity)
{
((ItemScrubberBlockEntity)bE).doDrop();
}
}
super.onRemove(state, lvl, pos, newState, isMoving);
}
@Override
public InteractionResult use(BlockState state, Level lvl, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
if(!lvl.isClientSide())
{
BlockEntity be = lvl.getBlockEntity(pos);
if(be instanceof ItemScrubberBlockEntity)
{
ItemScrubberBlockEntity entity = (ItemScrubberBlockEntity)be;
NetworkHooks.openScreen(((ServerPlayer)player), entity, pos);
ModMessages.sendToPlayer(new EnergySyncS2CPacket(entity.getEnergyStorage().getEnergyStored(), entity.getBlockPos()), (ServerPlayer)player);
}else{
throw new IllegalStateException("Our container is missing!");
}
}
return InteractionResult.sidedSuccess(lvl.isClientSide);
}
@Override
@Nullable
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return new ItemScrubberBlockEntity(pos, state);
}
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level lvl, BlockState state, BlockEntityType<T> type)
{
return createTickerHelper(type, ModEntities.ITEM_SCRUBBER.get(), ItemScrubberBlockEntity::tick);
}
protected static <E extends BlockEntity, A extends BlockEntity> BlockEntityTicker<A> createTickerHelper(BlockEntityType<A> pServerType, BlockEntityType<E> pClientType, BlockEntityTicker<? super E> pTicker) {
return pClientType == pServerType ? (BlockEntityTicker<A>) pTicker : null;
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
return defaultBlockState().setValue(FACING, pContext.getHorizontalDirection().getOpposite());
}
}

View file

@ -0,0 +1,102 @@
package dev.zontreck.thresholds.blocks;
import dev.zontreck.thresholds.blocks.entity.MagicalScrubberBlockEntity;
import dev.zontreck.thresholds.blocks.entity.ModEntities;
import dev.zontreck.thresholds.networking.ModMessages;
import dev.zontreck.thresholds.networking.packets.EnergySyncS2CPacket;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nullable;
public class MagicalScrubberBlock extends HorizontalDirectionalBlock implements EntityBlock
{
public MagicalScrubberBlock(Properties p_54120_) {
super(p_54120_);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
super.createBlockStateDefinition(pBuilder);
pBuilder.add(FACING);
}
@Override
public RenderShape getRenderShape(BlockState state)
{
return RenderShape.MODEL;
}
@Override
public void onRemove(BlockState state, Level lvl, BlockPos pos, BlockState newState, boolean isMoving)
{
if(state.getBlock()!=newState.getBlock())
{
BlockEntity bE = lvl.getBlockEntity(pos);
if(bE instanceof MagicalScrubberBlockEntity)
{
((MagicalScrubberBlockEntity)bE).doDrop();
}
}
super.onRemove(state, lvl, pos, newState, isMoving);
}
@Override
public InteractionResult use(BlockState state, Level lvl, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
if(!lvl.isClientSide())
{
BlockEntity be = lvl.getBlockEntity(pos);
if(be instanceof MagicalScrubberBlockEntity)
{
MagicalScrubberBlockEntity entity = (MagicalScrubberBlockEntity)be;
NetworkHooks.openScreen(((ServerPlayer)player), entity, pos);
ModMessages.sendToPlayer(new EnergySyncS2CPacket(entity.getEnergyStorage().getEnergyStored(), entity.getBlockPos()), (ServerPlayer)player);
}else{
throw new IllegalStateException("Our container is missing!");
}
}
return InteractionResult.sidedSuccess(lvl.isClientSide);
}
@Override
@Nullable
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return new MagicalScrubberBlockEntity(pos, state);
}
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level lvl, BlockState state, BlockEntityType<T> type)
{
return createTickerHelper(type, ModEntities.MAGICAL_SCRUBBER.get(), MagicalScrubberBlockEntity::tick);
}
protected static <E extends BlockEntity, A extends BlockEntity> BlockEntityTicker<A> createTickerHelper(BlockEntityType<A> pServerType, BlockEntityType<E> pClientType, BlockEntityTicker<? super E> pTicker) {
return pClientType == pServerType ? (BlockEntityTicker<A>) pTicker : null;
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
return defaultBlockState().setValue(FACING, pContext.getHorizontalDirection().getOpposite());
}
}

View file

@ -0,0 +1,146 @@
package dev.zontreck.thresholds.blocks;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.CreativeModeTabs;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class ModBlocks {
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, ThresholdsMod.MOD_ID);
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, ThresholdsMod.MOD_ID);
public static void register(IEventBus bus){
BLOCKS.register(bus);
ITEMS.register(bus);
ThresholdsMod.LOGGER.info("Registering all blocks...");
}
public static final RegistryObject<Block> ETERNIUM_ORE_BLOCK = BLOCKS.register("eternium_ore_block", () -> new Block(BlockBehaviour.Properties.of().requiresCorrectToolForDrops().strength(7F).explosionResistance(1200).destroyTime(6)));
public static final RegistryObject<Item> ETERNIUM_ORE_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("eternium_ore_block", () -> new BlockItem(ETERNIUM_ORE_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> VAULT_STEEL_ORE_BLOCK = BLOCKS.register("vault_steel_ore_block", ()->new Block(BlockBehaviour.Properties.of().requiresCorrectToolForDrops().strength(8F).explosionResistance(1200).destroyTime(100)));
public static final RegistryObject<Item> VAULT_STEEL_ORE_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_steel_ore_block", ()->new BlockItem(VAULT_STEEL_ORE_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> NETHER_VAULT_STEEL_ORE_BLOCK = BLOCKS.register("nether_vault_steel_ore_block", ()->new Block(BlockBehaviour.Properties.of().requiresCorrectToolForDrops().strength(8F).explosionResistance(1200).destroyTime(100)));
public static final RegistryObject<Item> NETHER_VAULT_STEEL_ORE_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("nether_vault_steel_ore_block", ()->new BlockItem(NETHER_VAULT_STEEL_ORE_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> ETERNIUM_BLOCK = BLOCKS.register("eternium_block", ()->new Block(BlockBehaviour.Properties.of().requiresCorrectToolForDrops().strength(8F).explosionResistance(1200).destroyTime(100)));
public static final RegistryObject<Item> ETERNIUM_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("eternium_block", ()->new FoiledBlockItem(ETERNIUM_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> DEEPSLATE_ETERNIUM_ORE_BLOCK = BLOCKS.register("deepslate_eternium_ore_block", () -> new Block(BlockBehaviour.Properties.of().requiresCorrectToolForDrops().strength(5f).explosionResistance(1200).destroyTime(7)));
public static final RegistryObject<Item> DEEPSLATE_ETERNIUM_ORE_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("deepslate_eternium_ore_block", () -> new BlockItem(DEEPSLATE_ETERNIUM_ORE_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> AURORA_BLOCK = BLOCKS.register("aurora_block", () -> new Block(BlockBehaviour.Properties.of().requiresCorrectToolForDrops().strength(9f).explosionResistance(100000f).destroyTime(10).sound(SoundType.NETHERITE_BLOCK)));
public static final RegistryObject<Item> AURORA_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("aurora_block", () -> new BlockItem(AURORA_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> AURORA_DOOR = BLOCKS.register("aurora_door", AuroraDoorBlock::new);
public static final RegistryObject<Item> AURORA_DOOR_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("aurora_door", () -> new BlockItem(AURORA_DOOR.get(), new Item.Properties())));
public static final RegistryObject<Block> CLEAR_GLASS_BLOCK = BLOCKS.register("clear_glass_block", () -> new Block(BlockBehaviour.Properties.copy(Blocks.GLASS).strength(1f).destroyTime(6).noOcclusion().isViewBlocking(ModBlocks::never)));
public static final RegistryObject<Item> CLEAR_GLASS_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("clear_glass_block", () -> new BlockItem(CLEAR_GLASS_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> ITEM_SCRUBBER = BLOCKS.register("item_scrubber", ()->new ItemScrubberBlock(BlockBehaviour.Properties.copy(ModBlocks.AURORA_BLOCK.get()).noOcclusion().isViewBlocking(ModBlocks::never)));
public static final RegistryObject<Item> ITEM_SCRUBBER_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("item_scrubber", ()->new BlockItem(ITEM_SCRUBBER.get(), new Item.Properties())));
public static final RegistryObject<Block> MAGICAL_SCRUBBER = BLOCKS.register("magical_scrubber", ()->new MagicalScrubberBlock(BlockBehaviour.Properties.copy(ModBlocks.AURORA_BLOCK.get()).noOcclusion().isViewBlocking(ModBlocks::never)));
public static final RegistryObject<Item> MAGICAL_SCRUBBER_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("magical_scrubber", ()->new BlockItem(MAGICAL_SCRUBBER.get(), new Item.Properties())));
public static final RegistryObject<Block> STABLE_SINGULARITY = BLOCKS.register("stable_singularity", ()->new Block(BlockBehaviour.Properties.copy(ModBlocks.AURORA_BLOCK.get()).noOcclusion().isViewBlocking(ModBlocks::never)));
public static final RegistryObject<Item> STABLE_SINGULARITY_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("stable_singularity", ()->new BlockItem(STABLE_SINGULARITY.get(), new Item.Properties())));
public static final RegistryObject<Block> ILUSIUM_ORE_BLOCK = BLOCKS.register("ilusium_ore_block", () -> new Block(BlockBehaviour.Properties.copy(ModBlocks.ETERNIUM_ORE_BLOCK.get()).noOcclusion()));
public static final RegistryObject<Item> ILUSIUM_ORE_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("ilusium_ore_block", () -> new BlockItem(ILUSIUM_ORE_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> DEEPSLATE_ILUSIUM_ORE_BLOCK = BLOCKS.register("deepslate_ilusium_ore_block", () -> new Block(BlockBehaviour.Properties.copy(ILUSIUM_ORE_BLOCK.get()).noOcclusion()));
public static final RegistryObject<Item> DEEPSLATE_ILUSIUM_ORE_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("deepslate_ilusium_ore_block", () -> new BlockItem(DEEPSLATE_ILUSIUM_ORE_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> ILUSIUM_BLOCK = BLOCKS.register("ilusium_block", () -> new Block(BlockBehaviour.Properties.copy(ModBlocks.ETERNIUM_BLOCK.get()).noOcclusion().strength(5, 20).requiresCorrectToolForDrops()));
public static final RegistryObject<Item> ILUSIUM_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("ilusium_block", () -> new BlockItem(ILUSIUM_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> COMPRESSION_CHAMBER_BLOCK = BLOCKS.register("compression_chamber", ()->new CompressionChamberBlock(BlockBehaviour.Properties.copy(ModBlocks.ILUSIUM_BLOCK.get()).noOcclusion().isViewBlocking(ModBlocks::never)));
public static final RegistryObject<Item> COMPRESSION_CHAMBER_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("compression_chamber", ()->new BlockItem(COMPRESSION_CHAMBER_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> COMPRESSED_OBSIDIAN_BLOCK = BLOCKS.register("compressed_obsidian_block", ()->new Block(BlockBehaviour.Properties.copy(Blocks.OBSIDIAN)));
public static final RegistryObject<Item> COMPRESSED_OBSIDIAN_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("compressed_obsidian_block", ()->new BlockItem(COMPRESSED_OBSIDIAN_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> LAYERED_COMPRESSED_OBSIDIAN_BLOCK = BLOCKS.register("layered_compressed_obsidian_block", ()->new Block(BlockBehaviour.Properties.copy(Blocks.OBSIDIAN)));
public static final RegistryObject<Item> LAYERED_COMPRESSED_OBSIDIAN_BLOCK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("layered_compressed_obsidian_block", ()->new BlockItem(LAYERED_COMPRESSED_OBSIDIAN_BLOCK.get(), new Item.Properties())));
public static final RegistryObject<Block> LIMINAL_TILES = BLOCKS.register("liminal_tiles", ()-> new Block(BlockBehaviour.Properties.copy(Blocks.BEDROCK)));
public static final RegistryObject<Item> LIMINAL_TILES_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("liminal_tiles", ()->new BlockItem(LIMINAL_TILES.get(), new Item.Properties())));
public static final RegistryObject<Block> BLACK = BLOCKS.register("black", ()->new Block(BlockBehaviour.Properties.copy(Blocks.BEDROCK)));
public static final RegistryObject<Item> BLACK_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("black", ()->new FoiledBlockItem(BLACK.get(), new Item.Properties().stacksTo(128))));
public static final RegistryObject<Block> LIMINAL_TILE_STAIRS = BLOCKS.register("liminal_tile_stairs", ()->new StairBlock(LIMINAL_TILES.get()::defaultBlockState, BlockBehaviour.Properties.copy(Blocks.BEDROCK).destroyTime(1000).strength(1000)));
public static final RegistryObject<Item> LIMINAL_TILE_STAIRS_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("liminal_tile_stairs", ()->new BlockItem(LIMINAL_TILE_STAIRS.get(), new Item.Properties())));
public static final RegistryObject<Block> LIMINAL_TILE_SLAB = BLOCKS.register("liminal_tile_slab", ()->new SlabBlock(BlockBehaviour.Properties.copy(Blocks.BEDROCK)));
public static final RegistryObject<Item> LIMINAL_TILE_SLAB_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("liminal_tile_slab", ()->new BlockItem(LIMINAL_TILE_SLAB.get(), new Item.Properties())));
public static final RegistryObject<Block> LIMINAL_WINDOW = BLOCKS.register("liminal_window", () -> new ParallaxWindow(15));
public static final RegistryObject<Item> LIMINAL_WINDOW_I = CreativeModeTabs.addToOTEModTab(ITEMS.register("liminal_window", () -> new BlockItem(LIMINAL_WINDOW.get(), new Item.Properties())));
/*
public static final class_2248 LIMINAL_WINDOW_NOON = (class_2248)createBlock("liminal_window_noon", new LiminalWindowBlock(QuiltBlockSettings.method_9630((class_4970)class_2246.field_31037).method_9626(class_2498.field_11537)), true, (class_1761)ModItems.LIMINAL_POOLS_ITEM_GROUP);
public static final class_2248 LIMINAL_WINDOW_DUSK = (class_2248)createBlock("liminal_window_dusk", new LiminalWindowBlock(QuiltBlockSettings.method_9630((class_4970)class_2246.field_31037).method_9626(class_2498.field_11537)), true, (class_1761)ModItems.LIMINAL_POOLS_ITEM_GROUP);
public static final class_2248 LIMINAL_WINDOW_ABYSS = (class_2248)createBlock("liminal_window_abyss", new LiminalWindowBlock(QuiltBlockSettings.method_9630((class_4970)class_2246.field_31037).method_9626(class_2498.field_11537)), true, (class_1761)ModItems.LIMINAL_POOLS_ITEM_GROUP);*/
private static boolean never(BlockState p_50806_, BlockGetter p_50807_, BlockPos p_50808_) {
return false;
}
}

View file

@ -0,0 +1,28 @@
package dev.zontreck.thresholds.blocks;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
public class ParallaxWindow extends BaseEntityBlock
{
protected static final double OFFSET = 0.0625;
public ParallaxWindow(int light) {
super(Properties.copy(Blocks.BEDROCK).lightLevel(x->light).sound(SoundType.GLASS));
}
@Override
public boolean propagatesSkylightDown(BlockState pState, BlockGetter pReader, BlockPos pPos) {
return true;
}
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return null;
}
}

View file

@ -0,0 +1,309 @@
package dev.zontreck.thresholds.blocks.entity;
import dev.zontreck.thresholds.implementation.OutputItemStackHandler;
import dev.zontreck.thresholds.implementation.compressor.CompressionChamberMenu;
import dev.zontreck.thresholds.implementation.energy.OTEEnergy;
import dev.zontreck.thresholds.networking.ModMessages;
import dev.zontreck.thresholds.networking.packets.EnergySyncS2CPacket;
import dev.zontreck.thresholds.recipe.CompressionChamberRecipe;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.Containers;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.SimpleContainer;
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.ContainerData;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nullable;
import java.util.Optional;
public class CompressionChamberBlockEntity extends BlockEntity implements MenuProvider
{
public CompressionChamberBlockEntity(BlockPos pPos, BlockState pBlockState) {
super(ModEntities.COMPRESSION_CHAMBER.get(), pPos, pBlockState);
outputSlot = new OutputItemStackHandler(outputItems);
data = new ContainerData() {
@Override
public int get(int i) {
return switch (i){
case 0 -> CompressionChamberBlockEntity.this.progress;
default -> 0;
};
}
@Override
public void set(int i, int i1) {
switch(i)
{
case 0->CompressionChamberBlockEntity.this.progress = i1;
}
}
@Override
public int getCount() {
return 1;
}
};
}
protected final ContainerData data;
protected int progress=0;
public static int PROCESSING_TICKS = 80;
protected final ItemStackHandler itemsHandler = new ItemStackHandler(1){
@Override
protected void onContentsChanged(int slot)
{
setChanged();
}
};
protected final ItemStackHandler outputItems = new ItemStackHandler(1){
@Override
protected void onContentsChanged(int slot)
{
setChanged();
}
};
private ItemStackHandler outputSlot;
private final OTEEnergy ENERGY_STORAGE = new OTEEnergy(ENERGY_REQUIREMENT*3, ENERGY_REQUIREMENT*512) {
@Override
public void onChanged() {
setChanged();
ModMessages.sendToAll(new EnergySyncS2CPacket(energy, getBlockPos()));
}
};
private static int ENERGY_REQUIREMENT = 750;
private LazyOptional<IEnergyStorage> lazyEnergyHandler = LazyOptional.empty();
private LazyOptional<IItemHandler> lazyItemHandler = LazyOptional.empty();
private LazyOptional<IItemHandler> lazyOutputItems = LazyOptional.empty();
@Override
public Component getDisplayName() {
return Component.literal("Compression Chamber");
}
@Override
@Nullable
public AbstractContainerMenu createMenu(int id, Inventory inv, Player player) {
return new CompressionChamberMenu(id, inv, this, this.data);
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side)
{
if(cap == ForgeCapabilities.ENERGY)
{
return lazyEnergyHandler.cast();
}
if(side == Direction.DOWN && cap == ForgeCapabilities.ITEM_HANDLER)
{
// Return the output slot only
return lazyOutputItems.cast();
}
if(cap == ForgeCapabilities.ITEM_HANDLER)
{
return lazyItemHandler.cast();
}
return super.getCapability(cap,side);
}
@Override
public void onLoad()
{
super.onLoad();
lazyItemHandler = LazyOptional.of(()->itemsHandler);
lazyOutputItems = LazyOptional.of(()->outputSlot);
lazyEnergyHandler = LazyOptional.of(()->ENERGY_STORAGE);
}
@Override
public void invalidateCaps()
{
super.invalidateCaps();
lazyItemHandler.invalidate();
lazyOutputItems.invalidate();
lazyEnergyHandler.invalidate();
}
@Override
protected void saveAdditional(CompoundTag nbt)
{
nbt.put("inventory", itemsHandler.serializeNBT());
nbt.put("output", outputItems.serializeNBT());
nbt.putInt("prog", progress);
nbt.putInt("energy", ENERGY_STORAGE.getEnergyStored());
super.saveAdditional(nbt);
}
@Override
public void load(CompoundTag nbt){
super.load(nbt);
itemsHandler.deserializeNBT(nbt.getCompound("inventory"));
outputItems.deserializeNBT(nbt.getCompound("output"));
progress = nbt.getInt("prog");
ENERGY_STORAGE.setEnergy(nbt.getInt("energy"));
}
public void doDrop()
{
SimpleContainer cont = new SimpleContainer(itemsHandler.getSlots());
for (int i = 0; i < itemsHandler.getSlots(); i++) {
cont.setItem(i, itemsHandler.getStackInSlot(i));
}
cont = new SimpleContainer(outputItems.getSlots());
for (int i = 0; i < outputItems.getSlots(); i++) {
cont.setItem(i, outputItems.getStackInSlot(i));
}
Containers.dropContents(this.level, this.worldPosition, cont);
}
public static void tick(Level lvl, BlockPos pos, BlockState state, CompressionChamberBlockEntity entity)
{
if(lvl.isClientSide())return;
if(hasRecipe(entity))
{
if(!hasEnergy(entity))return; // Halt until sufficient energy has been received
entity.progress++;
setChanged(lvl, pos, state);
drain(entity);
if(entity.progress >= CompressionChamberBlockEntity.PROCESSING_TICKS)
{
craftItem(entity);
}
}else {
if(entity.progress>0){
entity.resetProgress();
setChanged(lvl, pos, state);
}
}
}
private static void drain(CompressionChamberBlockEntity entity) {
entity.ENERGY_STORAGE.extractEnergy(ENERGY_REQUIREMENT, false);
}
private static boolean hasEnergy(CompressionChamberBlockEntity entity) {
return (entity.ENERGY_STORAGE.getEnergyStored() >= ENERGY_REQUIREMENT);
}
private static void craftItem(CompressionChamberBlockEntity entity) {
if(hasRecipe(entity))
{
SimpleContainer inventory = new SimpleContainer(entity.itemsHandler.getSlots());
for(int i=0;i<entity.itemsHandler.getSlots();i++)
{
inventory.setItem(i, entity.itemsHandler.getStackInSlot(i));
}
SimpleContainer output = new SimpleContainer(entity.outputItems.getSlots());
for(int i=0;i<entity.outputItems.getSlots();i++)
{
output.setItem(i, entity.outputItems.getStackInSlot(i));
}
Optional<CompressionChamberRecipe> recipe = entity.level.getRecipeManager().getRecipeFor(CompressionChamberRecipe.Type.INSTANCE, inventory, entity.level);
ItemStack existing = entity.outputItems.getStackInSlot(0);
if(existing.is(Items.AIR))
{
existing = recipe.get().getResultItem(entity.level.registryAccess());
}else
existing.setCount(recipe.get().getResultItem(entity.level.registryAccess()).getCount() + existing.getCount());
entity.outputItems.setStackInSlot(0, existing);
entity.itemsHandler.extractItem(0,1,false);
entity.resetProgress();
}
}
private static boolean hasRecipe(CompressionChamberBlockEntity entity) {
SimpleContainer inventory = new SimpleContainer(entity.itemsHandler.getSlots());
for(int i=0;i<entity.itemsHandler.getSlots();i++)
{
inventory.setItem(i, entity.itemsHandler.getStackInSlot(i));
}
SimpleContainer output = new SimpleContainer(entity.outputItems.getSlots());
for(int i=0;i<entity.outputItems.getSlots();i++)
{
output.setItem(i, entity.outputItems.getStackInSlot(i));
}
Optional<CompressionChamberRecipe> recipe = entity.level.getRecipeManager().getRecipeFor(CompressionChamberRecipe.Type.INSTANCE, inventory, entity.level);
boolean ret = recipe.isPresent() && canInsertIntoOutput(output, recipe.get().getResultItem(entity.level.registryAccess()));
if(ret)
{
PROCESSING_TICKS = recipe.get().getTime();
}
return ret;
}
private static boolean canInsertIntoOutput(SimpleContainer inventory, ItemStack result) {
ItemStack existing = inventory.getItem(0);
boolean stackCompat = (existing.getMaxStackSize() > existing.getCount());
boolean sameType = (existing.getItem() == result.getItem());
boolean outputEmpty = existing.isEmpty();
if(outputEmpty)return true;
return (stackCompat && sameType);
}
private void resetProgress() {
progress=0;
}
public IEnergyStorage getEnergyStorage() {
return ENERGY_STORAGE;
}
public void setEnergy(int energy) {
ENERGY_STORAGE.setEnergy(energy);
}
}

View file

@ -0,0 +1,292 @@
package dev.zontreck.thresholds.blocks.entity;
import dev.zontreck.thresholds.implementation.OutputItemStackHandler;
import dev.zontreck.thresholds.implementation.energy.OTEEnergy;
import dev.zontreck.thresholds.implementation.scrubber.ItemScrubberMenu;
import dev.zontreck.thresholds.networking.ModMessages;
import dev.zontreck.thresholds.networking.packets.EnergySyncS2CPacket;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.Containers;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.SimpleContainer;
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.ContainerData;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nullable;
public class ItemScrubberBlockEntity extends BlockEntity implements MenuProvider
{
protected final ItemStackHandler itemsHandler = new ItemStackHandler(1){
@Override
protected void onContentsChanged(int slot)
{
setChanged();
}
};
protected final ItemStackHandler outputItems = new ItemStackHandler(1){
@Override
protected void onContentsChanged(int slot)
{
setChanged();
}
};
private ItemStackHandler outputSlot;
private final OTEEnergy ENERGY_STORAGE = new OTEEnergy(ENERGY_REQ*3, ENERGY_REQ+512) {
@Override
public void onChanged() {
setChanged();
ModMessages.sendToAll(new EnergySyncS2CPacket(energy, getBlockPos()));
}
};
private static final int ENERGY_REQ = 1500;
private LazyOptional<IEnergyStorage> lazyEnergyHandler = LazyOptional.empty();
private LazyOptional<IItemHandler> lazyItemHandler = LazyOptional.empty();
private LazyOptional<IItemHandler> lazyOutputItems = LazyOptional.empty();
public ItemScrubberBlockEntity(BlockPos pos, BlockState state) {
super(ModEntities.ITEM_SCRUBBER.get(), pos, state);
outputSlot = new OutputItemStackHandler(outputItems);
this.data = new ContainerData() {
@Override
public int get(int p_39284_) {
return switch(p_39284_){
case 0 -> ItemScrubberBlockEntity.this.progress;
default -> 0;
};
}
@Override
public void set(int p_39285_, int p_39286_) {
switch(p_39285_)
{
case 0 -> ItemScrubberBlockEntity.this.progress = p_39286_;
}
}
@Override
public int getCount() {
return 1;
}
};
}
protected final ContainerData data;
private int progress = 0;
public static final int MAXIMUM_PROCESSING_TICKS = 250;
@Override
@Nullable
public AbstractContainerMenu createMenu(int id, Inventory inv, Player player) {
return new ItemScrubberMenu(id, inv, this, this.data);
}
@Override
public Component getDisplayName() {
return Component.translatable("block.otemod.item_scrubber");
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side)
{
if(cap == ForgeCapabilities.ENERGY)
{
return lazyEnergyHandler.cast();
}
if(side == Direction.DOWN && cap == ForgeCapabilities.ITEM_HANDLER)
{
// Return the output slot only
return lazyOutputItems.cast();
}
if(cap == ForgeCapabilities.ITEM_HANDLER)
{
return lazyItemHandler.cast();
}
return super.getCapability(cap,side);
}
@Override
public void onLoad()
{
super.onLoad();
lazyItemHandler = LazyOptional.of(()->itemsHandler);
lazyOutputItems = LazyOptional.of(()->outputSlot);
lazyEnergyHandler = LazyOptional.of(()->ENERGY_STORAGE);
}
@Override
public void invalidateCaps()
{
super.invalidateCaps();
lazyItemHandler.invalidate();
lazyOutputItems.invalidate();
lazyEnergyHandler.invalidate();
}
@Override
protected void saveAdditional(CompoundTag nbt)
{
nbt.put("inventory", itemsHandler.serializeNBT());
nbt.put("output", outputItems.serializeNBT());
nbt.putInt("prog", progress);
nbt.putInt("energy", ENERGY_STORAGE.getEnergyStored());
super.saveAdditional(nbt);
}
@Override
public void load(CompoundTag nbt){
super.load(nbt);
itemsHandler.deserializeNBT(nbt.getCompound("inventory"));
outputItems.deserializeNBT(nbt.getCompound("output"));
progress = nbt.getInt("prog");
ENERGY_STORAGE.setEnergy(nbt.getInt("energy"));
}
public void doDrop()
{
SimpleContainer cont = new SimpleContainer(itemsHandler.getSlots());
for (int i = 0; i < itemsHandler.getSlots(); i++) {
cont.setItem(i, itemsHandler.getStackInSlot(i));
}
cont = new SimpleContainer(outputItems.getSlots());
for (int i = 0; i < outputItems.getSlots(); i++) {
cont.setItem(i, outputItems.getStackInSlot(i));
}
Containers.dropContents(this.level, this.worldPosition, cont);
}
public static void tick(Level lvl, BlockPos pos, BlockState state, ItemScrubberBlockEntity entity)
{
if(lvl.isClientSide())return;
if(hasRecipe(entity))
{
if(!hasEnergy(entity))return; // Halt until sufficient energy has been received
entity.progress++;
setChanged(lvl, pos, state);
drain(entity);
if(entity.progress >= ItemScrubberBlockEntity.MAXIMUM_PROCESSING_TICKS)
{
craftItem(entity);
}
}else {
if(entity.progress>0){
entity.resetProgress();
setChanged(lvl, pos, state);
}
}
}
private static void drain(ItemScrubberBlockEntity entity) {
entity.ENERGY_STORAGE.extractEnergy(ENERGY_REQ, false);
}
private static boolean hasEnergy(ItemScrubberBlockEntity entity) {
return (entity.ENERGY_STORAGE.getEnergyStored() >= ENERGY_REQ);
}
private static void craftItem(ItemScrubberBlockEntity entity) {
if(hasRecipe(entity))
{
ItemStack existing = entity.outputItems.getStackInSlot(0);
existing.setCount(existing.getCount()+1);
if(existing.is(Items.AIR))
{
existing = makeOutputItem(entity.itemsHandler.getStackInSlot(0));
}
entity.itemsHandler.extractItem(0, 1, false);
entity.outputItems.setStackInSlot(0, existing);
entity.resetProgress();
}
}
private static boolean hasRecipe(ItemScrubberBlockEntity entity) {
SimpleContainer inventory = new SimpleContainer(entity.itemsHandler.getSlots());
for(int i=0;i<entity.itemsHandler.getSlots();i++)
{
inventory.setItem(i, entity.itemsHandler.getStackInSlot(i));
}
SimpleContainer output = new SimpleContainer(entity.outputItems.getSlots());
for(int i=0;i<entity.outputItems.getSlots();i++)
{
output.setItem(i, entity.outputItems.getStackInSlot(i));
}
boolean hasAnItem = !entity.itemsHandler.getStackInSlot(0).isEmpty();
ItemStack result = null;
if(hasAnItem)
{
result = makeOutputItem(entity.itemsHandler.getStackInSlot(0));
}
return hasAnItem && canInsertIntoOutput(output, result);
}
private static boolean canInsertIntoOutput(SimpleContainer inventory, ItemStack result) {
ItemStack existing = inventory.getItem(0);
boolean stackCompat = (existing.getMaxStackSize() > existing.getCount());
boolean sameType = (existing.getItem() == result.getItem());
boolean outputEmpty = existing.isEmpty();
if(outputEmpty)return true;
return (stackCompat && sameType);
}
private void resetProgress() {
progress=0;
}
protected static ItemStack makeOutputItem(ItemStack original)
{
ItemStack newItem = new ItemStack(original.getItem(),1);
return newItem;
}
public IEnergyStorage getEnergyStorage() {
return ENERGY_STORAGE;
}
public void setEnergy(int energy) {
ENERGY_STORAGE.setEnergy(energy);
}
}

View file

@ -0,0 +1,332 @@
package dev.zontreck.thresholds.blocks.entity;
import dev.zontreck.libzontreck.util.ItemUtils;
import dev.zontreck.thresholds.implementation.OutputItemStackHandler;
import dev.zontreck.thresholds.implementation.energy.OTEEnergy;
import dev.zontreck.thresholds.implementation.scrubber.MagicalScrubberMenu;
import dev.zontreck.thresholds.networking.ModMessages;
import dev.zontreck.thresholds.networking.packets.EnergySyncS2CPacket;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.Containers;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.SimpleContainer;
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.ContainerData;
import net.minecraft.world.item.EnchantedBookItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.Map;
public class MagicalScrubberBlockEntity extends BlockEntity implements MenuProvider
{
protected final ItemStackHandler itemsHandler = new ItemStackHandler(1){
@Override
protected void onContentsChanged(int slot)
{
setChanged();
}
};
protected final ItemStackHandler outputItems = new ItemStackHandler(1){
@Override
protected void onContentsChanged(int slot)
{
setChanged();
}
};
private ItemStackHandler outputSlot;
private final OTEEnergy ENERGY_STORAGE = new OTEEnergy(ENERGY_REQ*3, ENERGY_REQ+512) {
@Override
public void onChanged() {
setChanged();
ModMessages.sendToAll(new EnergySyncS2CPacket(energy, getBlockPos()));
}
};
private static final int ENERGY_REQ = 1000;
private LazyOptional<IEnergyStorage> lazyEnergyHandler = LazyOptional.empty();
private LazyOptional<IItemHandler> lazyItemHandler = LazyOptional.empty();
private LazyOptional<IItemHandler> lazyOutputItems = LazyOptional.empty();
public MagicalScrubberBlockEntity(BlockPos pos, BlockState state) {
super(ModEntities.MAGICAL_SCRUBBER.get(), pos, state);
outputSlot = new OutputItemStackHandler(outputItems);
this.data = new ContainerData() {
@Override
public int get(int p_39284_) {
return switch(p_39284_){
case 0 -> MagicalScrubberBlockEntity.this.progress;
default -> 0;
};
}
@Override
public void set(int p_39285_, int p_39286_) {
switch(p_39285_)
{
case 0 -> MagicalScrubberBlockEntity.this.progress = p_39286_;
}
}
@Override
public int getCount() {
return 1;
}
};
}
protected final ContainerData data;
private int progress = 0;
public static final int MAXIMUM_PROCESSING_TICKS = 175;
@Override
@Nullable
public AbstractContainerMenu createMenu(int id, Inventory inv, Player player) {
return new MagicalScrubberMenu(id, inv, this, this.data);
}
@Override
public Component getDisplayName() {
return Component.translatable("block.otemod.magical_scrubber");
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side)
{
if(cap == ForgeCapabilities.ENERGY)
{
return lazyEnergyHandler.cast();
}
if(side == Direction.DOWN && cap == ForgeCapabilities.ITEM_HANDLER)
{
// Return the output slot only
return lazyOutputItems.cast();
}
if(cap == ForgeCapabilities.ITEM_HANDLER)
{
return lazyItemHandler.cast();
}
return super.getCapability(cap,side);
}
@Override
public void onLoad()
{
super.onLoad();
lazyItemHandler = LazyOptional.of(()->itemsHandler);
lazyOutputItems = LazyOptional.of(()->outputSlot);
lazyEnergyHandler = LazyOptional.of(()->ENERGY_STORAGE);
}
@Override
public void invalidateCaps()
{
super.invalidateCaps();
lazyItemHandler.invalidate();
lazyOutputItems.invalidate();
lazyEnergyHandler.invalidate();
}
@Override
protected void saveAdditional(CompoundTag nbt)
{
nbt.put("inventory", itemsHandler.serializeNBT());
nbt.put("output", outputItems.serializeNBT());
nbt.putInt("prog", progress);
nbt.putInt("energy", ENERGY_STORAGE.getEnergyStored());
super.saveAdditional(nbt);
}
@Override
public void load(CompoundTag nbt){
super.load(nbt);
itemsHandler.deserializeNBT(nbt.getCompound("inventory"));
outputItems.deserializeNBT(nbt.getCompound("output"));
progress = nbt.getInt("prog");
ENERGY_STORAGE.setEnergy(nbt.getInt("energy"));
}
public void doDrop()
{
SimpleContainer cont = new SimpleContainer(itemsHandler.getSlots());
for (int i = 0; i < itemsHandler.getSlots(); i++) {
cont.setItem(i, itemsHandler.getStackInSlot(i));
}
cont = new SimpleContainer(outputItems.getSlots());
for (int i = 0; i < outputItems.getSlots(); i++) {
cont.setItem(i, outputItems.getStackInSlot(i));
}
Containers.dropContents(this.level, this.worldPosition, cont);
}
public static void tick(Level lvl, BlockPos pos, BlockState state, MagicalScrubberBlockEntity entity)
{
if(lvl.isClientSide())return;
if(hasRecipe(entity))
{
if(!hasEnergy(entity))return; // Halt until sufficient energy has been received
entity.progress++;
setChanged(lvl, pos, state);
drain(entity);
if(entity.progress >= MagicalScrubberBlockEntity.MAXIMUM_PROCESSING_TICKS)
{
craftItem(entity);
}
}else {
if(entity.progress>0){
entity.resetProgress();
setChanged(lvl, pos, state);
}
}
}
private static void drain(MagicalScrubberBlockEntity entity) {
entity.ENERGY_STORAGE.extractEnergy(ENERGY_REQ, false);
}
private static boolean hasEnergy(MagicalScrubberBlockEntity entity) {
return (entity.ENERGY_STORAGE.getEnergyStored() >= ENERGY_REQ);
}
private static void craftItem(MagicalScrubberBlockEntity entity) {
if(hasRecipe(entity))
{
ItemStack existing = entity.outputItems.getStackInSlot(0);
ItemStack main = entity.itemsHandler.getStackInSlot(0);
//Map<Enchantment, Integer> enchants = main.getAllEnchantments();
Map<Enchantment, Integer> enchantments = ItemUtils.getEnchantments(main.copy());
if(enchantments.size()>0)
{
Iterator<Map.Entry<Enchantment,Integer>> iEntries = enchantments.entrySet().iterator();
try{
Map.Entry<Enchantment,Integer> entry = iEntries.next();
EnchantmentInstance eInst = new EnchantmentInstance(entry.getKey(), entry.getValue());
existing = EnchantedBookItem.createForEnchantment(eInst);
iEntries.remove();
main = makeOutputItem(main.copy());
while(iEntries.hasNext())
{
entry = iEntries.next();
main.enchant(entry.getKey(), entry.getValue());
}
}catch(Exception E)
{
entity.outputItems.setStackInSlot(0, main);
entity.itemsHandler.extractItem(0, 1, false);
entity.resetProgress();
return;
}
if(enchantments.size()==0){
entity.itemsHandler.extractItem(0, 1, false);
}else entity.itemsHandler.setStackInSlot(0, main);
}else{
existing.setCount(existing.getCount()+1);
if(existing.is(Items.AIR))
{
existing = makeOutputItem(entity.itemsHandler.getStackInSlot(0));
}
entity.itemsHandler.extractItem(0, 1, false);
}
entity.outputItems.setStackInSlot(0, existing);
entity.resetProgress();
}
}
private static boolean hasRecipe(MagicalScrubberBlockEntity entity) {
SimpleContainer inventory = new SimpleContainer(entity.itemsHandler.getSlots());
for(int i=0;i<entity.itemsHandler.getSlots();i++)
{
inventory.setItem(i, entity.itemsHandler.getStackInSlot(i));
}
SimpleContainer output = new SimpleContainer(entity.outputItems.getSlots());
for(int i=0;i<entity.outputItems.getSlots();i++)
{
output.setItem(i, entity.outputItems.getStackInSlot(i));
}
boolean hasAnItem = !entity.itemsHandler.getStackInSlot(0).isEmpty();
ItemStack result = null;
if(hasAnItem)
{
result = makeOutputItem(entity.itemsHandler.getStackInSlot(0));
}
return hasAnItem && canInsertIntoOutput(output, result);
}
private static boolean canInsertIntoOutput(SimpleContainer inventory, ItemStack result) {
ItemStack existing = inventory.getItem(0);
boolean stackCompat = (existing.getMaxStackSize() > existing.getCount());
boolean sameType = (existing.getItem() == result.getItem());
boolean outputEmpty = existing.isEmpty();
if(outputEmpty)return true;
return (stackCompat && sameType);
}
private void resetProgress() {
progress=0;
}
protected static ItemStack makeOutputItem(ItemStack original)
{
ItemStack newItem = new ItemStack(original.getItem(),1);
return newItem;
}
public IEnergyStorage getEnergyStorage() {
return ENERGY_STORAGE;
}
public void setEnergy(int energy) {
ENERGY_STORAGE.setEnergy(energy);
}
}

View file

@ -0,0 +1,31 @@
package dev.zontreck.thresholds.blocks.entity;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.blocks.ModBlocks;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class ModEntities {
public static final DeferredRegister<BlockEntityType<?>> ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, ThresholdsMod.MOD_ID);
public static final RegistryObject <BlockEntityType <ItemScrubberBlockEntity>> ITEM_SCRUBBER = ENTITIES.register("item_scrubber", ()-> BlockEntityType.Builder.of(ItemScrubberBlockEntity::new, ModBlocks.ITEM_SCRUBBER.get()).build(null));
public static final RegistryObject <BlockEntityType <MagicalScrubberBlockEntity>> MAGICAL_SCRUBBER = ENTITIES.register("magical_scrubber", ()-> BlockEntityType.Builder.of(MagicalScrubberBlockEntity::new, ModBlocks.MAGICAL_SCRUBBER.get()).build(null));
public static final ResourceLocation PARALLAX_BLOCK = new ResourceLocation(ThresholdsMod.MOD_ID, "parallax_block");
public static final RegistryObject<BlockEntityType<CompressionChamberBlockEntity>> COMPRESSION_CHAMBER = ENTITIES.register("compression_chamber", ()->BlockEntityType.Builder.of(CompressionChamberBlockEntity::new, ModBlocks.COMPRESSION_CHAMBER_BLOCK.get()).build(null));
public static final RegistryObject <BlockEntityType <ParallaxWindowEntity>> PARALLAX_WINDOW_ENTITY = ENTITIES.register("parallax_window", ()->BlockEntityType.Builder.of(ParallaxWindowEntity::new, ModBlocks.LIMINAL_WINDOW.get()).build(null));
public static void register(IEventBus eventBus)
{
ENTITIES.register(eventBus);
}
}

View file

@ -0,0 +1,59 @@
package dev.zontreck.thresholds.blocks.entity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import java.util.Arrays;
public class ParallaxWindowEntity extends BlockEntity
{
public enum SkyType
{
Level1
}
public ParallaxWindowEntity(BlockPos pPos, BlockState pBlockState) {
super(ModEntities.PARALLAX_WINDOW_ENTITY.get(), pPos, pBlockState);
}
private SkyType skyType = SkyType.Level1;
public SkyType getSkyType() {
return skyType;
}
@Override
protected void saveAdditional(CompoundTag compoundTag) {
compoundTag.putString("skyType", this.skyType.name());
}
@Override
public void load(CompoundTag compoundTag) {
if (!compoundTag.contains("skyType")) {
return;
}
this.skyType = SkyType.valueOf(compoundTag.getString("skyType"));
}
private final Boolean[] shouldRender = new Boolean[6];
public boolean shouldRenderFace(Direction direction) {
int index = direction.ordinal();
if (shouldRender[index] == null) {
shouldRender[index] = level == null || Block.shouldRenderFace(getBlockState(), level, getBlockPos(), direction, getBlockPos().relative(direction));
}
return shouldRender[index];
}
public void neighborChanged() {
Arrays.fill(shouldRender, null);
}
}

View file

@ -0,0 +1,41 @@
package dev.zontreck.thresholds.blocks.types;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Plane;
import net.minecraft.world.level.block.IronBarsBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import java.util.EnumMap;
/** Pane block with sensible culling */
public class AlternatePaneBlock extends IronBarsBlock {
public static final EnumMap<Direction,BooleanProperty> DIRECTIONS;
static {
DIRECTIONS = new EnumMap<>(Direction.class);
DIRECTIONS.put(Direction.NORTH, NORTH);
DIRECTIONS.put(Direction.EAST, EAST);
DIRECTIONS.put(Direction.SOUTH, SOUTH);
DIRECTIONS.put(Direction.WEST, WEST);
}
public AlternatePaneBlock(Properties builder) {
super(builder);
}
@Override
public boolean skipRendering(BlockState state, BlockState adjacentBlockState, Direction side) {
// cull top and bottom if all props that we have are contained in the above or below
if (adjacentBlockState.getBlock() == this && side.getAxis().isVertical()) {
for (Direction dir : Plane.HORIZONTAL) {
BooleanProperty prop = DIRECTIONS.get(dir);
if (state.getValue(prop) && !adjacentBlockState.getValue(prop)) {
return false;
}
}
return true;
}
return super.skipRendering(state, adjacentBlockState, side);
}
}

View file

@ -0,0 +1,133 @@
package dev.zontreck.thresholds.chat;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.chat.HoverTip;
import dev.zontreck.libzontreck.events.ProfileLoadedEvent;
import dev.zontreck.libzontreck.events.ProfileUnloadingEvent;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.util.ItemUtils;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import dev.zontreck.thresholds.configs.PlayerFlyCache;
import dev.zontreck.thresholds.enchantments.ModEnchantments;
import dev.zontreck.thresholds.implementation.vault.StarterProvider;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Abilities;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(modid= ThresholdsMod.MOD_ID, bus=Mod.EventBusSubscriber.Bus.FORGE)
public class ChatServerOverride {
@SubscribeEvent
public void onJoin(final ProfileLoadedEvent ev)
{
//Player joined, send custom alert
ServerPlayer play = ev.player;
Profile prof = ev.profile;
if(prof.flying)
{
play.getAbilities().flying=true;
play.onUpdateAbilities();
}
Abilities playerAbilities = play.getAbilities();
boolean mayFly = false;
ItemStack feet = play.getItemBySlot(EquipmentSlot.FEET);
if(ItemUtils.getEnchantmentLevel(ModEnchantments.FLIGHT_ENCHANTMENT.get(), feet)>0)mayFly = true;
playerAbilities.mayfly=mayFly;
PlayerFlyCache c = PlayerFlyCache.cachePlayer(play);
c.Flying=prof.flying;
c.FlyEnabled = mayFly;
c.Assert(play);
if(StarterProvider.exists())
ThresholdsMod.checkFirstJoin(ev.player);
if(!ThresholdsServerConfig.USE_CUSTOM_JOINLEAVE.get()) return;
ChatHelpers.broadcast(ChatHelpers.macro("!Dark_Gray![!Dark_Green!+!Dark_Gray!] !Bold!!Dark_Aqua![0]",prof.nickname), ev.level.getServer());
}
@SubscribeEvent
public void onLeave(ProfileUnloadingEvent ev)
{
// Get player profile, send disconnect alert, then commit profile and remove it from memory
Profile px=ev.profile;
if(px==null)return;
if(!ThresholdsServerConfig.USE_CUSTOM_JOINLEAVE.get()) return;
// Send the alert
ChatHelpers.broadcast(ChatHelpers.macro("!Dark_Gray![!Dark_Red!-!Dark_Gray!] !Bold!!Dark_Aqua![0]", px.nickname), px.player.server);
px.flying=px.player.getAbilities().flying;
ev.setCanceled(true);
}
@SubscribeEvent
public void onClone(final PlayerEvent.Clone ev)
{
if(ev.getEntity().level().isClientSide)return;
// Fix for fly ability not copying to new instance on death or other circumstances
Player old = ev.getOriginal();
Player n = ev.getEntity();
PlayerFlyCache c = PlayerFlyCache.cachePlayer((ServerPlayer)old);
c.Assert((ServerPlayer)n);
}
@SubscribeEvent
public void onChat(final ServerChatEvent ev){
if(ev.getPlayer().level().isClientSide)return;
// Player has chatted, apply override
if(!ThresholdsServerConfig.USE_CUSTOM_CHATREPLACER.get()) return;
ServerPlayer sp = ev.getPlayer();
// Get profile
Profile XD=null;
try {
XD = Profile.get_profile_of(sp.getStringUUID());
} catch (UserProfileNotYetExistsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Override the chat!
String prefixStr = "";
if(XD.prefix != ""){
prefixStr = ChatColor.DARK_GRAY + "[" + ChatColor.BOLD + XD.prefix_color + XD.prefix + ChatColor.resetChat() + ChatColor.DARK_GRAY + "] ";
}
String msg = ev.getRawText();
msg= ChatColor.doColors(msg);
String nameStr = ChatColor.resetChat() + "< "+ XD.name_color + XD.nickname + ChatColor.resetChat() + " >";
String message = ": "+XD.chat_color + msg;
Style hover = Style.EMPTY;
hover=hover.withFont(Style.DEFAULT_FONT).withHoverEvent(HoverTip.get(ChatColor.MINECOIN_GOLD+"User Name: "+XD.username));
ev.setCanceled(true);
ChatHelpers.broadcast(Component.literal(prefixStr + nameStr + message).setStyle(hover), ev.getPlayer().server);
}
}

View file

@ -0,0 +1,48 @@
package dev.zontreck.thresholds.client.renderer;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import dev.zontreck.thresholds.blocks.entity.ParallaxWindowEntity;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.core.Direction;
import org.joml.Matrix4f;
public class ParallaxWindowEntityRenderer implements BlockEntityRenderer<ParallaxWindowEntity>
{
@Override
public void render(ParallaxWindowEntity parallaxWindowEntity, float v, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, int i1) {
Matrix4f m4f = poseStack.last().pose();
var renderType = switch (parallaxWindowEntity.getSkyType()) {
case Level1 -> RenderType.endPortal();
};
renderCube(parallaxWindowEntity, m4f, multiBufferSource.getBuffer(renderType));
}
private void renderCube(ParallaxWindowEntity entity, Matrix4f matrix, VertexConsumer buffer) {
renderFace(entity, matrix, buffer, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, Direction.SOUTH);
renderFace(entity, matrix, buffer, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, Direction.NORTH);
renderFace(entity, matrix, buffer, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, Direction.EAST);
renderFace(entity, matrix, buffer, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, Direction.WEST);
renderFace(entity, matrix, buffer, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, Direction.DOWN);
renderFace(entity, matrix, buffer, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, Direction.UP);
}
private void renderFace(ParallaxWindowEntity entity, Matrix4f matrix, VertexConsumer buffer, float f, float g, float h, float i, float j, float k, float l, float m, Direction direction) {
if (entity.shouldRenderFace(direction)) {
buffer.vertex(matrix, f, h, j).endVertex();
buffer.vertex(matrix, g, h, k).endVertex();
buffer.vertex(matrix, g, i, l).endVertex();
buffer.vertex(matrix, f, i, m).endVertex();
}
}
@Override
public int getViewDistance() {
return 256;
}
}

View file

@ -0,0 +1,110 @@
package dev.zontreck.thresholds.commands;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.commands.items.ShareItemInChatCommand;
import dev.zontreck.thresholds.commands.profilecmds.ChatColorCommand;
import dev.zontreck.thresholds.commands.profilecmds.NameColorCommand;
import dev.zontreck.thresholds.commands.profilecmds.NickCommand;
import dev.zontreck.thresholds.commands.profilecmds.PrefixColorCommand;
import dev.zontreck.thresholds.commands.profilecmds.PrefixCommand;
import dev.zontreck.thresholds.commands.vaults.StarterCommand;
import dev.zontreck.thresholds.commands.vaults.TrashCommand;
import dev.zontreck.thresholds.commands.vaults.VaultCommand;
import dev.zontreck.thresholds.commands.zschem.LoadSchem;
import dev.zontreck.thresholds.commands.zschem.Place;
import dev.zontreck.thresholds.commands.zschem.PlaceAsAir;
import dev.zontreck.thresholds.commands.zschem.SaveSchem;
import dev.zontreck.thresholds.commands.zschem.SetPos1;
import dev.zontreck.thresholds.commands.zschem.SetPos2;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(modid= ThresholdsMod.MOD_ID,bus=Mod.EventBusSubscriber.Bus.FORGE)
public class CommandRegistry {
public static Map<String,Long> CommandCooldownRegistry = new HashMap<>();
public static void markUsed(String cmd)
{
// Command was used, mark the current time
CommandCooldownRegistry.put(cmd, Instant.now().getEpochSecond());
}
public static boolean canUse(String cmd)
{
if(!CommandCooldownRegistry.containsKey(cmd)) return true;
long lastUse = CommandCooldownRegistry.get(cmd);
switch(cmd)
{
case "rtp":
{
if(Instant.now().getEpochSecond() > lastUse+Long.parseLong(String.valueOf(ThresholdsServerConfig.RTP_COOLDOWN))){
CommandCooldownRegistry.remove(cmd);
return true;
}else return false;
}
default:
{
CommandCooldownRegistry.remove(cmd);
return true; // cooldown not yet made
}
}
}
public static String getRemaining(String string) {
long now = Instant.now().getEpochSecond();
if(!CommandCooldownRegistry.containsKey(string))return "0";
long used = CommandCooldownRegistry.get(string);
long cmd_time = 0L;
switch(string)
{
case "rtp":
{
cmd_time = Long.parseLong(String.valueOf(ThresholdsServerConfig.RTP_COOLDOWN));
break;
}
default:
{
cmd_time = 0L;
break;
}
}
used+=cmd_time;
long diff = used-now;
if(diff<0)diff=0L;
return String.valueOf(diff);
}
@SubscribeEvent
public void onRegisterCommands(final RegisterCommandsEvent ev)
{
ChatColorCommand.register(ev.getDispatcher());
NameColorCommand.register(ev.getDispatcher());
PrefixColorCommand.register(ev.getDispatcher());
PrefixCommand.register(ev.getDispatcher());
NickCommand.register(ev.getDispatcher());
VaultCommand.register(ev.getDispatcher());
TrashCommand.register(ev.getDispatcher());
SetPos1.register(ev.getDispatcher());
SetPos2.register(ev.getDispatcher());
SaveSchem.register(ev.getDispatcher());
LoadSchem.register(ev.getDispatcher());
Place.register(ev.getDispatcher());
PlaceAsAir.register(ev.getDispatcher());
ShareItemInChatCommand.register(ev.getDispatcher());
StarterCommand.register(ev.getDispatcher());
}
}

View file

@ -0,0 +1,52 @@
package dev.zontreck.thresholds.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.thresholds.ThresholdsMod;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
public class FlyCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("fly").executes(FlyCommand::Fly));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int Fly(CommandContext<CommandSourceStack> ctx2)
{
// Request homes
// String homeName = "";
// CommandSourceStack ctx = ctx2.getSource();
// homeName = StringArgumentType.getString(ctx2, "nickname");
// if(homeName==null)return 0;
CommandSourceStack ctx = ctx2.getSource();
ServerPlayer p = (ServerPlayer)ctx.getEntity();
if(p==null)return 1;
if(p.getAbilities().mayfly){
p.getAbilities().mayfly=false;
p.getAbilities().flying=false;
p.onUpdateAbilities();
ctx.sendSystemMessage(Component.literal(ThresholdsMod.ThresholdsPrefix + ChatColor.DARK_PURPLE + " Your ability to fly has been disabled"));
}else {
p.getAbilities().mayfly=true;
p.onUpdateAbilities();
ctx.sendSystemMessage(Component.literal(ThresholdsMod.ThresholdsPrefix + ChatColor.DARK_PURPLE + " You can now fly"));
}
return 0;
}
}

View file

@ -0,0 +1,8 @@
package dev.zontreck.thresholds.commands.antigrief;
// This will accelerate the healing queue, not do it instantly!
// The queue will get processed at a rate of 10* the configured rate.
public class HealNow
{
}

View file

@ -0,0 +1,62 @@
package dev.zontreck.thresholds.commands.items;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.chat.HoverTip;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.ThresholdsMod;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.AirItem;
import net.minecraft.world.item.ItemStack;
public class ShareItemInChatCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("shareitem").executes(c->share_item(c.getSource())));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int share_item(CommandSourceStack source) {
if(source.getEntity() instanceof Player)
{
ServerPlayer play = (ServerPlayer)source.getEntity();
ItemStack is = play.getItemInHand(InteractionHand.MAIN_HAND);
if(is.getItem() instanceof AirItem)
{
play.displayClientMessage(ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You cannot share air in the chat."), false);
return 0;
}
Profile prof;
try {
prof = Profile.get_profile_of(play.getUUID().toString());
} catch (UserProfileNotYetExistsException e) {
return 1;
}
MutableComponent component = ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix).append(is.getDisplayName()).append(ChatHelpers.macro(" !White!-!Dark_Purple! Hover here to see the item that "+prof.name_color+prof.nickname+"!Dark_Purple! shared"));
Style style = Style.EMPTY.withFont(Style.DEFAULT_FONT);
component = component.withStyle(style.withHoverEvent(HoverTip.getItem(is)));
ChatHelpers.broadcast(component, ThresholdsMod.THE_SERVER);
}else {
return 1;
}
return 0;
}
}

View file

@ -0,0 +1,59 @@
package dev.zontreck.thresholds.commands.profilecmds;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.chat.ChatColor.ColorOptions;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.implementation.Messages;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.server.command.EnumArgument;
public class ChatColorCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("chat_color")
.executes(c->setchatcolor(c.getSource(), ColorOptions.White))
.then(Commands.argument("color", EnumArgument.enumArgument(ChatColor.ColorOptions.class))//StringArgumentType.string())
.executes(c -> setchatcolor(c.getSource(), c.getArgument("color", ChatColor.ColorOptions.class)))// EnumArgument.getS(c, "color")))
)
);
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
public static int setchatcolor(CommandSourceStack source, ColorOptions string) {
// Chat Color has a registry of colors that we can use to map back to our desired color
// To code
String colorcoded = ChatColor.from(string);
// Get profile
if(!(source.getEntity() instanceof Player)){
return 1;
}
ServerPlayer play = (ServerPlayer)source.getEntity();
Profile p;
try {
p = Profile.get_profile_of(play.getStringUUID());
} catch (UserProfileNotYetExistsException e) {
return 1;
}
p.chat_color = colorcoded;
p.commit();
LibZontreck.PROFILES.put(play.getStringUUID(), p);
ChatHelpers.broadcastTo(play, ChatHelpers.macro(Messages.CHAT_COLOR_UPDATED), source.getServer());
return 0;
}
}

View file

@ -0,0 +1,60 @@
package dev.zontreck.thresholds.commands.profilecmds;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.chat.ChatColor.ColorOptions;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.implementation.Messages;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.server.command.EnumArgument;
public class NameColorCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("nick_color")
.executes(c->setchatcolor(c.getSource(), ColorOptions.White))
.then(Commands.argument("color", EnumArgument.enumArgument(ChatColor.ColorOptions.class))//StringArgumentType.string())
.executes(c -> setchatcolor(c.getSource(), c.getArgument("color", ChatColor.ColorOptions.class)))// EnumArgument.getS(c, "color")))
)
);
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
public static int setchatcolor(CommandSourceStack source, ColorOptions string) {
// Chat Color has a registry of colors that we can use to map back to our desired color
// To code
String colorcoded = ChatColor.from(string);
// Get profile
if(!(source.getEntity() instanceof Player)){
return 1;
}
ServerPlayer play = (ServerPlayer)source.getEntity();
Profile p;
try {
p = Profile.get_profile_of(play.getStringUUID());
} catch (UserProfileNotYetExistsException e) {
return 1;
}
p.name_color = colorcoded;
p.commit();
LibZontreck.PROFILES.put(play.getStringUUID(), p);
ChatHelpers.broadcastTo(play, ChatHelpers.macro(Messages.NAME_COLOR_UPDATED), source.getServer());
return 0;
}
}

View file

@ -0,0 +1,55 @@
package dev.zontreck.thresholds.commands.profilecmds;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.implementation.Messages;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
public class NickCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("nick")
.executes(c->setchatcolor(c.getSource(), c.getSource().getPlayerOrException().getName().getString()))
.then(Commands.argument("new_name", StringArgumentType.string())//StringArgumentType.string())
.executes(c -> setchatcolor(c.getSource(), StringArgumentType.getString(c, "new_name")))// EnumArgument.getS(c, "color")))
)
);
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
public static int setchatcolor(CommandSourceStack source, String string) {
// Get profile
if(!(source.getEntity() instanceof Player)){
return 1;
}
ServerPlayer play = (ServerPlayer)source.getEntity();
Profile p;
try {
p = Profile.get_profile_of(play.getStringUUID());
} catch (UserProfileNotYetExistsException e) {
return 1;
}
p.nickname = string;
p.commit();
LibZontreck.PROFILES.put(play.getStringUUID(), p);
ChatHelpers.broadcastTo(play, ChatHelpers.macro(Messages.NICK_UPDATED), source.getServer());
return 0;
}
}

View file

@ -0,0 +1,60 @@
package dev.zontreck.thresholds.commands.profilecmds;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.chat.ChatColor.ColorOptions;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.implementation.Messages;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.server.command.EnumArgument;
public class PrefixColorCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("prefix_color")
.executes(c->setchatcolor(c.getSource(), ColorOptions.White))
.then(Commands.argument("color", EnumArgument.enumArgument(ChatColor.ColorOptions.class))//StringArgumentType.string())
.executes(c -> setchatcolor(c.getSource(), c.getArgument("color", ChatColor.ColorOptions.class)))// EnumArgument.getS(c, "color")))
)
);
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
public static int setchatcolor(CommandSourceStack source, ColorOptions string) {
// Chat Color has a registry of colors that we can use to map back to our desired color
// To code
String colorcoded = ChatColor.from(string);
// Get profile
if(!(source.getEntity() instanceof Player)){
return 1;
}
ServerPlayer play = (ServerPlayer)source.getEntity();
Profile p;
try {
p = Profile.get_profile_of(play.getStringUUID());
} catch (UserProfileNotYetExistsException e) {
return 1;
}
p.prefix_color = colorcoded;
p.commit();
LibZontreck.PROFILES.put(play.getStringUUID(), p);
ChatHelpers.broadcastTo(play, ChatHelpers.macro(Messages.PREFIX_COLOR_UPDATED), source.getServer());
return 0;
}
}

View file

@ -0,0 +1,54 @@
package dev.zontreck.thresholds.commands.profilecmds;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.implementation.Messages;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
public class PrefixCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("prefix")
.executes(c->setchatcolor(c.getSource(), "Member"))
.then(Commands.argument("new_prefix", StringArgumentType.string())//StringArgumentType.string())
.executes(c -> setchatcolor(c.getSource(), StringArgumentType.getString(c, "new_prefix")))// EnumArgument.getS(c, "color")))
)
);
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
public static int setchatcolor(CommandSourceStack source, String string) {
// Get profile
if(!(source.getEntity() instanceof Player)){
return 1;
}
ServerPlayer play = (ServerPlayer)source.getEntity();
Profile p;
try {
p = Profile.get_profile_of(play.getStringUUID());
} catch (UserProfileNotYetExistsException e) {
return 1;
}
p.prefix = string;
p.commit();
LibZontreck.PROFILES.put(play.getStringUUID(), p);
ChatHelpers.broadcastTo(play, ChatHelpers.macro(Messages.PREFIX_UPDATED), source.getServer());
return 0;
}
}

View file

@ -0,0 +1,98 @@
package dev.zontreck.thresholds.commands.vaults;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.Messages;
import dev.zontreck.thresholds.implementation.PlayerFirstJoinTag;
import dev.zontreck.thresholds.implementation.vault.NoMoreVaultException;
import dev.zontreck.thresholds.implementation.vault.StarterContainer;
import dev.zontreck.thresholds.implementation.vault.VaultContainer;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraftforge.network.NetworkHooks;
public class StarterCommand
{
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("starter").executes(x->openStarterMenu(x.getSource())).then(Commands.argument("player", EntityArgument.player()).executes(x->starterCommand(x.getSource(), EntityArgument.getPlayer(x, "player")))));
}
public static int starterCommand(CommandSourceStack ctx, ServerPlayer player)
{
if(ctx.hasPermission(ctx.getServer().getOperatorUserPermissionLevel()))
{
try {
vendStarterKit(player);
} catch (UserProfileNotYetExistsException e) {
throw new RuntimeException(e);
}
return 0;
}
return 1;
}
public static void vendStarterKit(ServerPlayer player) throws UserProfileNotYetExistsException {
Profile prof = Profile.get_profile_of(player.getStringUUID());
PlayerFirstJoinTag PFJT = PlayerFirstJoinTag.now();
PFJT.LastGiven=0L;
PFJT.save(prof.NBT);
ThresholdsMod.checkFirstJoin(player);
}
public static int openStarterMenu(CommandSourceStack ctx)
{
ServerPlayer player = ctx.getPlayer();
if(player != null)
{
if(player.hasPermissions(ctx.getServer().getOperatorUserPermissionLevel()))
{
try {
StarterContainer container = new StarterContainer(player);
NetworkHooks.openScreen(player, new SimpleMenuProvider(container.serverMenu, Component.literal("Starter Gear")));
// Add to the master vault registry
if(StarterContainer.VAULT_REGISTRY.containsKey(player.getUUID()))StarterContainer.VAULT_REGISTRY.remove(player.getUUID());
StarterContainer.VAULT_REGISTRY.put(player.getUUID(), container);
} catch (NoMoreVaultException e) {
throw new RuntimeException(e);
}
}else {
ChatHelpers.broadcastTo(player, ChatHelpers.macro(Messages.STARTER_FAILURE_PERMISSIONS), ctx.getServer());
}
return 0;
}
ctx.sendFailure(ChatHelpers.macro(Messages.STARTER_FAILURE_CONSOLE));
return 1;
}
public static void doOpen(ServerPlayer p){
StarterContainer container;
try {
container = new StarterContainer(p);
} catch (NoMoreVaultException e) {
ChatHelpers.broadcastTo(p.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +"!Dark_Red!You cannot open anymore vaults. Craft a new vault!"), p.server);
return;
}
NetworkHooks.openScreen(p, new SimpleMenuProvider(container.serverMenu, Component.literal("Starter Gear")));
// Add to the master vault registry
if(StarterContainer.VAULT_REGISTRY.containsKey(p.getUUID()))VaultContainer.VAULT_REGISTRY.remove(p.getUUID());
StarterContainer.VAULT_REGISTRY.put(p.getUUID(), container);
}
}

View file

@ -0,0 +1,48 @@
package dev.zontreck.thresholds.commands.vaults;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.vault.NoMoreVaultException;
import dev.zontreck.thresholds.implementation.vault.VaultContainer;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraftforge.network.NetworkHooks;
public class TrashCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("trash").executes(c-> vault(c.getSource())));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int vault(CommandSourceStack source) {
//VaultContainer cont = new VaultContainer(i, source.getPlayer().getUUID());
//cont.startOpen(source.getPlayer());
ServerPlayer play = (ServerPlayer)source.getEntity();
VaultContainer container;
try {
container = new VaultContainer(play, -1);
} catch (NoMoreVaultException e) {
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You cannot open anymore vaults. Craft a new vault!"), play.server);
return 0;
}
NetworkHooks.openScreen(play, new SimpleMenuProvider(container.serverMenu, Component.literal("Trash")));
// Add to the master vault registry
if(VaultContainer.VAULT_REGISTRY.containsKey(play.getUUID()))VaultContainer.VAULT_REGISTRY.remove(play.getUUID());
VaultContainer.VAULT_REGISTRY.put(play.getUUID(), container);
return 0;
}
}

View file

@ -0,0 +1,60 @@
package dev.zontreck.thresholds.commands.vaults;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.vault.NoMoreVaultException;
import dev.zontreck.thresholds.implementation.vault.VaultContainer;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraftforge.network.NetworkHooks;
public class VaultCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("pv").executes(c-> vault(c.getSource(), 0)).then(Commands.argument("number", IntegerArgumentType.integer()).executes(c -> vault(c.getSource(), IntegerArgumentType.getInteger(c, "number")))));
dispatcher.register(Commands.literal("vault").executes(c-> vault(c.getSource(), 0)).then(Commands.argument("number", IntegerArgumentType.integer()).executes(c -> vault(c.getSource(), IntegerArgumentType.getInteger(c, "number")))));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int vault(CommandSourceStack source, int i) {
//VaultContainer cont = new VaultContainer(i, source.getPlayer().getUUID());
//cont.startOpen(source.getPlayer());
ServerPlayer play = (ServerPlayer)source.getEntity();
if(i <0)
{
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You can only specify a vault number in the positive range"), source.getServer());
return 0;
}
doOpen(play, i);
return 0;
}
public static void doOpen(ServerPlayer p, int i){
VaultContainer container;
try {
container = new VaultContainer(p, i);
} catch (NoMoreVaultException e) {
ChatHelpers.broadcastTo(p.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You cannot open anymore vaults. Craft a new vault!"), p.server);
return;
}
NetworkHooks.openScreen(p, new SimpleMenuProvider(container.serverMenu, Component.literal("Vault " + i)));
// Add to the master vault registry
if(VaultContainer.VAULT_REGISTRY.containsKey(p.getUUID()))VaultContainer.VAULT_REGISTRY.remove(p.getUUID());
VaultContainer.VAULT_REGISTRY.put(p.getUUID(), container);
}
}

View file

@ -0,0 +1,139 @@
package dev.zontreck.thresholds.commands.zschem;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3;
import dev.zontreck.libzontreck.vectors.WorldPosition;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.integrations.LuckPermsHelper;
import dev.zontreck.thresholds.permissions.Permissions;
import dev.zontreck.thresholds.zschem.MemoryHolder;
import dev.zontreck.thresholds.zschem.MemoryHolder.Container;
import dev.zontreck.thresholds.zschem.StoredBlock;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.Tag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.fml.loading.FMLConfig;
import net.minecraftforge.fml.loading.FMLPaths;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class LoadSchem {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("loadzschem").executes(c-> loadSchematicUsage(c.getSource())).then(Commands.argument("name", StringArgumentType.string()).executes(z->loadSchematic(z.getSource(), StringArgumentType.getString(z, "name")))));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int loadSchematic(CommandSourceStack source, String name) {
// Perform sanity checks
ServerPlayer play = (ServerPlayer)source.getEntity();
if(play==null)return 1;
if(!LuckPermsHelper.hasGroupOrPerm(play, Permissions.zschem, Permissions.zschem_load)){
LuckPermsHelper.sendNoPermissionsMessage(play, Permissions.zschem_load, Permissions.zschem);
return 1;
}
if(MemoryHolder.hasPlayerCached(play))
{
Container cont = MemoryHolder.getContainer(play);
if(cont == null)
{
loadSchematicUsage(source);
}else {
if(cont.Pos1 != ThresholdsMod.ZERO_VECTOR)
{
// Lets go!
List<StoredBlock> blocks = new ArrayList<StoredBlock>();
// First we calculate every vector between pos1 and pos2.
// Then we subtract pos1 from the vector to acquire a relative position.
// Then we save the block with this relative position to the blocks list
// Once serialized, it is then possible to add the position. Note that this makes it impossible to rotate a zschem like with worldedit, but thats usually fine for our usecases. once in-game worldedit can be used to rotate.
// TODO: Also- It is possible that a rotational implementation can be added in the future
Path configDir = FMLPaths.GAMEDIR.get().resolve(FMLConfig.defaultConfigPath());
configDir = configDir.resolve("ZSchems");
File X = configDir.toFile();
if(!X.exists())
{
X.mkdir();
}
configDir = configDir.resolve(name+"-zschem.nbt");
if(configDir.toFile().exists()){
CompoundTag CT=new CompoundTag();
try {
CT = NbtIo.readCompressed(configDir.toFile());
} catch (IOException e) {
e.printStackTrace();
return 1;
}
ListTag blst = CT.getList("blocks", CompoundTag.TAG_COMPOUND);
Iterator<Tag> tags = blst.iterator();
while(tags.hasNext())
{
CompoundTag nxt = (CompoundTag)tags.next();
StoredBlock sb = new StoredBlock(nxt);
ServerLevel pasteLvl = cont.lvl;
sb.updateWorld(pasteLvl);
WorldPosition wp = sb.getWorldPosition();
Vector3 superPos = cont.Pos1;
wp.Position = superPos.add(wp.Position);
sb.setPosition(wp.Position);
blocks.add(sb);
}
MemoryHolder.setBlocks(play, blocks);
}else {
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix + " !Dark_Red!No such ZSchem exists!"), source.getServer());
return 0;
}
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Green!ZSchem loaded from disk!"), ThresholdsMod.THE_SERVER);
return 0;
}
}
}
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro("!Dark_Red! You must set the first position"), ThresholdsMod.THE_SERVER);
return 0;
}
private static int loadSchematicUsage(CommandSourceStack source)
{
String usage = ThresholdsMod.ThresholdsPrefix;
usage += "!gold! /loadzschem [string:name]";
ServerPlayer play=(ServerPlayer)source.getEntity();
if(play==null)return 1;
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(usage), ThresholdsMod.THE_SERVER);
return 0;
}
}

View file

@ -0,0 +1,75 @@
package dev.zontreck.thresholds.commands.zschem;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.integrations.LuckPermsHelper;
import dev.zontreck.thresholds.permissions.Permissions;
import dev.zontreck.thresholds.zschem.MemoryHolder;
import dev.zontreck.thresholds.zschem.MemoryHolder.Container;
import dev.zontreck.thresholds.zschem.StoredBlock;
import dev.zontreck.thresholds.zschem.WorldProp;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
import java.util.Collections;
import java.util.List;
// This command will place the loaded schematic in world. The schematic will originate from position 1. The positions are relative and are added onto position 1.
public class Place {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("placezschem").executes(c-> place(c.getSource())));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int place(CommandSourceStack source) {
ServerPlayer play = (ServerPlayer)source.getEntity();
if(play==null)return 1;
if(!LuckPermsHelper.hasGroupOrPerm(play, Permissions.zschem, Permissions.zschem_place)){
LuckPermsHelper.sendNoPermissionsMessage(play, Permissions.zschem_place, Permissions.zschem);
return 1;
}
if(!MemoryHolder.hasPlayerCached(play)){
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You must first load the zschem!"), ThresholdsMod.THE_SERVER);
return 1;
}
Container cont = MemoryHolder.getContainer(play);
List<StoredBlock> blocks = cont.blocks;
Collections.shuffle(blocks);
if(cont.Pos1 != ThresholdsMod.ZERO_VECTOR)
{
WorldProp system = WorldProp.acquire(cont.lvl);
// Begin the process
for (StoredBlock storedBlock : blocks) {
// alter the stored block and send it off to the queue system for the relevant world!
system.customEnqueue(storedBlock);
}
}else {
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You must first load the zschem!"), ThresholdsMod.THE_SERVER);
return 1;
}
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Green!Enqueued!"), ThresholdsMod.THE_SERVER);
return 0;
}
}

View file

@ -0,0 +1,82 @@
package dev.zontreck.thresholds.commands.zschem;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.integrations.LuckPermsHelper;
import dev.zontreck.thresholds.permissions.Permissions;
import dev.zontreck.thresholds.zschem.MemoryHolder;
import dev.zontreck.thresholds.zschem.MemoryHolder.Container;
import dev.zontreck.thresholds.zschem.StoredBlock;
import dev.zontreck.thresholds.zschem.WorldProp;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.block.Blocks;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
// This command will place the loaded schematic in world. The schematic will originate from position 1. The positions are relative and are added onto position 1.
public class PlaceAsAir {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("zsetair").executes(c-> place(c.getSource())));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int place(CommandSourceStack source) {
ServerPlayer play = (ServerPlayer)source.getEntity();
if(play==null)return 1;
if(!LuckPermsHelper.hasGroupOrPerm(play, Permissions.zschem, Permissions.zschem_air)){
LuckPermsHelper.sendNoPermissionsMessage(play, Permissions.zschem_air, Permissions.zschem);
return 1;
}
if(!MemoryHolder.hasPlayerCached(play)){
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You must first set the positions!"), ThresholdsMod.THE_SERVER);
return 1;
}
Container cont = MemoryHolder.getContainer(play);
if(cont.Pos1 != ThresholdsMod.ZERO_VECTOR && cont.Pos2 != ThresholdsMod.ZERO_VECTOR)
{
WorldProp system = WorldProp.acquire(cont.lvl);
// Begin the process
List<Vector3> positions = cont.Pos1.makeCube(cont.Pos2);
Collections.shuffle(positions);
Iterator<Vector3> v3 = positions.iterator();
while(v3.hasNext())
{
Vector3 pos = v3.next();
StoredBlock sb = new StoredBlock(pos.asBlockPos(), Blocks.AIR.defaultBlockState(), source.getLevel());
system.customEnqueue(sb);
}
}else {
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You must first set the positions!"), ThresholdsMod.THE_SERVER);
return 1;
}
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Green!Enqueued!"), ThresholdsMod.THE_SERVER);
return 0;
}
}

View file

@ -0,0 +1,125 @@
package dev.zontreck.thresholds.commands.zschem;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.integrations.LuckPermsHelper;
import dev.zontreck.thresholds.permissions.Permissions;
import dev.zontreck.thresholds.zschem.MemoryHolder;
import dev.zontreck.thresholds.zschem.MemoryHolder.Container;
import dev.zontreck.thresholds.zschem.StoredBlock;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.fml.loading.FMLConfig;
import net.minecraftforge.fml.loading.FMLPaths;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class SaveSchem {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("savezschem").executes(c-> saveSchematicUsage(c.getSource())).then(Commands.argument("name", StringArgumentType.string()).executes(z->saveSchematic(z.getSource(), StringArgumentType.getString(z, "name")))));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int saveSchematic(CommandSourceStack source, String name) {
// Perform sanity checks
ServerPlayer play = (ServerPlayer)source.getEntity();
if(play==null)return 1;
if(!LuckPermsHelper.hasGroupOrPerm(play, Permissions.zschem, Permissions.zschem_save)){
LuckPermsHelper.sendNoPermissionsMessage(play, Permissions.zschem_save, Permissions.zschem);
return 1;
}
if(MemoryHolder.hasPlayerCached(play))
{
Container cont = MemoryHolder.getContainer(play);
if(cont == null)
{
saveSchematicUsage(source);
}else {
if(cont.Pos1 != ThresholdsMod.ZERO_VECTOR && cont.Pos2 != ThresholdsMod.ZERO_VECTOR)
{
// Lets go!
List<StoredBlock> blocks = new ArrayList<StoredBlock>();
// First we calculate every vector between pos1 and pos2.
// Then we subtract pos1 from the vector to acquire a relative position.
// Then we save the block with this relative position to the blocks list
// Once serialized, it is then possible to add the position. Note that this makes it impossible to rotate a zschem like with worldedit, but thats usually fine for our usecases. once in-game worldedit can be used to rotate.
// TODO: Also- It is possible that a rotational implementation can be added in the future
List<Vector3> positions = cont.Pos1.makeCube(cont.Pos2);
for (Vector3 vector3 : positions) {
Vector3 v3 = vector3.subtract(cont.Pos1);
BlockPos current = vector3.asBlockPos();
StoredBlock sb = new StoredBlock(current, cont.lvl.getBlockState(current), cont.lvl);
sb.setPosition(v3);
blocks.add(sb);
}
CompoundTag savedSchem = new CompoundTag();
ListTag lst = new ListTag();
for (StoredBlock sBlock : blocks) {
lst.add(sBlock.serialize());
}
savedSchem.put("blocks", lst);
Path configDir = FMLPaths.GAMEDIR.get().resolve(FMLConfig.defaultConfigPath());
configDir = configDir.resolve("ZSchems");
File X = configDir.toFile();
if(!X.exists())
{
X.mkdir();
}
configDir = configDir.resolve(name+"-zschem.nbt");
// Save file!
try {
NbtIo.writeCompressed(savedSchem, configDir.toFile());
} catch (IOException e) {
e.printStackTrace();
}
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Green!ZSchem saved to disk!"), ThresholdsMod.THE_SERVER);
return 0;
}
}
}
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro("!Dark_Red! You must first set the positions"), ThresholdsMod.THE_SERVER);
return 0;
}
private static int saveSchematicUsage(CommandSourceStack source)
{
String usage = ThresholdsMod.ThresholdsPrefix;
usage += "!gold! /savezschem [string:name]";
ServerPlayer play=(ServerPlayer)source.getEntity();
if(play==null)return 1;
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(usage), ThresholdsMod.THE_SERVER);
return 0;
}
}

View file

@ -0,0 +1,44 @@
package dev.zontreck.thresholds.commands.zschem;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.integrations.LuckPermsHelper;
import dev.zontreck.thresholds.permissions.Permissions;
import dev.zontreck.thresholds.zschem.MemoryHolder;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
public class SetPos1 {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("zpos1").executes(c-> setzPos1(c.getSource())));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int setzPos1(CommandSourceStack source) {
ServerPlayer play = (ServerPlayer)source.getEntity();
if(play==null)return 1;
if(!LuckPermsHelper.hasGroupOrPerm(play, Permissions.zschem, Permissions.zschem_pos1)){
LuckPermsHelper.sendNoPermissionsMessage(play, Permissions.zschem_pos1, Permissions.zschem);
return 1;
}
MemoryHolder.setPos1(play, new Vector3(source.getPosition()));
MemoryHolder.setLevel(play, source.getLevel());
ChatHelpers.broadcastTo(play.getUUID(), Component.literal(ThresholdsMod.ThresholdsPrefix +ChatColor.doColors(" !Dark_Green!Position 1 set!")), ThresholdsMod.THE_SERVER);
return 0;
}
}

View file

@ -0,0 +1,44 @@
package dev.zontreck.thresholds.commands.zschem;
import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector3;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.integrations.LuckPermsHelper;
import dev.zontreck.thresholds.permissions.Permissions;
import dev.zontreck.thresholds.zschem.MemoryHolder;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
public class SetPos2 {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
{
dispatcher.register(Commands.literal("zpos2").executes(c-> setzPos2(c.getSource())));
//dispatcher.register(Commands.literal("sethome").then(Commands.argument("nickname", StringArgumentType.string())).executes(command -> {
//String arg = StringArgumentType.getString(command, "nickname");
//return setHome(command.getSource(), arg);
//}));
}
private static int setzPos2(CommandSourceStack source) {
ServerPlayer play = (ServerPlayer)source.getEntity();
if(play==null)return 1;
if(!LuckPermsHelper.hasGroupOrPerm(play, Permissions.zschem, Permissions.zschem_pos2)){
LuckPermsHelper.sendNoPermissionsMessage(play, Permissions.zschem_pos2, Permissions.zschem);
return 1;
}
MemoryHolder.setPos2(play, new Vector3(source.getPosition()));
MemoryHolder.setLevel(play, source.getLevel());
ChatHelpers.broadcastTo(play.getUUID(), Component.literal(ThresholdsMod.ThresholdsPrefix +ChatColor.doColors(" !Dark_Green!Position 2 set!")), ThresholdsMod.THE_SERVER);
return 0;
}
}

View file

@ -0,0 +1,27 @@
package dev.zontreck.thresholds.configs;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Abilities;
public class PlayerFlyCache
{
public boolean FlyEnabled;
public boolean Flying;
public static PlayerFlyCache cachePlayer(ServerPlayer play){
PlayerFlyCache cache = new PlayerFlyCache();
cache.FlyEnabled = play.getAbilities().mayfly;
cache.Flying = play.getAbilities().flying;
play.onUpdateAbilities();
return cache;
}
public void Assert(ServerPlayer play){
Abilities playerAbilities = play.getAbilities();
playerAbilities.flying=Flying;
playerAbilities.mayfly=FlyEnabled;
play.onUpdateAbilities();
}
}

View file

@ -0,0 +1,95 @@
package dev.zontreck.thresholds.configs;
import java.util.ArrayList;
import java.util.List;
import net.minecraftforge.common.ForgeConfigSpec;
public class ThresholdsServerConfig {
public static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
public static final ForgeConfigSpec SPEC;
public static final ForgeConfigSpec.ConfigValue<Double> SPAWN_EGG_CHANCE;
public static final ForgeConfigSpec.ConfigValue<Integer> ITEM_DESPAWN_TIMER;
public static final ForgeConfigSpec.ConfigValue<Integer> RTP_COOLDOWN;
public static final ForgeConfigSpec.ConfigValue<Integer> HEALER_TIMER;
public static final ForgeConfigSpec.BooleanValue DEBUG_HEALER;
public static final ForgeConfigSpec.ConfigValue<Integer> TIME_BETWEEN_BLOCKS;
public static final ForgeConfigSpec.ConfigValue<Integer> MAX_TRIES_HEAL;
public static final ForgeConfigSpec.ConfigValue<Integer> MAX_VAULTS;
public static final ForgeConfigSpec.ConfigValue<List<String>> EXCLUDE_DIMS;
public static final ForgeConfigSpec.ConfigValue<Double> CHANCE_OF_PLAYER_HEAD;
public static final ForgeConfigSpec.ConfigValue<Boolean> ENABLE_PLAYER_HEAD_DROPS;
public static final ForgeConfigSpec.BooleanValue USE_CUSTOM_JOINLEAVE;
public static final ForgeConfigSpec.BooleanValue USE_CUSTOM_CHATREPLACER;
public static final ForgeConfigSpec.ConfigValue<Boolean> ENABLE_DEATH_MESSAGES;
public static final ForgeConfigSpec.ConfigValue<Boolean> GIVE_KIT_EVERY_CHANGE;
public static final ForgeConfigSpec.ConfigValue<Boolean> DEBUG;
static {
List<String> defaultExcludeDimensions = new ArrayList<String>();
defaultExcludeDimensions.add("minecraft:the_nether"); // Excluded to make mining for Ancient Debris easier
defaultExcludeDimensions.add("minecraft:the_end"); // Excluded due to End Crystals
BUILDER.push("OTE");
DEBUG = BUILDER.comment("Turn on debug messages in the console for all OTE functions? This could be spammy").define("debug_enabled", false);
BUILDER.push("STARTERKIT");
GIVE_KIT_EVERY_CHANGE = BUILDER.comment("Enable this to give the starter kit every time it is changed, regardless of whether the player has already received that kit on their next join.").define("starter_kit_given_on_change", false);
BUILDER.pop();
MAX_VAULTS = BUILDER.comment("What is the maximum number of vaults a player may have available? (0 is unlimited)").define("max_vaults", 0);
ITEM_DESPAWN_TIMER = BUILDER.comment("How many times should the item's expire be cancelled. The vanilla expire time is 5 minutes, so this would be ticked down once every 5 minutes.").define("item_extra_lives", 2);
ENABLE_DEATH_MESSAGES = BUILDER.comment("Whether you want to enable the death messages to be output by OTEMod when a player dies. These can be quite random!").define("enable_ote_death_msgs", true);
BUILDER.push("drops");
ENABLE_PLAYER_HEAD_DROPS = BUILDER.comment("Whether to enable dropping of player Heads").define("enable_player_head_drops", true);
SPAWN_EGG_CHANCE = BUILDER.comment("What is the chance for a spawn egg to drop from a mob when looting 3 is used? Default: 0.25").define("spawn_egg_chance", 0.25);
CHANCE_OF_PLAYER_HEAD = BUILDER.comment("Chance of a player head dropping on death").define("player_death_drops_head", 0.5);
BUILDER.pop();
BUILDER.pop();
BUILDER.push("COMMANDS");
RTP_COOLDOWN = BUILDER.comment("How many seconds between RTP uses? This can be quite laggy on the server due to the potential that new chunks are getting generated").define("rtp.cooldown", 30); // Default of 30 should be enough
BUILDER.pop();
BUILDER.push("ANTIGRIEF").comment("AntiGrief Explosion Healing Events");
HEALER_TIMER = BUILDER.comment("Time between healing events (In Milliseconds)").define("timer", 250); // Should this be lower?
DEBUG_HEALER = BUILDER.comment("Whether or not to debug the healer engine. (Saves as SNBT instead of NBT)").define("debug", false);
TIME_BETWEEN_BLOCKS = BUILDER.comment("The amount of time between restoring blocks (Maximum). This is in ticks").define("time_between", 25);
MAX_TRIES_HEAL = BUILDER.comment("Maximum amount of retries to restore a block").define("max_tries", 6);
List<String> defDims = new ArrayList<String>();
defDims.add("minecraft:the_end");
defDims.add("minecraft:the_nether");
defDims.add("thresholds:resource");
EXCLUDE_DIMS = BUILDER.comment("Dimension names (ex. minecraft:overworld) to exclude from the explosion healing events").define("exclude_dimensions", defDims);
BUILDER.pop();
BUILDER.push("CHATSERVER");
USE_CUSTOM_JOINLEAVE = BUILDER.comment("Whether to use the custom join and leave messages").define("join_leave_messages", true);
USE_CUSTOM_CHATREPLACER = BUILDER.comment("Whether to use the custom chat replacer (If disabled the relevant commands will be removed)").define("chatprettifier", true);
BUILDER.pop();
SPEC=BUILDER.build();
}
}

View file

@ -0,0 +1,29 @@
package dev.zontreck.thresholds.database;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import dev.zontreck.libzontreck.util.FileTreeDatastore;
public class OTEDatastore extends FileTreeDatastore
{
private static final Path OTEBASE;
static{
Path X = FileTreeDatastore.of("otemod");
OTEBASE=X;
if(!OTEBASE.toFile().exists())
{
try {
Files.createDirectory(OTEBASE);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static Path of(String nick)
{
return OTEBASE.resolve(nick);
}
}

View file

@ -0,0 +1,99 @@
package dev.zontreck.thresholds.effects;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.util.ItemUtils;
import dev.zontreck.libzontreck.util.ServerUtilities;
import dev.zontreck.thresholds.enchantments.ModEnchantments;
import dev.zontreck.thresholds.implementation.Messages;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Abilities;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.fml.LogicalSide;
import org.jetbrains.annotations.Nullable;
public class FlightEffect extends MobEffect {
protected FlightEffect(MobEffectCategory pCategory, int pColor) {
super(pCategory, pColor);
}
@Override
public void applyEffectTick(LivingEntity pLivingEntity, int pAmplifier) {
super.applyEffectTick(pLivingEntity, pAmplifier);
if(LibZontreck.CURRENT_SIDE == LogicalSide.CLIENT) return;
if(pLivingEntity instanceof Player)
{
if(LibZontreck.CURRENT_SIDE == LogicalSide.SERVER)
{
ServerPlayer player = ServerUtilities.getPlayerByID(pLivingEntity.getStringUUID());
recheck(player);
}
}
}
@Override
public boolean isDurationEffectTick(int pDuration, int pAmplifier) {
return true;
}
@Override
public void applyInstantenousEffect(@Nullable Entity pSource, @Nullable Entity pIndirectSource, LivingEntity pLivingEntity, int pAmplifier, double pHealth) {
if(LibZontreck.CURRENT_SIDE == LogicalSide.CLIENT) return;
if(pLivingEntity instanceof Player)
{
ServerPlayer player = ServerUtilities.getPlayerByID(pLivingEntity.getStringUUID());
recheck(player);
}
super.applyInstantenousEffect(pSource, pIndirectSource, pLivingEntity, pAmplifier, pHealth);
}
private static void recheck(ServerPlayer sp)
{
if(sp.gameMode.isCreative())return; // Don't mess with the creative mode attributes
ItemStack feet = sp.getItemBySlot(EquipmentSlot.FEET);
boolean hasFlight = false;
if(ItemUtils.getEnchantmentLevel(ModEnchantments.FLIGHT_ENCHANTMENT.get(), feet)>0)hasFlight=true;
if(!hasFlight)
{
sp.removeEffect(ModEffects.FLIGHT.get());
}
Abilities playerAbilities = sp.getAbilities();
if(hasFlight)
{
if(playerAbilities.mayfly == false)
{
playerAbilities.mayfly=true;
sp.onUpdateAbilities();
ChatHelpers.broadcastTo(sp, ChatHelpers.macro(Messages.FLIGHT_GIVEN), sp.server);
}
}else {
if(playerAbilities.mayfly)
{
playerAbilities.mayfly=false;
playerAbilities.flying=false;
sp.onUpdateAbilities();
ChatHelpers.broadcastTo(sp, ChatHelpers.macro(Messages.FLIGHT_REMOVED), sp.server);
}
}
}
}

View file

@ -0,0 +1,23 @@
package dev.zontreck.thresholds.effects;
import dev.zontreck.thresholds.ThresholdsMod;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class ModEffects
{
public static final DeferredRegister<MobEffect> REGISTRY = DeferredRegister.create(ForgeRegistries.MOB_EFFECTS, ThresholdsMod.MOD_ID);
public static final RegistryObject<MobEffect> FLIGHT = REGISTRY.register("flight", ()->new FlightEffect(MobEffectCategory.BENEFICIAL, 0xFF0000FF));
public static void register(IEventBus bus)
{
REGISTRY.register(bus);
}
}

View file

@ -0,0 +1,33 @@
package dev.zontreck.thresholds.enchantments;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
public class BorrowedProtectionEnchantment extends Enchantment
{
protected BorrowedProtectionEnchantment(Rarity pRarity, EnchantmentCategory pCategory, EquipmentSlot[] pApplicableSlots) {
super(pRarity, pCategory, pApplicableSlots);
}
@Override
public boolean isCurse() {
return false;
}
@Override
public boolean isTradeable() {
return true;
}
@Override
public boolean isDiscoverable() {
return true;
}
@Override
public boolean isTreasureOnly() {
return false;
}
}

View file

@ -0,0 +1,106 @@
package dev.zontreck.thresholds.enchantments;
import dev.zontreck.libzontreck.util.ItemUtils;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import dev.zontreck.thresholds.effects.ModEffects;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.Mod;
import java.util.concurrent.atomic.AtomicInteger;
@Mod.EventBusSubscriber(modid = ThresholdsMod.MOD_ID)
public class FlightEnchantment extends Enchantment
{
public FlightEnchantment(EquipmentSlot... slots)
{
super(Rarity.VERY_RARE, EnchantmentCategory.ARMOR_FEET, slots);
}
@Override
public int getMaxLevel()
{
return 1;
}
@Override
public int getMinCost(int level)
{
return 28 + (level - 1) * 15;
}
@Override
public int getMaxCost(int level)
{
return this.getMinCost(level) + 15;
}
@Override
public boolean isTreasureOnly(){
return true;
}
@Override
public boolean isTradeable()
{
return true;
}
// Not a bug. Flight is meant to be a permanent upgrade to a item. It is considered a curse due to unstable behavior. Flight will eat up durability and forge energy
// Flight should NOT be able to be removed via the grindstone
@Override
public boolean isCurse()
{
return true;
}
public static AtomicInteger TICKS = new AtomicInteger(0);
@SubscribeEvent
public static void onEnchantmentTick(TickEvent.PlayerTickEvent event)
{
if(event.side == LogicalSide.CLIENT) return;
if(TICKS.getAndIncrement() >= (5*20))
{
TICKS.set(0);
if(ThresholdsServerConfig.DEBUG.get())
{
ThresholdsMod.LOGGER.info("> Flight Enchantment Tick <");
}
if(event.phase == TickEvent.Phase.END)
{
ServerPlayer sp = (ServerPlayer) event.player;
ItemStack feet = sp.getItemBySlot(EquipmentSlot.FEET);
boolean hasFlight = false;
if(ItemUtils.getEnchantmentLevel(ModEnchantments.FLIGHT_ENCHANTMENT.get(), feet)>0)hasFlight=true;
if(hasFlight)
{
MobEffectInstance inst = new MobEffectInstance(ModEffects.FLIGHT.get(), -1, 0, false, false, true);
event.player.addEffect(inst);
}
}
}
}
}

View file

@ -0,0 +1,75 @@
package dev.zontreck.thresholds.enchantments;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
public class MobEggEnchantment extends Enchantment
{
public static final String TAG_BIAS = "mob_egging_bias";
public MobEggEnchantment()
{
super(Rarity.VERY_RARE, EnchantmentCategory.WEAPON, new EquipmentSlot[] {EquipmentSlot.MAINHAND});
}
@Override
public int getMaxLevel()
{
return 6;
}
@Override
public int getMinCost(int level)
{
return 28 + (level - 1) * 15;
}
@Override
public int getMaxCost(int level)
{
return this.getMinCost(level) + 15;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack)
{
return super.canApplyAtEnchantingTable(stack);
}
@Override
public boolean isTreasureOnly(){
return false;
}
@Override
public boolean isTradeable()
{
return true;
}
@Override
public boolean isDiscoverable()
{
return false;
}
public static boolean givesEgg(int level, int bias)
{
double CHANCE = ThresholdsServerConfig.SPAWN_EGG_CHANCE.get() * 100;
CHANCE *= (level / 0.5);
CHANCE += bias;
double rng = Math.random()*100000;
if(ThresholdsServerConfig.DEBUG.get())
{
ThresholdsMod.LOGGER.info("Spawn Egg Chance (" + CHANCE + ") [" + rng + "]");
}
return (rng <= CHANCE);
}
}

View file

@ -0,0 +1,28 @@
package dev.zontreck.thresholds.enchantments;
import dev.zontreck.thresholds.ThresholdsMod;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class ModEnchantments {
protected static final EquipmentSlot[] ARMOR_SLOTS = new EquipmentSlot[]{EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
public static final DeferredRegister<Enchantment> REGISTERS = DeferredRegister.create(ForgeRegistries.ENCHANTMENTS, ThresholdsMod.MOD_ID);
public static final RegistryObject<Enchantment> MOB_EGGING_ENCHANTMENT = REGISTERS.register("mob_egging", ()->new MobEggEnchantment());
public static final RegistryObject<Enchantment> FLIGHT_ENCHANTMENT = REGISTERS.register("player_flight", ()->new FlightEnchantment(EquipmentSlot.FEET));
public static final RegistryObject<Enchantment> BORROWED_PROTECTION = REGISTERS.register("borrowed_protection", ()->new BorrowedProtectionEnchantment(Enchantment.Rarity.UNCOMMON, EnchantmentCategory.ARMOR, ARMOR_SLOTS));
public static final RegistryObject<Enchantment> NIGHT_VISION_ENCHANT = REGISTERS.register("night_vision", ()->new NightVisionEnchantment(EquipmentSlot.HEAD));
public static void register(IEventBus bus){
REGISTERS.register(bus);
}
}

View file

@ -0,0 +1,93 @@
package dev.zontreck.thresholds.enchantments;
import dev.zontreck.libzontreck.util.ItemUtils;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.Mod;
import java.util.concurrent.atomic.AtomicInteger;
@Mod.EventBusSubscriber(modid = ThresholdsMod.MOD_ID)
public class NightVisionEnchantment extends Enchantment
{
public NightVisionEnchantment(EquipmentSlot... slots)
{
super(Rarity.VERY_RARE, EnchantmentCategory.ARMOR_HEAD, slots);
}
@Override
public int getMaxLevel()
{
return 1;
}
@Override
public boolean isTreasureOnly(){
return true;
}
@Override
public boolean isTradeable()
{
return true;
}
// Not a bug. Flight is meant to be a permanent upgrade to a item. It is considered a curse due to unstable behavior. Flight will eat up durability and forge energy
// Flight should NOT be able to be removed via the grindstone
@Override
public boolean isCurse()
{
return false;
}
public static AtomicInteger TICKS = new AtomicInteger(0);
@SubscribeEvent
public static void onEnchantmentTick(TickEvent.PlayerTickEvent event)
{
if(event.side == LogicalSide.CLIENT) return;
if(TICKS.getAndIncrement() >= (2*20))
{
TICKS.set(0);
if(ThresholdsServerConfig.DEBUG.get())
{
ThresholdsMod.LOGGER.info("> NVision Enchantment Tick <");
}
if(event.phase == TickEvent.Phase.END)
{
ServerPlayer sp = (ServerPlayer) event.player;
ItemStack feet = sp.getItemBySlot(EquipmentSlot.HEAD);
boolean hasNV = false;
if(ItemUtils.getEnchantmentLevel(ModEnchantments.NIGHT_VISION_ENCHANT.get(), feet)>0)hasNV=true;
if(hasNV)
{
MobEffectInstance inst = new MobEffectInstance(MobEffects.NIGHT_VISION, 60*20, 4, false, false, true);
event.player.addEffect(inst);
}
}
}
}
}

View file

@ -0,0 +1,15 @@
package dev.zontreck.thresholds.entities;
import net.minecraftforge.eventbus.api.IEventBus;
public class ModEntityTypes {
//public static final DeferredRegister<EntityType<?>> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, OTEMod.MOD_ID);
//public static final RegistryObject<EntityType<? extends PossumEntity>> POSSUM = ENTITIES.register("possum", ()-> EntityType.Builder.of(PossumEntity::new, MobCategory.CREATURE).sized(1.5f, 0.5f).build(new ResourceLocation(OTEMod.MOD_ID, "possum").toString()));
public static void register(IEventBus bus){
//ENTITIES.register(bus);
}
}

View file

@ -0,0 +1,59 @@
package dev.zontreck.thresholds.entities.monsters;
public class PossumEntity
{
/*
public PossumEntity(EntityType<? extends Animal> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
//TODO Auto-generated constructor stub
}
private AnimationFactory factory = GeckoLibUtil.createFactory(this);
@Override
public AnimationFactory getFactory() {
return factory;
}
@Override
public PossumEntity getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) {
return (PossumEntity) ModEntityTypes.POSSUM.get().create(pLevel);
}
@Override
public boolean isFood(ItemStack pStack)
{
return pStack.is(Items.APPLE);
}
public static AttributeSupplier createAttributes() {
return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 12.0D).add(Attributes.MOVEMENT_SPEED, (double)0.2F).build();
}
private <E extends IAnimatable> PlayState predicate(AnimationEvent<E> ev)
{
if(ev.isMoving())
{
// change anim
return PlayState.CONTINUE;
}
ev.getController().setAnimation(new AnimationBuilder().addAnimation("animation.model.idle", ILoopType.EDefaultLoopTypes.LOOP));
return PlayState.CONTINUE;
}
@Override
public void registerControllers(AnimationData data) {
data.addAnimationController(new AnimationController<IAnimatable>(this, "controller", 0, this::predicate));
}
@Override
public void registerGoals()
{
this.goalSelector.addGoal(0, new FloatGoal(this));
this.goalSelector.addGoal(1, new WaterAvoidingRandomStrollGoal(this, 1));
}*/
}

View file

@ -0,0 +1,22 @@
package dev.zontreck.thresholds.entities.monsters.client;
public class PossumModel
{
/*
@Override
public ResourceLocation getAnimationFileLocation(PossumEntity animatable) {
return new ResourceLocation(OTEMod.MOD_ID, "animations/possum.animation.json");
}
@Override
public ResourceLocation getModelLocation(PossumEntity object) {
return new ResourceLocation(OTEMod.MOD_ID, "geo/possum.geo.json");
}
@Override
public ResourceLocation getTextureLocation(PossumEntity object) {
return new ResourceLocation(OTEMod.MOD_ID, "textures/entity/possum_texture.png");
}*/
}

View file

@ -0,0 +1,29 @@
package dev.zontreck.thresholds.entities.monsters.client;
public class PossumRenderer
{
/*
public PossumRenderer(EntityRendererProvider.Context renderManager) {
super(renderManager, new PossumModel());
this.shadowRadius=0.3f;
}
@Override
public ResourceLocation getTextureLocation(PossumEntity entity)
{
return new ResourceLocation(OTEMod.MOD_ID, "textures/entity/possum_texture.png");
}
@Override
public RenderType getRenderType(PossumEntity animatable, float partialTicks,
PoseStack stack, MultiBufferSource buffer,
VertexConsumer consumer, int packed, ResourceLocation loc)
{
return super.getRenderType(animatable, partialTicks, stack, buffer, consumer, packed, loc);
}
*/
}

View file

@ -0,0 +1,39 @@
package dev.zontreck.thresholds.events;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.integrations.KeyBindings;
import dev.zontreck.thresholds.networking.ModMessages;
import dev.zontreck.thresholds.networking.packets.OpenVaultC2SPacket;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.time.Instant;
public class ClientEvents {
@Mod.EventBusSubscriber(modid = ThresholdsMod.MOD_ID, value = Dist.CLIENT)
public static class ForgeEvents
{
// Timeout!
static long lastPress;
@SubscribeEvent
public static void onKeyInput(InputEvent.Key event)
{
//OTEMod.LOGGER.info("KEY PRESS: "+event.getKey());
if(KeyBindings.OPEN_VAULT.matches(event.getKey(), event.getScanCode()) && Minecraft.getInstance().screen == null && lastPress+10 < Instant.now().getEpochSecond())
{
lastPress = Instant.now().getEpochSecond();
ModMessages.sendToServer(new OpenVaultC2SPacket(0, false, 0));
}
}
}
@Mod.EventBusSubscriber(modid = ThresholdsMod.MOD_ID, value=Dist.CLIENT, bus=Mod.EventBusSubscriber.Bus.MOD)
public static class ClientModBus
{
}
}

View file

@ -0,0 +1,138 @@
package dev.zontreck.thresholds.events;
import dev.zontreck.libzontreck.lore.LoreContainer;
import dev.zontreck.libzontreck.lore.LoreEntry;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.util.ItemUtils;
import dev.zontreck.libzontreck.util.heads.HeadUtilities;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import dev.zontreck.thresholds.enchantments.MobEggEnchantment;
import dev.zontreck.thresholds.enchantments.ModEnchantments;
import dev.zontreck.thresholds.implementation.DeathMessages;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraftforge.common.ForgeSpawnEggItem;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.time.Instant;
import java.util.Date;
import java.util.Random;
@Mod.EventBusSubscriber(modid= ThresholdsMod.MOD_ID)
public class EventHandler {
@SubscribeEvent (priority = EventPriority.HIGHEST)
public static void playerDied(LivingDeathEvent event)
{
if(!(event.getEntity() instanceof Player))return;
Profile profile;
try {
profile = Profile.get_profile_of(event.getEntity().getStringUUID());
} catch (UserProfileNotYetExistsException e) {
e.printStackTrace();
return;
}
profile.deaths++;
profile.commit();
if(!ThresholdsServerConfig.ENABLE_PLAYER_HEAD_DROPS.get())
{
return;
}
int looting=0;
//ServerPlayer killedPlayer = (ServerPlayer)ent;
if(event.getEntity() instanceof Player){
ServerPlayer pla = profile.player;
looting = ItemUtils.getEnchantmentLevel(Enchantments.MOB_LOOTING, pla.getMainHandItem());
}
// Calculate chance
double base_chance = ThresholdsServerConfig.CHANCE_OF_PLAYER_HEAD.get();
base_chance += looting;
base_chance *= 100;
Random rng = new Random();
double num = rng.nextDouble(0,100000);
if(num <= base_chance)
{
ItemStack head = HeadUtilities.get(profile.username, "").setHoverName(ChatHelpers.macro(profile.nickname+"'s Head"));
LoreContainer lore = new LoreContainer(head);
LoreEntry entry = new LoreEntry.Builder().bold(true).text(ChatHelpers.macroize("!dark_green!Player: " + profile.name_color+profile.username)).build();
lore.miscData.loreData.add(entry);
entry = new LoreEntry.Builder().text(ChatHelpers.macroize("!Dark_Purple!Date: !Dark_Red![0]", Date.from(Instant.now()).toString())).build();
lore.miscData.loreData.add(entry);
entry = new LoreEntry.Builder().text(ChatHelpers.macroize("!Dark_Purple!Total Deaths: !Dark_Red![0]", String.valueOf(profile.deaths))).build();
lore.miscData.loreData.add(entry);
lore.commitLore();
event.getEntity().spawnAtLocation(head);
}
try {
ChatHelpers.broadcast(Component.literal(DeathMessages.getRandomDeathMessage(Profile.get_profile_of(event.getEntity().getStringUUID()), event.getSource())), event.getEntity().level().getServer());
} catch (UserProfileNotYetExistsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@SubscribeEvent
public void onEntityKilled(LivingDropsEvent ev){
if(ev.getEntity().level().isClientSide)return;
Entity killedentity = ev.getEntity();
Entity ent = ev.getSource().getEntity();
if(ent instanceof Player)
{
ServerPlayer play = (ServerPlayer)ent;
LivingEntity killed = ev.getEntity();
ItemStack stack = play.getMainHandItem();
int levelOfEgging = ItemUtils.getEnchantmentLevel(ModEnchantments.MOB_EGGING_ENCHANTMENT.get(),stack);
if(levelOfEgging==0)return;
CompoundTag tag = stack.getTag();
int bias = tag.getInt(MobEggEnchantment.TAG_BIAS);
if(MobEggEnchantment.givesEgg(levelOfEgging, bias))
{
bias=0;
tag.putInt(MobEggEnchantment.TAG_BIAS, bias);
// .25% chance
// Check enchantment level for looting
int level = ItemUtils.getEnchantmentLevel (Enchantments.MOB_LOOTING,stack);
if(level==3){
ItemStack egg = new ItemStack(ForgeSpawnEggItem.fromEntityType(killed.getType()));
ev.getDrops().add(new ItemEntity(killed.level(), killed.getX(), killed.getY(), killed.getZ(), egg));
//LoreHandlers.updateItem(stack, ItemStatType.EGGING);
}
}else{
bias += 1;
tag.putInt(MobEggEnchantment.TAG_BIAS, bias);
}
}
}
}

View file

@ -0,0 +1,155 @@
package dev.zontreck.thresholds.events;
import dev.zontreck.thresholds.ThresholdsMod;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(modid= ThresholdsMod.MOD_ID, bus=Mod.EventBusSubscriber.Bus.FORGE)
public class LoreHandlers {
/*
@SubscribeEvent
public void onBlockMined(BlockEvent.BreakEvent ev)
{
if(ev.getLevel().isClientSide())return;
ServerPlayer sp = (ServerPlayer)ev.getPlayer();
ItemStack itemUsed = sp.getItemInHand(InteractionHand.MAIN_HAND);
ResourceLocation loc = ForgeRegistries.ITEMS.getKey(itemUsed.getItem());
String itemModName = ChatHelpers.macroize("[0]:[1]", loc.getNamespace(), loc.getPath());
if(itemModName.contains("pickaxe"))
{
updateItem(itemUsed, ItemStatType.PICK);
}else if(itemModName.contains("shovel"))
{
updateItem(itemUsed, ItemStatType.SHOVEL);
} else if(itemModName.contains("axe"))
{
updateItem(itemUsed, ItemStatType.AXE);
} else if(itemModName.contains("pickadze"))
{
updateItem(itemUsed, ItemStatType.PICK);
}
}
@SubscribeEvent
public void onBlock(BlockEvent.BlockToolModificationEvent ev)
{
if(ev.getLevel().isClientSide())return;
// Check the block right clicked, and the item in hand
ServerPlayer sp = (ServerPlayer)ev.getPlayer();
ItemStack itemUsed = sp.getMainHandItem();
BlockState bs = ev.getState();
ResourceLocation loc = ForgeRegistries.ITEMS.getKey(itemUsed.getItem());
String itemModName = ChatHelpers.macroize("[0]:[1]", loc.getNamespace(), loc.getPath());
if(itemModName.contains("hoe"))
{
if(bs.is(Blocks.DIRT) || bs.is(Blocks.GRASS_BLOCK))
{
OTEMod.LOGGER.info("DIRT!");
updateItem(itemUsed, ItemStatType.HOE);
}
} else if(itemModName.contains("shovel"))
{
if(bs.is(Blocks.GRASS_BLOCK))
{
updateItem(itemUsed, ItemStatType.SHOVELPATH);
}
}
}
@SubscribeEvent
public void onShears(PlayerInteractEvent.EntityInteract ev)
{
if(ev.getLevel().isClientSide)return;
if(ev.getCancellationResult() == InteractionResult.PASS)
{
// Check the entity right-clicked, and the item in hand
OTEMod.LOGGER.info("Success");
ServerPlayer sp = (ServerPlayer)ev.getEntity();
ItemStack itemUsed = sp.getMainHandItem();
Entity target = ev.getTarget();
ResourceLocation loc = ForgeRegistries.ITEMS.getKey(itemUsed.getItem());
String itemModName = ChatHelpers.macroize("[0]:[1]", loc.getNamespace(), loc.getPath());
ResourceLocation locEnt = ForgeRegistries.ENTITY_TYPES.getKey(ev.getTarget().getType());
String entityModName = ChatHelpers.macroize("[0]:[1]", locEnt.getNamespace(), locEnt.getPath());
if(itemModName.contains("shears"))
{
if(entityModName.contains("sheep"))
{
updateItem(itemUsed, ItemStatType.SHEARS);
}
}
}
}
@SubscribeEvent
public void onEntityKilled(LivingDeathEvent ev)
{
if(ev.getEntity().level().isClientSide)return;
// Handle two things
// 1. Update mob kill count on a sword if wielded.
// 2. If mob, process randomness. If death by player with looting 3, 0.1% chance for a spawn egg to drop
Entity source = ev.getSource().getEntity();
ServerPlayer sp= null;
if(source instanceof Player)
{
sp = (ServerPlayer)source;
}
if(sp==null)return;
ItemStack weaponUsed = sp.getItemInHand(InteractionHand.MAIN_HAND);
ResourceLocation loc = ForgeRegistries.ITEMS.getKey(weaponUsed.getItem());
String itemModName = ChatHelpers.macroize("[0]:[1]", loc.getNamespace(), loc.getPath());
if(itemModName.contains("sword"))
{
updateItem(weaponUsed, ItemStatType.SWORD);
}
}
// Only valid to be used by OTEMod
protected static void updateItem(ItemStack weaponUsed, ItemStatType type)
{
// Update the mob kill count
CompoundTag props = weaponUsed.getTag();
if(props==null)props=new CompoundTag();
CompoundTag container = props.getCompound(ItemStatTag.STATS_TAG+"_"+type.name().toLowerCase());
LoreContainer contain = new LoreContainer(weaponUsed);
ItemStatTag isTag;
try{
isTag = new ItemStatTag(type, container.getInt(ItemStatTag.STATS_TAG+"_"+type.name().toLowerCase()));
}catch (Exception e){
isTag = new ItemStatTag(type, 0);
}
isTag.increment();
LoreEntry entry;
if(contain.miscData.loreData.size()==0)
{
// Missing entry
entry = new LoreEntry.Builder().text(ItemStatistics.makeText(isTag)).build();
contain.miscData.loreData.add(entry);
}else {
entry = contain.miscData.loreData.get(0); // Stat is set at 0
entry.text = ItemStatistics.makeText(isTag);
}
// Update item
contain.commitLore();
}*/
}

View file

@ -0,0 +1,17 @@
package dev.zontreck.thresholds.events;
import dev.zontreck.thresholds.ThresholdsMod;
import net.minecraftforge.event.entity.EntityAttributeCreationEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
@Mod.EventBusSubscriber(modid = ThresholdsMod.MOD_ID, bus = Bus.MOD)
public class ModEventBusEvents {
@SubscribeEvent
public static void onMobAttributeCreation(EntityAttributeCreationEvent ev)
{
//ev.put((EntityType<? extends LivingEntity>) ModEntityTypes.POSSUM.get(), PossumEntity.createAttributes());
ThresholdsMod.LOGGER.info("/!\\ REGISTERING ATTRIBUTES /!\\");
}
}

View file

@ -0,0 +1,38 @@
package dev.zontreck.thresholds.implementation;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.items.ModItems;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
@Mod.EventBusSubscriber(modid = ThresholdsMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class CreativeModeTabs
{
public static final DeferredRegister<CreativeModeTab> REGISTER = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, ThresholdsMod.MOD_ID);
public static final List<Supplier<? extends ItemLike>> OTEMOD_TAB_ITEMS = new ArrayList<>();
public static final RegistryObject<CreativeModeTab> OTE_TAB = REGISTER.register("otemod", () -> CreativeModeTab.builder()
.title(Component.translatable("itemGroup.tabs.otemod"))
.icon(ModItems.IHAN_CRYSTAL.get()::getDefaultInstance)
.displayItems((display, output) -> OTEMOD_TAB_ITEMS.forEach(it->output.accept(it.get())))
.build()
);
public static <T extends Item> RegistryObject<T> addToOTEModTab(RegistryObject<T> itemLike)
{
OTEMOD_TAB_ITEMS.add(itemLike);
return itemLike;
}
}

View file

@ -0,0 +1,58 @@
package dev.zontreck.thresholds.implementation;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.util.ChatHelpers;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageTypes;
public class DeathMessages {
private static final List<String> messages;
private static final List<String> messages_falling;
static{
messages=new ArrayList<>();
messages_falling = new ArrayList<>();
messages.add("!Dark_Red!On their [0] death, [1]!Dark_Red! was reduced to a jittering flesh pile");
messages.add("!Dark_Red![1]!Dark_Red! experienced their [0] death, while running away in fear from [2]");
messages.add("!Dark_Red![1] was eaten alive by [2]");
messages.add("!Dark_Red!For their [0] death, [1]!Dark_Red! got a little bit too careless!");
messages.add("!Dark_Red!Not all whimpering messes are good, as [1]!Dark_Red! is evidence of.");
messages.add("!Dark_Red![0]!? Seriously?! Come on! [1]!Dark_Red! you can do better than this!");
messages.add("!Dark_Red!What is that... the [0]th time? For fucks sake, I'm not even surprised anymore.");
messages_falling.add("!Dark_Red![1]!Dark_Red!... oh my dear sweet [1]!Dark_Red!, oh you sweet summer child with ribbons in your hair... you cannot in fact, fly, (yet)");
messages_falling.add("!Dark_Red![1]!Dark_Red! clearly had the delusion they could fly.... their [0] death says otherwise.");
messages_falling.add("!Dark_Red![1]!Dark_Red! tried flying, but forgot their wings");
}
public static String getRandomDeathMessage(Profile playerWhoDied, DamageSource source)
{
Random rng = new Random();
int msg = rng.nextInt(0, messages.size()-1);
String sourceName="";
if(source.isCreativePlayer())
{
sourceName = "A godlike player";
}
if(source.is(DamageTypes.FALL))
{
msg = rng.nextInt(0,messages_falling.size()-1);
return ChatHelpers.macroize(messages_falling.get(msg), String.valueOf(playerWhoDied.deaths), playerWhoDied.name_color + playerWhoDied.nickname);
}
if(source.getEntity() != null)
{
if(sourceName.equals(""))
{
sourceName = source.getEntity().getName().getString();
}
} else sourceName = "an imaginary zombie!";
return ChatHelpers.macroize(messages.get(msg), String.valueOf(playerWhoDied.deaths), playerWhoDied.name_color + playerWhoDied.nickname, sourceName);
}
}

View file

@ -0,0 +1,78 @@
package dev.zontreck.thresholds.implementation;
import dev.zontreck.thresholds.database.OTEDatastore;
import net.minecraft.nbt.*;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.GameType;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
public class InventoryBackup extends OTEDatastore
{
ServerPlayer player;
File my_file;
ListTag list;
public static final Path FILE_TREE_PATH = of("gamemode_inventories");
public InventoryBackup(ServerPlayer player, GameType mode)
{
this.player = player;
if(!FILE_TREE_PATH.toFile().exists())
{
FILE_TREE_PATH.toFile().mkdir();
}
var temp = FILE_TREE_PATH.resolve(player.getStringUUID());
if(!temp.toFile().exists()) temp.toFile().mkdir();
my_file = temp.resolve(mode.getName() + ".nbt").toFile();
}
public void restore()
{
try {
if(!my_file.exists())
{
list = new ListTag();
return;
}
CompoundTag tag = NbtIo.read(my_file);
list = tag.getList("inventory", Tag.TAG_COMPOUND);
} catch (IOException e) {
e.printStackTrace();
}
}
public void save()
{
try{
CompoundTag tag = new CompoundTag();
list = new ListTag();
list = player.getInventory().save(list);
tag.put("inventory", list);
NbtIo.write(tag, my_file);
}catch(Exception e)
{
e.printStackTrace();
}
}
public void apply()
{
try {
player.getInventory().load(list);
}catch(Exception e)
{
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,32 @@
package dev.zontreck.thresholds.implementation;
public class Messages {
public static final String THRESHOLDS_PREFIX;
public static final String PREFIX_UPDATED;
public static final String PREFIX_COLOR_UPDATED;
public static final String NICK_UPDATED;
public static final String NAME_COLOR_UPDATED;
public static final String CHAT_COLOR_UPDATED;
public static final String STARTER_FAILURE_CONSOLE;
public static final String STARTER_FAILURE_PERMISSIONS;
public static final String STARTER_KIT_GIVEN;
public static final String FLIGHT_GIVEN;
public static final String FLIGHT_REMOVED;
static{
THRESHOLDS_PREFIX = "!Dark_Gray![!Dark_Purple!Thresholds!Dark_Gray!] ";
PREFIX_UPDATED = THRESHOLDS_PREFIX + " !Dark_Purple!Your prefix has been updated";
PREFIX_COLOR_UPDATED = THRESHOLDS_PREFIX + "!Dark_Purple!Your prefix color has been updated";
NICK_UPDATED = THRESHOLDS_PREFIX + "!Dark_Purple! Your nickname has been updated";
NAME_COLOR_UPDATED = THRESHOLDS_PREFIX + "!Dark_Purple!Your name color has been updated";
CHAT_COLOR_UPDATED = THRESHOLDS_PREFIX + "!Dark_Purple!Your chat color has been updated";
STARTER_FAILURE_CONSOLE = THRESHOLDS_PREFIX + "!Dark_Red!This command can only be executed from within the game";
STARTER_FAILURE_PERMISSIONS = THRESHOLDS_PREFIX + "!Dark_Red!This command can only be executed by server operators";
STARTER_KIT_GIVEN = THRESHOLDS_PREFIX + "!Dark_Purple!You have been given a starter kit. Welcome to the server.";
FLIGHT_GIVEN = THRESHOLDS_PREFIX + "!Dark_Green!You start to feel lighter than a feather";
FLIGHT_REMOVED = THRESHOLDS_PREFIX + "!Dark_Red!You have a sinking feeling you are no longer lighter than a feather.";
}
}

View file

@ -0,0 +1,19 @@
package dev.zontreck.thresholds.implementation;
public class MouseHelpers {
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int sizeX, int sizeY)
{
return (mouseX>=x && mouseX <= x+sizeX) && (mouseY >= y && mouseY <= y+sizeY);
}
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int size)
{
return isMouseOver(mouseX, mouseY, x, y, size,size);
}
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y)
{
return isMouseOver(mouseX, mouseY, x, y, 16);
}
}

View file

@ -0,0 +1,44 @@
package dev.zontreck.thresholds.implementation;
import net.minecraft.core.NonNullList;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.ItemStackHandler;
public class OutputItemStackHandler extends ItemStackHandler {
private final ItemStackHandler internalSlot;
public OutputItemStackHandler(ItemStackHandler hidden) {
super();
internalSlot = hidden;
}
@Override
public void setSize(int size) {
stacks = NonNullList.<ItemStack>withSize(size, ItemStack.EMPTY);
}
@Override
public void setStackInSlot(int slot, ItemStack stack) {
internalSlot.setStackInSlot(slot, stack);
}
@Override
public int getSlots() {
return internalSlot.getSlots();
}
@Override
public ItemStack getStackInSlot(int slot) {
return internalSlot.getStackInSlot(slot);
}
@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
return stack;
}
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
return internalSlot.extractItem(slot, amount, simulate);
}
}

View file

@ -0,0 +1,38 @@
package dev.zontreck.thresholds.implementation;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.LongTag;
import java.time.Instant;
public class PlayerFirstJoinTag
{
private PlayerFirstJoinTag(long time)
{
LastGiven = time;
}
public long LastGiven;
public static final String ID = "firstjoin";
public static final String LAST_GIVEN_TAG = "last";
public static PlayerFirstJoinTag now()
{
return new PlayerFirstJoinTag(Instant.now().getEpochSecond());
}
public void save(CompoundTag parent)
{
CompoundTag tag = new CompoundTag();
tag.put(LAST_GIVEN_TAG, LongTag.valueOf(LastGiven));
parent.put(ID, tag);
}
public static PlayerFirstJoinTag load(CompoundTag tag)
{
if(!tag.contains(ID)) return null;
CompoundTag me = tag.getCompound(ID);
return new PlayerFirstJoinTag(me.getLong(LAST_GIVEN_TAG));
}
}

View file

@ -0,0 +1,5 @@
package dev.zontreck.thresholds.implementation;
public class StarterKitDoesNotExistException extends Exception
{
}

View file

@ -0,0 +1,155 @@
package dev.zontreck.thresholds.implementation.compressor;
import dev.zontreck.thresholds.blocks.ModBlocks;
import dev.zontreck.thresholds.blocks.entity.CompressionChamberBlockEntity;
import dev.zontreck.thresholds.implementation.inits.ModMenuTypes;
import net.minecraft.core.Direction;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.items.SlotItemHandler;
public class CompressionChamberMenu extends AbstractContainerMenu
{
public final CompressionChamberBlockEntity entity;
public final Level level;
public final ContainerData data;
public CompressionChamberMenu(int id, Inventory inv, FriendlyByteBuf buf)
{
this(id, inv, inv.player.level().getBlockEntity(buf.readBlockPos()), new SimpleContainerData(1));
}
public CompressionChamberMenu(int id, Inventory inv, BlockEntity entity, ContainerData data)
{
super(ModMenuTypes.COMPRESSION_CHAMBER.get(), id);
checkContainerSize(inv, 1);
this.data=data;
this.level = entity.getLevel();
this.entity = (CompressionChamberBlockEntity) entity;
addPlayerInventory(inv);
addPlayerHotbar(inv);
this.entity.getCapability(ForgeCapabilities.ITEM_HANDLER, Direction.UP).ifPresent(handler->{
addSlot(new SlotItemHandler(handler, 0, 34,34));
});
this.entity.getCapability(ForgeCapabilities.ITEM_HANDLER, Direction.DOWN).ifPresent(handler->{
addSlot(new SlotItemHandler(handler, 0, 113, 34));
});
addDataSlots(data);
}
public boolean isCrafting()
{
return data.get(0) > 0;
}
public int getScaledProgress()
{
if(!isCrafting())return 0;
int progress = this.data.get(0);
int max = CompressionChamberBlockEntity.PROCESSING_TICKS;
int progressArrow = 39;
if(progress != 0 && max != 0)
{
int percent = progress * progressArrow / max;
return percent;
}
return 0;
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 2; // must be the number of slots you have!
@Override
public ItemStack quickMoveStack(Player playerIn, int index) {
Slot sourceSlot = slots.get(index);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (index < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (index < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + index);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
} else {
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
return copyOfSourceStack;
}
@Override
public boolean stillValid(Player player) {
return stillValid(ContainerLevelAccess.create(level, entity.getBlockPos()), player, ModBlocks.COMPRESSION_CHAMBER_BLOCK.get());
}
private static final int PLAYER_INVENTORY_FIRST_SLOT_HEIGHT = 85;
private static final int PLAYER_INVENTORY_FIRST_SLOT_LEFT = 11;
private static final int PLAYER_HOTBAR_FIRST_SLOT = 143;
private void addPlayerInventory(Inventory inv)
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
this.addSlot(new Slot(inv, j+i*9+9, PLAYER_INVENTORY_FIRST_SLOT_LEFT+j*18, PLAYER_INVENTORY_FIRST_SLOT_HEIGHT+i*18));
}
}
}
private void addPlayerHotbar(Inventory inv)
{
for (int index = 0; index < 9; index++) {
this.addSlot(new Slot(inv, index, PLAYER_INVENTORY_FIRST_SLOT_LEFT+index*18, PLAYER_HOTBAR_FIRST_SLOT));
}
}
}

View file

@ -0,0 +1,99 @@
package dev.zontreck.thresholds.implementation.compressor;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.MouseHelpers;
import dev.zontreck.thresholds.implementation.energy.screenrenderer.EnergyInfoArea;
import net.minecraft.client.gui.GuiGraphics;
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;
import java.util.Optional;
public class CompressionChamberScreen extends AbstractContainerScreen<CompressionChamberMenu> {
private static final ResourceLocation TEXTURE = new ResourceLocation(ThresholdsMod.MOD_ID, "textures/gui/energized_compression_chamber.png");
private EnergyInfoArea EIA;
public CompressionChamberScreen(CompressionChamberMenu pMenu, Inventory pPlayerInventory, Component pTitle) {
super(pMenu, pPlayerInventory, pTitle);
this.topPos=0;
this.leftPos=0;
this.imageWidth=176;
this.imageHeight=177;
}
@Override
protected void init() {
super.init();
assignEnergyArea();
}
private void assignEnergyArea() {
int x = (width - imageWidth )/2;
int y = (height - imageHeight)/2;
EIA = new EnergyInfoArea(x+63, y+46, menu.entity.getEnergyStorage(), 39, 6);
}
@Override
protected void renderBg(GuiGraphics guiGraphics, float v, int i, int i1) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, TEXTURE);
guiGraphics.blit(TEXTURE, this.leftPos, this.topPos, 0,0, imageWidth, imageHeight);
renderCraftingProgress(guiGraphics);
EIA.draw(guiGraphics);
}
@Override
protected void renderLabels(GuiGraphics stack, int mouseX, int mouseY)
{
stack.drawString(font, this.title.getString(), 32, 4, 0xFFFFFF);
int x = (width - imageWidth )/2;
int y = (height - imageHeight)/2;
renderEnergy(stack, mouseX, mouseY, x, y);
//this.font.draw(stack, this.playerInventoryTitle.getString(), this.leftPos + 17, this.topPos + 123, 0xFFFFFF);
}
private void renderEnergy(GuiGraphics stack, int mouseX, int mouseY, int x, int y) {
if(isMouseAbove(mouseX, mouseY, x, y, 63, 46, 39, 6)){
stack.renderTooltip(font, EIA.getTooltips(), Optional.empty(), mouseX-x, mouseY-y);
}
}
private void renderCraftingProgress(GuiGraphics stack)
{
if(menu.isCrafting())
{
stack.blit(TEXTURE, leftPos+63, topPos+34, 179, 11, menu.getScaledProgress(),6);
}
}
@Override
public void render(GuiGraphics stack, int mouseX, int mouseY, float delta)
{
renderBackground(stack);
super.render(stack, mouseX, mouseY, delta);
renderTooltip(stack, mouseX, mouseY);
}
private boolean isMouseAbove(int mouseX, int mouseY, int x, int y, int offsetX, int offsetY, int width, int height)
{
return MouseHelpers.isMouseOver(mouseX, mouseY, x+offsetX, y+offsetY, width, height);
}
}

View file

@ -0,0 +1,42 @@
package dev.zontreck.thresholds.implementation.energy;
import net.minecraftforge.energy.EnergyStorage;
public abstract class OTEEnergy extends EnergyStorage
{
public OTEEnergy(int capacity, int maxTransfer) {
super(capacity, maxTransfer);
}
@Override
public int extractEnergy(int max, boolean simulate)
{
int ex = super.extractEnergy(max, simulate);
if(ex != 0){
onChanged();
}
return ex;
}
@Override
public int receiveEnergy(int max, boolean simulate)
{
int rcv = super.receiveEnergy(max, simulate);
if(rcv!=0){
onChanged();
}
return rcv;
}
public int setEnergy(int energy){
this.energy=energy;
onChanged();
return energy;
}
public abstract void onChanged();
}

View file

@ -0,0 +1,48 @@
package dev.zontreck.thresholds.implementation.energy.screenrenderer;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.Component;
import net.minecraftforge.energy.IEnergyStorage;
import java.util.List;
/*
* BluSunrize
* Copyright (c) 2021
*
* This code is licensed under "Blu's License of Common Sense"
* Details can be found in the license file in the root folder of this project
*/
public class EnergyInfoArea extends InfoArea {
private final IEnergyStorage energy;
public EnergyInfoArea(int xMin, int yMin) {
this(xMin, yMin, null,8,64);
}
public EnergyInfoArea(int xMin, int yMin, IEnergyStorage energy) {
this(xMin, yMin, energy,8,64);
}
public EnergyInfoArea(int xMin, int yMin, IEnergyStorage energy, int width, int height) {
super(new Rect2i(xMin, yMin, width, height));
this.energy = energy;
}
public List<Component> getTooltips() {
return List.of(Component.literal(energy.getEnergyStored()+"/"+energy.getMaxEnergyStored()+" FE"));
}
@Override
public void draw(GuiGraphics transform) {
final int height = area.getHeight();
final int width = area.getWidth();
int stored = (int)(height*(energy.getEnergyStored()/(float)energy.getMaxEnergyStored()));
if(area.getHeight() > area.getWidth())
transform.fillGradient(area.getX(), area.getY() + (height + stored), area.getX() + area.getWidth(), area.getY() + area.getHeight(), 0xff0000, 0xff550000);
else transform.fillGradient(area.getX() + (width + stored), area.getY(),area.getX() + area.getWidth(), area.getY() + area.getHeight(), 0xff0000, 0xff005500);
}
}

View file

@ -0,0 +1,22 @@
package dev.zontreck.thresholds.implementation.energy.screenrenderer;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.Rect2i;
/*
* BluSunrize
* Copyright (c) 2021
*
* This code is licensed under "Blu's License of Common Sense"
* Details can be found in the license file in the root folder of this project
*/
public abstract class InfoArea {
protected final Rect2i area;
protected InfoArea(Rect2i area) {
this.area = area;
}
public abstract void draw(GuiGraphics transform);
}

View file

@ -0,0 +1,28 @@
package dev.zontreck.thresholds.implementation.events;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import net.minecraftforge.eventbus.api.Event;
public class VaultCreatedEvent extends Event
{
public int vault_num;
public Profile user;
public int in_use;
public int max;
public int playerMax;
public int remaining;
public boolean at_max;
public VaultCreatedEvent(int num, Profile user, int vaultsInUse)
{
max= ThresholdsServerConfig.MAX_VAULTS.get();
vault_num = num;
in_use = vaultsInUse;
playerMax=user.available_vaults;
remaining = playerMax-in_use;
if(remaining<=0)at_max=true;
this.user=user;
}
}

View file

@ -0,0 +1,11 @@
package dev.zontreck.thresholds.implementation.events;
import dev.zontreck.libzontreck.profiles.Profile;
public class VaultDeletedEvent extends VaultCreatedEvent{
public VaultDeletedEvent(int num, Profile user, int vaultsInUse) {
super(num, user, vaultsInUse);
}
}

View file

@ -0,0 +1,17 @@
package dev.zontreck.thresholds.implementation.events;
import dev.zontreck.libzontreck.profiles.Profile;
import net.minecraftforge.items.ItemStackHandler;
public class VaultModifiedEvent extends VaultCreatedEvent
{
public ItemStackHandler inventory;
public ItemStackHandler oldInventory;
public VaultModifiedEvent(int num, Profile user, int vaultsInUse, ItemStackHandler inv, ItemStackHandler old) {
super(num, user, vaultsInUse);
inventory=inv;
oldInventory = old;
}
}

View file

@ -0,0 +1,41 @@
package dev.zontreck.thresholds.implementation.inits;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.compressor.CompressionChamberMenu;
import dev.zontreck.thresholds.implementation.scrubber.ItemScrubberMenu;
import dev.zontreck.thresholds.implementation.scrubber.MagicalScrubberMenu;
import dev.zontreck.thresholds.implementation.vault.StarterMenu;
import dev.zontreck.thresholds.implementation.vault.VaultMenu;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraftforge.common.extensions.IForgeMenuType;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.network.IContainerFactory;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public final class ModMenuTypes
{
public static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.MENU_TYPES, ThresholdsMod.MOD_ID);
public static final RegistryObject<MenuType<VaultMenu>> VAULT = registerMenuType(VaultMenu::new, "vault");
public static final RegistryObject<MenuType<StarterMenu>> STARTER = registerMenuType(StarterMenu::new, "starter");
public static final RegistryObject<MenuType<ItemScrubberMenu>> SCRUBBER = registerMenuType(ItemScrubberMenu::new, "item_scrubber_menu");
public static final RegistryObject<MenuType<MagicalScrubberMenu>> MAGIC_SCRUBBER = registerMenuType(MagicalScrubberMenu::new, "magical_scrubber_menu");
public static final RegistryObject<MenuType<CompressionChamberMenu>> COMPRESSION_CHAMBER = registerMenuType(CompressionChamberMenu::new, "compression_chamber");
private static <T extends AbstractContainerMenu> RegistryObject<MenuType<T>> registerMenuType(IContainerFactory<T> factory, String name)
{
return CONTAINERS.register(name, ()->IForgeMenuType.create(factory));
}
public static void register(IEventBus bus)
{
CONTAINERS.register(bus);
}
}

View file

@ -0,0 +1,150 @@
package dev.zontreck.thresholds.implementation.scrubber;
import dev.zontreck.thresholds.blocks.ModBlocks;
import dev.zontreck.thresholds.blocks.entity.ItemScrubberBlockEntity;
import dev.zontreck.thresholds.implementation.inits.ModMenuTypes;
import net.minecraft.core.Direction;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.items.SlotItemHandler;
public class ItemScrubberMenu extends AbstractContainerMenu
{
public final ItemScrubberBlockEntity entity;
private final Level level;
private final ContainerData data;
public ItemScrubberMenu(int id, Inventory inv, FriendlyByteBuf buf)
{
this(id, inv, inv.player.level().getBlockEntity(buf.readBlockPos()), new SimpleContainerData(1));
}
public ItemScrubberMenu(int id, Inventory inv, BlockEntity entity, ContainerData data){
super(ModMenuTypes.SCRUBBER.get(), id);
checkContainerSize(inv, 1);
this.entity = (ItemScrubberBlockEntity)entity;
this.data=data;
this.level = inv.player.level();
addPlayerInventory(inv);
addPlayerHotbar(inv);
this.entity.getCapability(ForgeCapabilities.ITEM_HANDLER, Direction.UP).ifPresent(handler->{
addSlot(new SlotItemHandler(handler, 0, 16, 41));
});
this.entity.getCapability(ForgeCapabilities.ITEM_HANDLER, Direction.DOWN).ifPresent(handler->{
addSlot(new SlotItemHandler(handler, 0, 177, 41));
});
addDataSlots(data);
}
public boolean isCrafting()
{
return data.get(0) > 0;
}
public int getScaledProgress()
{
if(!isCrafting())return 0;
int progress = this.data.get(0);
int max = ItemScrubberBlockEntity.MAXIMUM_PROCESSING_TICKS;
int progressArrow = 125;
if(progress != 0 && max != 0)
{
int percent = progress * progressArrow / max;
return percent;
}
return 0;
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 2; // must be the number of slots you have!
@Override
public ItemStack quickMoveStack(Player playerIn, int index) {
Slot sourceSlot = slots.get(index);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (index < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (index < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + index);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
} else {
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
return copyOfSourceStack;
}
@Override
public boolean stillValid(Player player) {
return stillValid(ContainerLevelAccess.create(level, entity.getBlockPos()), player, ModBlocks.ITEM_SCRUBBER.get());
}
private static final int PLAYER_INVENTORY_FIRST_SLOT_HEIGHT = 69;
private static final int PLAYER_INVENTORY_FIRST_SLOT_LEFT = 24;
private static final int PLAYER_HOTBAR_FIRST_SLOT = 125;
private void addPlayerInventory(Inventory inv)
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
this.addSlot(new Slot(inv, j+i*9+9, PLAYER_INVENTORY_FIRST_SLOT_LEFT+j*18, PLAYER_INVENTORY_FIRST_SLOT_HEIGHT+i*18));
}
}
}
private void addPlayerHotbar(Inventory inv)
{
for (int index = 0; index < 9; index++) {
this.addSlot(new Slot(inv, index, PLAYER_INVENTORY_FIRST_SLOT_LEFT+index*18, PLAYER_HOTBAR_FIRST_SLOT));
}
}
}

View file

@ -0,0 +1,99 @@
package dev.zontreck.thresholds.implementation.scrubber;
import java.util.Optional;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.MouseHelpers;
import dev.zontreck.thresholds.implementation.energy.screenrenderer.EnergyInfoArea;
import net.minecraft.client.gui.GuiGraphics;
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 ItemScrubberScreen extends AbstractContainerScreen<ItemScrubberMenu>
{
private static final ResourceLocation TEXTURE = new ResourceLocation(ThresholdsMod.MOD_ID, "textures/gui/item_scrubber_gui.png");
private EnergyInfoArea EIA;
public ItemScrubberScreen(ItemScrubberMenu p_97741_, Inventory p_97742_, Component p_97743_) {
super(p_97741_, p_97742_, p_97743_);
this.topPos=0;
this.leftPos=0;
this.imageWidth = 208;
this.imageHeight = 165;
}
@Override
protected void init()
{
super.init();
assignEnergyArea();
}
private void assignEnergyArea() {
int x = (width - imageWidth )/2;
int y = (height - imageHeight)/2;
EIA = new EnergyInfoArea(x+188, y+69, menu.entity.getEnergyStorage(), 7, 72);
}
@Override
protected void renderBg(GuiGraphics poseStack, float partialTick, int mouseX, int mouseY) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, TEXTURE);
poseStack.blit(TEXTURE, this.leftPos, this.topPos, 0,0, imageWidth, imageHeight);
renderUncraftingProgress(poseStack);
EIA.draw(poseStack);
}
@Override
protected void renderLabels(GuiGraphics stack, int mouseX, int mouseY)
{
stack.drawString(font, this.title.getString(), 63, 12, 0xFFFFFF);
int x = (width - imageWidth )/2;
int y = (height - imageHeight)/2;
renderEnergy(stack, mouseX, mouseY, x, y);
//this.font.draw(stack, this.playerInventoryTitle.getString(), this.leftPos + 17, this.topPos + 123, 0xFFFFFF);
}
private void renderEnergy(GuiGraphics stack, int mouseX, int mouseY, int x, int y) {
if(isMouseAbove(mouseX, mouseY, x, y, 188, 69, 7, 72)){
stack.renderTooltip(font, EIA.getTooltips(), Optional.empty(), mouseX-x, mouseY-y);
}
}
private void renderUncraftingProgress(GuiGraphics stack)
{
if(menu.isCrafting())
{
stack.blit(TEXTURE, leftPos+42, topPos+45, 1, 168, menu.getScaledProgress(),6);
}
}
@Override
public void render(GuiGraphics stack, int mouseX, int mouseY, float delta)
{
renderBackground(stack);
super.render(stack, mouseX, mouseY, delta);
renderTooltip(stack, mouseX, mouseY);
}
private boolean isMouseAbove(int mouseX, int mouseY, int x, int y, int offsetX, int offsetY, int width, int height)
{
return MouseHelpers.isMouseOver(mouseX, mouseY, x+offsetX, y+offsetY, width, height);
}
}

View file

@ -0,0 +1,150 @@
package dev.zontreck.thresholds.implementation.scrubber;
import dev.zontreck.thresholds.blocks.ModBlocks;
import dev.zontreck.thresholds.blocks.entity.MagicalScrubberBlockEntity;
import dev.zontreck.thresholds.implementation.inits.ModMenuTypes;
import net.minecraft.core.Direction;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.items.SlotItemHandler;
public class MagicalScrubberMenu extends AbstractContainerMenu
{
public final MagicalScrubberBlockEntity entity;
private final Level level;
private final ContainerData data;
public MagicalScrubberMenu(int id, Inventory inv, FriendlyByteBuf buf)
{
this(id, inv, inv.player.level().getBlockEntity(buf.readBlockPos()), new SimpleContainerData(1));
}
public MagicalScrubberMenu(int id, Inventory inv, BlockEntity entity, ContainerData data){
super(ModMenuTypes.MAGIC_SCRUBBER.get(), id);
checkContainerSize(inv, 1);
this.entity = (MagicalScrubberBlockEntity)entity;
this.data=data;
this.level = inv.player.level();
addPlayerInventory(inv);
addPlayerHotbar(inv);
this.entity.getCapability(ForgeCapabilities.ITEM_HANDLER, Direction.UP).ifPresent(handler->{
addSlot(new SlotItemHandler(handler, 0, 16, 41));
});
this.entity.getCapability(ForgeCapabilities.ITEM_HANDLER, Direction.DOWN).ifPresent(handler->{
addSlot(new SlotItemHandler(handler, 0, 177, 41));
});
addDataSlots(data);
}
public boolean isCrafting()
{
return data.get(0) > 0;
}
public int getScaledProgress()
{
if(!isCrafting())return 0;
int progress = this.data.get(0);
int max = MagicalScrubberBlockEntity.MAXIMUM_PROCESSING_TICKS;
int progressArrow = 125;
if(progress != 0 && max != 0)
{
int percent = progress * progressArrow / max;
return percent;
}
return 0;
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 2; // must be the number of slots you have!
@Override
public ItemStack quickMoveStack(Player playerIn, int index) {
Slot sourceSlot = slots.get(index);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (index < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (index < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + index);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
} else {
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
return copyOfSourceStack;
}
@Override
public boolean stillValid(Player player) {
return stillValid(ContainerLevelAccess.create(level, entity.getBlockPos()), player, ModBlocks.MAGICAL_SCRUBBER.get());
}
private static final int PLAYER_INVENTORY_FIRST_SLOT_HEIGHT = 69;
private static final int PLAYER_INVENTORY_FIRST_SLOT_LEFT = 24;
private static final int PLAYER_HOTBAR_FIRST_SLOT = 125;
private void addPlayerInventory(Inventory inv)
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
this.addSlot(new Slot(inv, j+i*9+9, PLAYER_INVENTORY_FIRST_SLOT_LEFT+j*18, PLAYER_INVENTORY_FIRST_SLOT_HEIGHT+i*18));
}
}
}
private void addPlayerHotbar(Inventory inv)
{
for (int index = 0; index < 9; index++) {
this.addSlot(new Slot(inv, index, PLAYER_INVENTORY_FIRST_SLOT_LEFT+index*18, PLAYER_HOTBAR_FIRST_SLOT));
}
}
}

View file

@ -0,0 +1,99 @@
package dev.zontreck.thresholds.implementation.scrubber;
import java.util.Optional;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.MouseHelpers;
import dev.zontreck.thresholds.implementation.energy.screenrenderer.EnergyInfoArea;
import net.minecraft.client.gui.GuiGraphics;
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 MagicalScrubberScreen extends AbstractContainerScreen<MagicalScrubberMenu>
{
private static final ResourceLocation TEXTURE = new ResourceLocation(ThresholdsMod.MOD_ID, "textures/gui/item_scrubber_gui.png");
private EnergyInfoArea EIA;
@Override
protected void init()
{
super.init();
assignEnergyArea();
}
private void assignEnergyArea() {
int x = (width - imageWidth )/2;
int y = (height - imageHeight)/2;
EIA = new EnergyInfoArea(x+188, y+69, menu.entity.getEnergyStorage(), 7, 72);
}
public MagicalScrubberScreen(MagicalScrubberMenu pMenu, Inventory pPlayerInventory, Component pTitle) {
super(pMenu, pPlayerInventory, pTitle);
this.topPos=0;
this.leftPos=0;
this.imageWidth = 208;
this.imageHeight = 165;
}
@Override
protected void renderBg(GuiGraphics poseStack, float partialTick, int mouseX, int mouseY) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, TEXTURE);
poseStack.blit(TEXTURE, this.leftPos, this.topPos, 0, 0, imageWidth, imageHeight);
renderUncraftingProgress(poseStack);
EIA.draw(poseStack);
}
@Override
protected void renderLabels(GuiGraphics stack, int mouseX, int mouseY)
{
stack.drawString(font, title.getString(), 63, 12, 0xFFFFFF);
int x = (width - imageWidth )/2;
int y = (height - imageHeight)/2;
renderEnergy(stack, mouseX, mouseY, x, y);
//this.font.draw(stack, this.playerInventoryTitle.getString(), this.leftPos + 17, this.topPos + 123, 0xFFFFFF);
}
private void renderEnergy(GuiGraphics stack, int mouseX, int mouseY, int x, int y) {
if(isMouseAbove(mouseX, mouseY, x, y, 188, 69, 7, 72)){
stack.renderTooltip(font, EIA.getTooltips(), Optional.empty(), mouseX-x, mouseY-y);
}
}
private void renderUncraftingProgress(GuiGraphics stack)
{
if(menu.isCrafting())
{
stack.blit(TEXTURE, leftPos+42, topPos+45, 1, 168, menu.getScaledProgress(), 6);
}
}
@Override
public void render(GuiGraphics stack, int mouseX, int mouseY, float delta)
{
renderBackground(stack);
super.render(stack, mouseX, mouseY, delta);
renderTooltip(stack, mouseX, mouseY);
}
private boolean isMouseAbove(int mouseX, int mouseY, int x, int y, int offsetX, int offsetY, int width, int height)
{
return MouseHelpers.isMouseOver(mouseX, mouseY, x+offsetX, y+offsetY, width, height);
}
}

View file

@ -0,0 +1,15 @@
package dev.zontreck.thresholds.implementation.vault;
/**
* You cannot create or open the vault due to server settings
*/
public class NoMoreVaultException extends Exception
{
public int vault;
public NoMoreVaultException(String msg, int vaultNum)
{
super(msg);
vault=vaultNum;
}
}

View file

@ -0,0 +1,91 @@
package dev.zontreck.thresholds.implementation.vault;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.LongTag;
import net.minecraft.nbt.NbtIo;
import net.minecraftforge.items.ItemStackHandler;
import java.io.File;
import java.io.IOException;
public class Starter {
public File file_location;
public final boolean isNew;
private long LastChanged;
private CompoundTag tag;
protected Starter(File loc)
{
file_location=loc;
isNew=!file_location.exists();
CompoundTag tag;
if(!isNew){
try {
tag = NbtIo.read(loc);
this.tag = tag.getCompound("inventory");
this.LastChanged = tag.getLong("changed");
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* This will return the contents of the NBT Vault
* @return
*/
public CompoundTag getContents(){
return tag;
}
/**
* This sets the internal compound tag of the vault provider, but also saves it to the file immediately.
* @param newTag
*/
public void setContents(CompoundTag newTag)
{
tag=newTag;
commit();
}
public void setLastChanged(long change)
{
LastChanged = change;
}
public long getLastChanged() {
return LastChanged;
}
private void commit()
{
CompoundTag newTag = new CompoundTag();
newTag.put("inventory", tag);
newTag.put("changed", LongTag.valueOf(LastChanged));
try {
NbtIo.write(newTag, file_location);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This is called to dispose of the vault and the vault file
*/
public void delete()
{
if(file_location.exists())
file_location.delete();
}
public ItemStackHandler getItems()
{
ItemStackHandler H = new ItemStackHandler(32);
H.deserializeNBT(getContents());
return H;
}
}

View file

@ -0,0 +1,109 @@
package dev.zontreck.thresholds.implementation.vault;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.MenuConstructor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.items.ItemStackHandler;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class StarterContainer
{
public static Map<UUID, StarterContainer> VAULT_REGISTRY = new HashMap<>();
public StarterMenu theContainer;
public ItemStackHandler myInventory;
public ItemStackHandler startingInventory;
public MenuConstructor serverMenu;
public UUID owner;
private MinecraftServer server;
public final UUID VaultID;
private boolean invalid = false;
public Starter main_accessor;
public StarterContainer(ServerPlayer player) throws NoMoreVaultException {
myInventory = new ItemStackHandler(54); // Vaults have a fixed size at the same as a double chest
startingInventory = new ItemStackHandler(64);
theContainer = new StarterMenu(player.containerCounter+1, player.getInventory(), myInventory, BlockPos.ZERO, player);
VaultID = theContainer.VaultMenuID;
owner = player.getUUID();
server=player.server;
serverMenu = theContainer.getServerMenu(myInventory);
// Check database for vault
StarterProvider.VaultAccessStrategy strategy;
strategy = StarterProvider.check();
if(strategy == StarterProvider.VaultAccessStrategy.CREATE || strategy == StarterProvider.VaultAccessStrategy.OPEN)
{
Starter accessor = StarterProvider.getStarter();
if(accessor.isNew)
{
main_accessor=accessor;
return;
}else {
myInventory.deserializeNBT(accessor.getContents());
startingInventory.deserializeNBT(accessor.getContents());
}
main_accessor=accessor;
}else {
// DENY
throw new NoMoreVaultException("No more vaults can be created", 0);
}
// Container is now ready to be sent to the client!
}
public void commit()
{
if(invalid)return;
boolean isEmpty=true;
CompoundTag saved = myInventory.serializeNBT();
ChatHelpers.broadcastToAbove(owner, Component.literal(ChatColor.BOLD+ChatColor.DARK_GREEN+"Saving the starter kit's contents..."), server);
main_accessor.setLastChanged(Instant.now().getEpochSecond());
Profile profile=null;
try {
profile = Profile.get_profile_of(owner.toString());
} catch (UserProfileNotYetExistsException e) {
e.printStackTrace();
return;
}
for(int i = 0;i<myInventory.getSlots();i++)
{
ItemStack is = myInventory.getStackInSlot(i);
if(!is.is(Items.AIR))
{
isEmpty=false;
}
}
if(!isEmpty)
main_accessor.setContents(saved);
else
main_accessor.delete();
//VaultModifiedEvent vme = new VaultModifiedEvent(-2, profile, 0, myInventory, startingInventory);
//OTEMod.bus.post(vme);
}
public void invalidate()
{
invalid=true;
}
}

View file

@ -0,0 +1,150 @@
package dev.zontreck.thresholds.implementation.vault;
import dev.zontreck.thresholds.implementation.inits.ModMenuTypes;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
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.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;
import java.util.Map;
import java.util.UUID;
public class StarterMenu extends AbstractContainerMenu
{
//private final ContainerLevelAccess containerAccess;
public final UUID VaultMenuID;
public final Player thePlayer;
public StarterMenu(int id, Inventory player, FriendlyByteBuf buf)
{
this(id, player, new ItemStackHandler(54), player.player.getOnPos(), player.player);
}
public StarterMenu(int id, Inventory player, IItemHandler slots, BlockPos pos, Player play)
{
super(ModMenuTypes.VAULT.get(), id);
thePlayer=play;
VaultMenuID=UUID.randomUUID();
//this.containerAccess = ContainerLevelAccess.create(player.player.level, pos);
final int slotSize = 18;
final int startX = 24;
final int inventoryY = 38;
addPlayerInventory(player);
addPlayerHotbar(player);
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));
}
}
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 54; // must be the number of slots you have!
@Override
public ItemStack quickMoveStack(Player playerIn, int index) {
Slot sourceSlot = slots.get(index);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (index < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (index < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + index);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
} else {
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
return copyOfSourceStack;
}
@Override
public boolean stillValid(Player p_38874_) {
return true; // We have no block
}
public static MenuConstructor getServerMenu (ItemStackHandler inventory){
return (id, player, play) -> new StarterMenu(id, player, inventory, BlockPos.ZERO, player.player);
}
public void doCommitAction()
{
// Locate the Vault in the Vault Registry and commit changes.
// Search for myself!
for(Map.Entry<UUID,StarterContainer> e : StarterContainer.VAULT_REGISTRY.entrySet())
{
if(e.getValue().VaultID.equals(VaultMenuID))
{
e.getValue().commit();
}
}
}
private static final int PLAYER_INVENTORY_FIRST_SLOT_HEIGHT = 156;
private static final int PLAYER_INVENTORY_FIRST_SLOT_LEFT = 24;
private static final int PLAYER_HOTBAR_FIRST_SLOT = 212;
private void addPlayerInventory(Inventory inv)
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
this.addSlot(new Slot(inv, j+i*9+9, PLAYER_INVENTORY_FIRST_SLOT_LEFT+j*18, PLAYER_INVENTORY_FIRST_SLOT_HEIGHT+i*18));
}
}
}
private void addPlayerHotbar(Inventory inv)
{
for (int index = 0; index < 9; index++) {
this.addSlot(new Slot(inv, index, PLAYER_INVENTORY_FIRST_SLOT_LEFT+index*18, PLAYER_HOTBAR_FIRST_SLOT));
}
}
}

View file

@ -0,0 +1,59 @@
package dev.zontreck.thresholds.implementation.vault;
import dev.zontreck.thresholds.database.OTEDatastore;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class StarterProvider extends OTEDatastore
{
public enum VaultAccessStrategy
{
OPEN,
CREATE,
DENY
}
public static final Path FILE_TREE_PATH = of("starter");
public static VaultAccessStrategy check()
{
if(!FILE_TREE_PATH.toFile().exists())
{
try {
Files.createDirectory(FILE_TREE_PATH);
} catch (IOException e) {
e.printStackTrace();
}
}
Path starterVaultPath = FILE_TREE_PATH.resolve("starter.nbt");
File vaultFile = starterVaultPath.toFile();
if(vaultFile.exists())
{
return VaultAccessStrategy.OPEN;
}else {
return VaultAccessStrategy.CREATE;
}
}
public static Starter getStarter() throws NoMoreVaultException
{
VaultAccessStrategy strat = check();
if(strat == VaultAccessStrategy.CREATE || strat == VaultAccessStrategy.OPEN)
{
Path userVault = FILE_TREE_PATH.resolve("starter.nbt");
Starter v = new Starter(userVault.toFile());
return v;
}else return null;
}
public static boolean exists()
{
Path v = FILE_TREE_PATH.resolve("starter.nbt");
return v.toFile().exists();
}
}

View file

@ -0,0 +1,66 @@
package dev.zontreck.thresholds.implementation.vault;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.zontreck.thresholds.ThresholdsMod;
import net.minecraft.client.gui.GuiGraphics;
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;
import net.minecraft.world.entity.player.Player;
import java.util.UUID;
public class StarterScreen extends AbstractContainerScreen <StarterMenu>
{
// 176x224
public final UUID VaultMenuID;
public final Player thePlayer;
public final StarterMenu THE_CONTAINER;
private static final ResourceLocation TEXTURE = new ResourceLocation(ThresholdsMod.MOD_ID, "textures/gui/vault.png");
public StarterScreen(StarterMenu container, Inventory playerInv, Component comp){
super(container, playerInv, comp);
thePlayer=playerInv.player;
this.VaultMenuID = container.VaultMenuID;
this.leftPos = 0;
this.topPos = 0;
this.THE_CONTAINER=container;
this.imageWidth = 207;
this.imageHeight = 238;
}
@Override
public void render(GuiGraphics stack, int mouseX, int mouseY, float partialTicks)
{
this.renderBackground(stack);
super.render(stack, mouseX, mouseY, partialTicks);
this.renderTooltip(stack, mouseX, mouseY);
}
@Override
protected void init()
{
super.init();
this.inventoryLabelY = 12;
this.inventoryLabelX = 63;
}
@Override
protected void renderBg(GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY)
{
renderBackground(pGuiGraphics);
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor (1.0f, 1.0f, 1.0f, 1.0f);
RenderSystem.setShaderTexture(0, TEXTURE);
pGuiGraphics.blit(TEXTURE, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight);
}
}

View file

@ -0,0 +1,64 @@
package dev.zontreck.thresholds.implementation.vault;
import dev.zontreck.libzontreck.profiles.Profile;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
import java.io.File;
import java.io.IOException;
public class Vault {
public int vaultNum;
public File file_location;
public Profile user;
public final boolean isNew;
private CompoundTag tag;
protected Vault(int num, File loc, Profile owner)
{
user=owner;
file_location=loc;
vaultNum=num;
isNew=!file_location.exists();
if(!isNew){
try {
tag = NbtIo.read(loc);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* This will return the contents of the NBT Vault
* @return
*/
public CompoundTag getContents(){
return tag;
}
/**
* This sets the internal compound tag of the vault provider, but also saves it to the file immediately.
* @param newTag
*/
public void setContents(CompoundTag newTag)
{
tag=newTag;
try {
NbtIo.write(newTag, file_location);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This is called to dispose of the vault and the vault file
*/
public void delete()
{
if(file_location.exists())
file_location.delete();
}
}

View file

@ -0,0 +1,116 @@
package dev.zontreck.thresholds.implementation.vault;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.events.VaultModifiedEvent;
import dev.zontreck.thresholds.implementation.vault.VaultProvider.VaultAccessStrategy;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.MenuConstructor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.items.ItemStackHandler;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class VaultContainer
{
public static Map<UUID, VaultContainer> VAULT_REGISTRY = new HashMap<>();
public VaultMenu theContainer;
public ItemStackHandler myInventory;
public ItemStackHandler startingInventory;
public MenuConstructor serverMenu;
public UUID owner;
private MinecraftServer server;
public final int VAULT_NUMBER;
public final UUID VaultID;
public Vault main_accessor;
private boolean invalid;
public VaultContainer(ServerPlayer player, int vaultNum) throws NoMoreVaultException {
myInventory = new ItemStackHandler(54); // Vaults have a fixed size at the same as a double chest
startingInventory = new ItemStackHandler(64);
theContainer = new VaultMenu(player.containerCounter+1, player.getInventory(), myInventory, BlockPos.ZERO, player, vaultNum);
VaultID = theContainer.VaultMenuID;
owner = player.getUUID();
server=player.server;
serverMenu = theContainer.getServerMenu(myInventory, vaultNum);
VAULT_NUMBER=vaultNum;
if(VAULT_NUMBER == -1)return; // Trash ID
// Check database for vault
VaultAccessStrategy strategy;
try {
strategy = VaultProvider.check(Profile.get_profile_of(player.getStringUUID()), vaultNum);
if(strategy == VaultAccessStrategy.CREATE || strategy == VaultAccessStrategy.OPEN)
{
Vault accessor = VaultProvider.get(Profile.get_profile_of(player.getStringUUID()), vaultNum);
if(accessor.isNew)
{
main_accessor=accessor;
return;
}else {
myInventory.deserializeNBT(accessor.getContents());
startingInventory.deserializeNBT(accessor.getContents());
}
main_accessor=accessor;
}else {
// DENY
throw new NoMoreVaultException("No more vaults can be created", vaultNum);
}
} catch (UserProfileNotYetExistsException e) {
throw new NoMoreVaultException("User profile not exists. No vault can be opened or created", -9999);
}
// Container is now ready to be sent to the client!
}
public void commit()
{
if(invalid)return;
if(VAULT_NUMBER == -1)return; // We have no need to save the trash
boolean isEmpty=true;
CompoundTag saved = myInventory.serializeNBT();
ChatHelpers.broadcastToAbove(owner, Component.literal(ChatColor.BOLD+ChatColor.DARK_GREEN+"Saving the vault's contents..."), server);
Profile profile=null;
try {
profile = Profile.get_profile_of(owner.toString());
} catch (UserProfileNotYetExistsException e) {
e.printStackTrace();
return;
}
for(int i = 0;i<myInventory.getSlots();i++)
{
ItemStack is = myInventory.getStackInSlot(i);
if(!is.is(Items.AIR))
{
isEmpty=false;
}
}
if(!isEmpty)
main_accessor.setContents(saved);
else
main_accessor.delete();
VaultModifiedEvent vme = new VaultModifiedEvent(VAULT_NUMBER, profile, VaultProvider.getInUse(profile), myInventory, startingInventory);
ThresholdsMod.bus.post(vme);
}
public void invalidate()
{
invalid=true;
}
}

View file

@ -0,0 +1,152 @@
package dev.zontreck.thresholds.implementation.vault;
import java.util.Map;
import java.util.UUID;
import dev.zontreck.thresholds.implementation.inits.ModMenuTypes;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
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.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 final Player thePlayer;
public final int VAULT_NUMBER;
public VaultMenu (int id, Inventory player, FriendlyByteBuf buf)
{
this(id, player, new ItemStackHandler(54), player.player.getOnPos(), player.player, 0);
}
public VaultMenu (int id, Inventory player, IItemHandler slots, BlockPos pos, Player play, int vaultNum)
{
super(ModMenuTypes.VAULT.get(), id);
thePlayer=play;
VaultMenuID=UUID.randomUUID();
VAULT_NUMBER=vaultNum;
//this.containerAccess = ContainerLevelAccess.create(player.player.level, pos);
final int slotSize = 18;
final int startX = 24;
final int inventoryY = 38;
addPlayerInventory(player);
addPlayerHotbar(player);
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));
}
}
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 54; // must be the number of slots you have!
@Override
public ItemStack quickMoveStack(Player playerIn, int index) {
Slot sourceSlot = slots.get(index);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (index < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (index < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + index);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
} else {
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
return copyOfSourceStack;
}
@Override
public boolean stillValid(Player p_38874_) {
return true; // We have no block
}
public static MenuConstructor getServerMenu (ItemStackHandler inventory, int vaultNum){
return (id, player, play) -> new VaultMenu(id, player, inventory, BlockPos.ZERO, player.player, vaultNum);
}
public void doCommitAction()
{
// Locate the Vault in the Vault Registry and commit changes.
// Search for myself!
for(Map.Entry<UUID,VaultContainer> e : VaultContainer.VAULT_REGISTRY.entrySet())
{
if(e.getValue().VaultID.equals(VaultMenuID))
{
e.getValue().commit();
}
}
}
private static final int PLAYER_INVENTORY_FIRST_SLOT_HEIGHT = 156;
private static final int PLAYER_INVENTORY_FIRST_SLOT_LEFT = 24;
private static final int PLAYER_HOTBAR_FIRST_SLOT = 212;
private void addPlayerInventory(Inventory inv)
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
this.addSlot(new Slot(inv, j+i*9+9, PLAYER_INVENTORY_FIRST_SLOT_LEFT+j*18, PLAYER_INVENTORY_FIRST_SLOT_HEIGHT+i*18));
}
}
}
private void addPlayerHotbar(Inventory inv)
{
for (int index = 0; index < 9; index++) {
this.addSlot(new Slot(inv, index, PLAYER_INVENTORY_FIRST_SLOT_LEFT+index*18, PLAYER_HOTBAR_FIRST_SLOT));
}
}
}

View file

@ -0,0 +1,98 @@
package dev.zontreck.thresholds.implementation.vault;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import dev.zontreck.thresholds.database.OTEDatastore;
public class VaultProvider extends OTEDatastore
{
public enum VaultAccessStrategy
{
OPEN,
CREATE,
DENY
}
public static final Path FILE_TREE_PATH = of("vaults");
public static VaultAccessStrategy check(Profile profile, int vaultNum)
{
if(!FILE_TREE_PATH.toFile().exists())
{
try {
Files.createDirectory(FILE_TREE_PATH);
} catch (IOException e) {
e.printStackTrace();
}
}
Path userVaultPath = FILE_TREE_PATH.resolve(profile.user_id);
File vaultFile = userVaultPath.resolve(String.valueOf(vaultNum)+".nbt").toFile();
if(!userVaultPath.toFile().exists()){
try {
Files.createDirectory(userVaultPath);
} catch (IOException e) {
e.printStackTrace();
}
}
if(vaultFile.exists())
{
return VaultAccessStrategy.OPEN;
}else {
List<File> files = getListOfFiles(userVaultPath);
if(isAtMaxVaults(profile, files.size()))
{
return VaultAccessStrategy.DENY;
}else {
return VaultAccessStrategy.CREATE;
}
}
}
public static int getInUse(Profile prof)
{
Path uservaults = FILE_TREE_PATH.resolve(prof.user_id);
return getListOfFiles(uservaults).size();
}
public static boolean isAtMaxVaults(Profile prof, int consumed)
{
if(ThresholdsServerConfig.MAX_VAULTS.get()==0){
if(consumed < prof.available_vaults){
return false;
}else return true;
}
if(prof.available_vaults >= ThresholdsServerConfig.MAX_VAULTS.get())
{
if(consumed<prof.available_vaults)
{
return false;
}
return true;
}else{
if(consumed<prof.available_vaults)return false;
else return true;
}
}
public static Vault get(Profile profile, int vault) throws NoMoreVaultException
{
VaultAccessStrategy strat = check(profile,vault);
if(strat == VaultAccessStrategy.CREATE || strat == VaultAccessStrategy.OPEN)
{
Path userVault = FILE_TREE_PATH.resolve(profile.user_id);
Vault v = new Vault(vault, userVault.resolve(String.valueOf(vault)+".nbt").toFile(), profile);
return v;
}else throw new NoMoreVaultException("Cannot open due to server limits", vault);
}
}

View file

@ -0,0 +1,84 @@
package dev.zontreck.thresholds.implementation.vault;
import java.util.UUID;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.networking.ModMessages;
import dev.zontreck.thresholds.networking.packets.OpenVaultC2SPacket;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
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;
import net.minecraft.world.entity.player.Player;
public class VaultScreen extends AbstractContainerScreen <VaultMenu>
{
// 176x224
public final UUID VaultMenuID;
public final Player thePlayer;
public final VaultMenu THE_CONTAINER;
private static final ResourceLocation TEXTURE = new ResourceLocation(ThresholdsMod.MOD_ID, "textures/gui/vault.png");
public VaultScreen(VaultMenu container, Inventory playerInv, Component comp){
super(container, playerInv, comp);
thePlayer=playerInv.player;
this.VaultMenuID = container.VaultMenuID;
this.leftPos = 0;
this.topPos = 0;
this.THE_CONTAINER=container;
this.imageWidth = 207;
this.imageHeight = 238;
}
@Override
public void render(GuiGraphics stack, int mouseX, int mouseY, float partialTicks)
{
this.renderBackground(stack);
super.render(stack, mouseX, mouseY, partialTicks);
this.renderTooltip(stack, mouseX, mouseY);
}
@Override
protected void init()
{
super.init();
this.inventoryLabelY = 12;
this.inventoryLabelX = 63;
// This is where custom controls would be added!
this.addWidget(Button.builder(Component.literal(""), (BTN)->{
thePlayer.closeContainer();
ModMessages.sendToServer(new OpenVaultC2SPacket(0, true, -1));
}).size(16,16).pos(this.leftPos+7, this.topPos+86).build());
this.addWidget(Button.builder(Component.literal(""), (BTN)->{
thePlayer.closeContainer();
ModMessages.sendToServer(new OpenVaultC2SPacket(0, true, 1));
}).size(16,16).pos(this.leftPos+187, this.topPos+84).build());
}
@Override
protected void renderBg(GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY)
{
renderBackground(pGuiGraphics);
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor (1.0f, 1.0f, 1.0f, 1.0f);
RenderSystem.setShaderTexture(0, TEXTURE);
pGuiGraphics.blit(TEXTURE, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight);
}
}

View file

@ -0,0 +1,44 @@
package dev.zontreck.thresholds.implementation.vault;
import java.util.Map;
import java.util.UUID;
import dev.zontreck.thresholds.ThresholdsMod;
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= ThresholdsMod.MOD_ID,bus=Mod.EventBusSubscriber.Bus.FORGE)
public class VaultWatcher {
@SubscribeEvent
public void onClosedContainer(PlayerContainerEvent.Close ev)
{
if(ev.getEntity().level().isClientSide)return;
//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<UUID, VaultContainer> entry : VaultContainer.VAULT_REGISTRY.entrySet()){
if(entry.getKey() == ev.getEntity().getUUID())
{
entry.getValue().commit();
entry.getValue().invalidate();
}
}
} else if(ev.getContainer() instanceof StarterMenu)
{
for(Map.Entry<UUID, StarterContainer> entry : StarterContainer.VAULT_REGISTRY.entrySet())
{
if(entry.getKey() == ev.getEntity().getUUID())
{
entry.getValue().commit();
entry.getValue().invalidate();
}
}
}
}
}

View file

@ -0,0 +1,28 @@
package dev.zontreck.thresholds.integrations;
import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@OnlyIn(Dist.CLIENT)
public class KeyBindings {
public static final String KEY_CATEGORY_OTEMOD = "key.category.otemod";
public static final String KEY_OPEN_VAULT = "key.otemod.open_vault";
public static final KeyMapping OPEN_VAULT = createKeyMapping(KEY_OPEN_VAULT, InputConstants.KEY_V, KEY_CATEGORY_OTEMOD);
private static KeyMapping createKeyMapping(String name, int keycode, String category){
final KeyMapping key = new KeyMapping(name, keycode, category);
return key;
}
@SubscribeEvent
public static void registerKeyMappings(RegisterKeyMappingsEvent event)
{
event.register(OPEN_VAULT);
}
}

View file

@ -0,0 +1,37 @@
package dev.zontreck.thresholds.integrations;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.implementation.Messages;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
public class LuckPermsHelper {
/*public static LuckPerms getLuckPerms()
{
return LuckPermsProvider.get();
}
private static User getUserOf(Player p){
return getLuckPerms().getPlayerAdapter(Player.class).getUser(p);
}
private static boolean hasPermission(User u, String perm)
{
return u.getCachedData().getPermissionData().checkPermission(perm).asBoolean();
}*/
public static boolean hasPermission(Player p, String perm)
{
//User u = getUserOf(p);
return true;
}
public static boolean hasGroupOrPerm(Player p, String group, String perm){
return hasPermission(p, group) || hasPermission(p, perm);
}
public static void sendNoPermissionsMessage(ServerPlayer play, String perm, String group) {
ChatHelpers.broadcastTo(play.getUUID(), ChatHelpers.macro(Messages.THRESHOLDS_PREFIX +" !Dark_Red!You do not have permission to use that command. You need permission !Gold!"+perm+" !White! or !Gold!"+group), play.server);
}
}

View file

@ -0,0 +1,11 @@
package dev.zontreck.thresholds.items;
import net.minecraft.world.item.Item;
public class IhanCrystal extends Item{
public IhanCrystal(Properties p_41383_) {
super(p_41383_);
}
}

View file

@ -0,0 +1,76 @@
package dev.zontreck.thresholds.items;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.implementation.CreativeModeTabs;
import net.minecraft.world.item.*;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class ModItems {
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, ThresholdsMod.MOD_ID);
public static final RegistryObject<Item> ETERNIUM_FRAGMENT = CreativeModeTabs.addToOTEModTab(ITEMS.register("eternium_fragment", () -> new Item(new Item.Properties())));
public static final RegistryObject<Item> IHAN_CRYSTAL = CreativeModeTabs.addToOTEModTab(ITEMS.register("ihan_crystal", () -> new Item(new Item.Properties())));
public static final RegistryObject<Item> AURORA_COMPOUND = CreativeModeTabs.addToOTEModTab(ITEMS.register("aurora_compound", () -> new Item(new Item.Properties())));
public static final RegistryObject<Item> ETERNIUM_RAW_ORE = CreativeModeTabs.addToOTEModTab(ITEMS.register("eternium_ore", () -> new Item(new Item.Properties())));
public static final RegistryObject<Item> ETERNIUM_INGOT = CreativeModeTabs.addToOTEModTab(ITEMS.register("eternium_ingot", ()-> new SimpleFoiledItem(new Item.Properties())));
public static final RegistryObject<Item> MELTED_ENDER_PEARL = CreativeModeTabs.addToOTEModTab(ITEMS.register("melted_ender_pearl", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> SINGULARITY = CreativeModeTabs.addToOTEModTab(ITEMS.register("singularity", () -> new UnstableSingularity(new Item.Properties().stacksTo(1))));
public static final RegistryObject<Item> COMPRESSED_OBSIDIAN_SHEET = CreativeModeTabs.addToOTEModTab(ITEMS.register("compressed_obsidian_sheet", ()->new Item(new Item.Properties())));
public static final RegistryObject<Item> LAYERED_COMPRESSED_OBSIDIAN_SHEET = CreativeModeTabs.addToOTEModTab(ITEMS.register("layered_compressed_obsidian_sheet", ()->new SimpleFoiledItem(new Item.Properties())));
public static final RegistryObject<Item> ENCASED_SINGULARITY = CreativeModeTabs.addToOTEModTab(ITEMS.register("encased_singularity", ()->new SimpleFoiledItem(new Item.Properties())));
public static final RegistryObject<Item> ETERNIUM_ROD = CreativeModeTabs.addToOTEModTab(ITEMS.register("eternium_rod", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> SCRUBBER_FRAME_PIECE = CreativeModeTabs.addToOTEModTab(ITEMS.register("scrubber_frame_piece", () -> new Item(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> SCRUBBER_FRAME = CreativeModeTabs.addToOTEModTab(ITEMS.register("scrubber_frame", () -> new Item(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULTSTEEL_INGOT = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_steel_ingot", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_BL = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_lower_left", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_LC = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_lower", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_BR = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_lower_right", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_L = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_left", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_R = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_right", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_UR = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_upper_right", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_UL = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_upper_left", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_U = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_upper", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_FRAG_C = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault_fragment_center", () -> new SimpleFoiledItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT = CreativeModeTabs.addToOTEModTab(ITEMS.register("vault", () -> new VaultItem(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> VAULT_RAW_ORE = CreativeModeTabs.addToOTEModTab(ITEMS.register("raw_vault_steel_ore", () -> new Item(new Item.Properties().stacksTo(64))));
public static final RegistryObject<Item> POSS_BALL = CreativeModeTabs.addToOTEModTab(ITEMS.register("poss_ball", () -> new PossBallItem(new Item.Properties())));
public static final RegistryObject<Item> ILUSIUM_ORE = CreativeModeTabs.addToOTEModTab(ITEMS.register("ilusium_ore", () -> new Item(new Item.Properties().fireResistant())));
public static final RegistryObject<Item> ILUSIUM_ROD = CreativeModeTabs.addToOTEModTab(ITEMS.register("ilusium_rod", () -> new Item(new Item.Properties().fireResistant())));
//public static final RegistryObject<Item> ILUSIUM_DUST = CreativeModeTabs.addToOTEModTab(ITEMS.register("ilusium_dust", () -> new Item(new Item.Properties().fireResistant())));
public static final RegistryObject<Item> ILUSIUM_INGOT = CreativeModeTabs.addToOTEModTab(ITEMS.register("ilusium_ingot", () -> new Item(new Item.Properties().fireResistant())));
public static final RegistryObject<Item> EMPTY_SPAWN_EGG = CreativeModeTabs.addToOTEModTab(ITEMS.register("empty_spawn_egg", () -> new Item(new Item.Properties())));
//public static final RegistryObject<Item> POSSUM_SPAWN_EGG = ITEMS.register("possum_spawn_egg", () -> new ForgeSpawnEggItem(ModEntityTypes.POSSUM, 0x938686, 0xc68787, new Item.Properties())));
public static void register(IEventBus bus){
ITEMS.register(bus);
}
}

View file

@ -0,0 +1,64 @@
package dev.zontreck.thresholds.items;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
public class PossBallItem extends Item
{
public PossBallItem(Properties pProperties) {
super(pProperties);
}
@Override
public boolean isFoil(ItemStack pStack) {
if(!pStack.hasTag())
{
pStack.setTag(new CompoundTag());
}
if(pStack.getTag().contains("entity"))
{
return true;
} else return false;
}
@Override
public boolean isDamageable(ItemStack stack) {
return true;
}
@Override
public int getMaxDamage(ItemStack stack) {
return 2;
}
@Override
public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pUsedHand) {
ItemStack stack = pPlayer.getItemInHand(pUsedHand);
pLevel.playSound((Player) null, pPlayer.getX(), pPlayer.getY(), pPlayer.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (pLevel.random.nextFloat() * 0.4f + 0.8f));
if(!pLevel.isClientSide)
{
ThrownPossBall TPB = new ThrownPossBall(pLevel, pPlayer);
if(pPlayer.getAbilities().instabuild) TPB.setItem(stack.copy());
else
TPB.setItem(stack);
TPB.shootFromRotation(pPlayer, pPlayer.getXRot(), pPlayer.getYRot(), 0.0F, 1.5F, 1.0F);
pLevel.addFreshEntity(TPB);
}
pPlayer.awardStat(Stats.ITEM_USED.get(this));
if(!pPlayer.getAbilities().instabuild)
{
stack.shrink(1);
}else {
}
return super.use(pLevel, pPlayer, pUsedHand);
}
}

View file

@ -0,0 +1,177 @@
package dev.zontreck.thresholds.items;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.lore.LoreContainer;
import dev.zontreck.libzontreck.lore.LoreEntry;
import net.minecraft.core.particles.ItemParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.HitResult;
import java.util.Optional;
import java.util.UUID;
public class ThrownPossBall extends ThrowableItemProjectile
{
boolean captured = false;
LivingEntity shooter;
public ThrownPossBall(EntityType<? extends ThrownPossBall> entity, Level level)
{
super(entity, level);
}
public ThrownPossBall(Level level, LivingEntity shooter)
{
super(EntityType.SNOWBALL, shooter, level);
this.shooter = shooter;
}
public ThrownPossBall(Level pLevel, double pX, double pY, double pZ)
{
super(EntityType.SNOWBALL, pX, pY, pZ, pLevel);
}
@Override
protected Item getDefaultItem()
{
return ModItems.POSS_BALL.get();
}
@Override
public void handleEntityEvent(byte pId) {
if(pId == 3)
{
double size = 0.08;
for (int i = 0; i < 8; ++i)
{
this.level().addParticle(new ItemParticleOption(ParticleTypes.ITEM, this.getItem()), this.getX(), this.getY(), this.getZ(), ((double)this.random.nextFloat() - 0.5) * 0.08, ((double)this.random.nextFloat() - 0.5) * 0.08, ((double)this.random.nextFloat() - 0.5) * 0.08);
}
}
}
@Override
protected void onHitEntity(EntityHitResult pResult) {
super.onHitEntity(pResult);
if(getItem().getTag().contains("entity"))
{
// Don't capture the entity
pResult.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.1F);
} else {
if(pResult.getEntity() instanceof LivingEntity le && !(le instanceof Player))
{
// We don't want to capture players
// Store the entity in the entity tag, then kill the entity
CompoundTag tag = new CompoundTag();
String entityName = le.getName().getString();
le.save(tag);
getItem().getTag().put("entity", tag);
captured=true;
LoreContainer cont = new LoreContainer(getItem());
cont.miscData.loreData.clear();
LoreEntry entry = new LoreEntry.Builder().bold(true).text(ChatColor.doColors("!Dark_Green!Captured Mob: !Dark_Purple!" + entityName)).build();
cont.miscData.loreData.add(entry);
cont.commitLore();
le.remove(RemovalReason.DISCARDED);
}
}
}
@Override
protected void onHit(HitResult pResult) {
super.onHit(pResult);
if(!this.level().isClientSide)
{
// We do two things here
// 1. If we contain an entity, spawn it
// 2. If no entity, and none was captured, decrease the durability a little
// 3. Drop the PossBall with entity, or without
ItemStack item = getItem();
CompoundTag tag = item.getTag();
if(tag.contains("entity"))
{
if(captured)
{
// Spawn poss ball item with the entity NBT
ItemEntity entity;
if(shooter != null)
entity = new ItemEntity(level(), shooter.position().x, shooter.position().y, shooter.position().z, item, 0, 0, 0);
else
entity = new ItemEntity(level(), shooter.position().x, shooter.position().y, shooter.position().z, item, 0, 0, 0);
level().addFreshEntity(entity);
} else {
// Spawn the real entity
Optional<Entity> entity = EntityType.create(tag.getCompound("entity"), level());
if(entity.isPresent())
{
Entity xEntity = entity.get();
xEntity.setUUID(UUID.randomUUID());
xEntity.setPos(position());
level().addFreshEntity(xEntity);
}
LoreContainer cont = new LoreContainer(item);
cont.miscData.loreData.clear();
cont.commitLore();
if(item.getDamageValue() == 0)
{
item.setTag(new CompoundTag());
}else {
tag.remove("entity");
}
ItemEntity x;
if(shooter!=null)
x = new ItemEntity(level(), shooter.position().x, shooter.position().y, shooter.position().z, item, 0, 0, 0);
else
x = new ItemEntity(level(), position().x, position().y, position().z, item, 0, 0, 0);
level().addFreshEntity(x);
}
} else {
// No capture
// Decrease the durability
//int damage = item.getDamageValue();
//damage++;
//item.setDamageValue(damage);
// Ensure no entity tag!
tag.remove("entity");
//if(item.getDamageValue() >= item.getMaxDamage())
// return;
ItemEntity entity;
if(shooter!= null)
entity = new ItemEntity(level(),shooter.position().x, shooter.position().y, shooter.position().z, item, 0, 0, 0);
else
entity = new ItemEntity(level(), position().x, position().y, position().z, item, 0, 0, 0);
level().addFreshEntity(entity);
}
this.level().broadcastEntityEvent(this, (byte)3);
this.discard();
}
}
}

View file

@ -0,0 +1,34 @@
package dev.zontreck.thresholds.items;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.SimpleFoiledItem;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
public class UnstableSingularity extends SimpleFoiledItem
{
public UnstableSingularity(Properties pProperties) {
super(pProperties);
}
@Override
public InteractionResult useOn(UseOnContext pContext) {
BlockState block = pContext.getLevel().getBlockState(pContext.getClickedPos());
if(block.getBlock().defaultDestroyTime() < 0)
{
pContext.getLevel().explode(pContext.getPlayer(), pContext.getClickedPos().getX(), pContext.getClickedPos().getY(), pContext.getClickedPos().getZ(), 16, true, Level.ExplosionInteraction.TNT);
pContext.getLevel().setBlock(pContext.getClickedPos(), Blocks.AIR.defaultBlockState(), 0, 0);
pContext.getItemInHand().shrink(1);
}
return InteractionResult.CONSUME;
}
}

View file

@ -0,0 +1,78 @@
package dev.zontreck.thresholds.items;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.configs.ThresholdsServerConfig;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
public class VaultItem extends Item
{
@Override
public boolean isFoil(ItemStack pStack) {
return true;
}
@Override
public Item asItem()
{
return this;
}
public VaultItem(Properties pProperties) {
super(pProperties);
//TODO Auto-generated constructor stub
}
@Override
public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pUsedHand)
{
ThresholdsMod.LOGGER.info("Vault item is being used");
if(!pLevel.isClientSide && pUsedHand == InteractionHand.MAIN_HAND)
{
ItemStack is = pPlayer.getItemInHand(pUsedHand);
Profile p;
try {
p = Profile.get_profile_of(pPlayer.getStringUUID());
if(ThresholdsServerConfig.MAX_VAULTS.get()>0)
{
if(p.available_vaults >= ThresholdsServerConfig.MAX_VAULTS.get())
{
ChatHelpers.broadcastTo(pPlayer.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Red!You cannot activate anymore vaults due to the maximum set by the server admin"), ThresholdsMod.THE_SERVER);
return InteractionResultHolder.pass(is);
} else {
p.available_vaults++;
p.commit();
ChatHelpers.broadcastTo(pPlayer.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Green!You now have "+String.valueOf(p.available_vaults)+" available vaults"), ThresholdsMod.THE_SERVER);
pPlayer.setItemInHand(pUsedHand, new ItemStack(Items.AIR));
return InteractionResultHolder.consume(is);
}
}else {
p.available_vaults++;
p.commit();
ChatHelpers.broadcastTo(pPlayer.getUUID(), ChatHelpers.macro(ThresholdsMod.ThresholdsPrefix +" !Dark_Green!You now have "+String.valueOf(p.available_vaults)+" available vaults"), ThresholdsMod.THE_SERVER);
pPlayer.setItemInHand(pUsedHand, new ItemStack(Items.AIR));
return InteractionResultHolder.consume(is);
}
} catch (UserProfileNotYetExistsException e) {
e.printStackTrace();
return super.use(pLevel, pPlayer, pUsedHand);
}
}
return super.use(pLevel, pPlayer, pUsedHand);
}
}

View file

@ -0,0 +1,28 @@
package dev.zontreck.thresholds.items.tags;
import net.minecraft.nbt.CompoundTag;
public class ItemStatTag {
public static final String STATS_TAG = "stat";
public ItemStatType type;
public int value;
public ItemStatTag(ItemStatType t, int tag)
{
type = t;
value = tag;
}
public void increment(){
value++;
}
public void decrement()
{
value--;
}
public void save(CompoundTag tag)
{
tag.putInt(STATS_TAG+"_"+type.name().toLowerCase(), value);
}
}

View file

@ -0,0 +1,13 @@
package dev.zontreck.thresholds.items.tags;
public enum ItemStatType {
SWORD,
ARMOR,
PICK,
AXE,
SHOVEL,
SHOVELPATH,
HOE,
SHEARS,
EGGING
}

View file

@ -0,0 +1,47 @@
package dev.zontreck.thresholds.items.tags;
import dev.zontreck.libzontreck.chat.ChatColor;
public class ItemStatistics {
public static String makeText(ItemStatTag tag)
{
return makeText(tag.type, tag.value);
}
public static String makeText(ItemStatType type, int val)
{
String lore = ChatColor.doColors("!White!");
switch(type)
{
case SWORD -> {
lore += "Mobs Killed: ";
}
case PICK -> {
lore += "Blocks Mined: ";
}
case ARMOR -> {
lore += "Damage Taken: ";
}
case SHOVEL -> {
lore += "Blocks Dug Up: ";
}
case SHOVELPATH -> {
lore += "Paths Made: ";
}
case AXE -> {
lore += "Wood Chopped: ";
}
case HOE -> {
lore += "Blocks Hoed: ";
}
case SHEARS -> {
lore += "Sheep Shaved: ";
}
case EGGING -> {
lore += "Mobs Egged: ";
}
}
lore += ChatColor.doColors("!Green!"+val);
return lore;
}
}

View file

@ -0,0 +1,22 @@
package dev.zontreck.thresholds.items.tags;
import java.util.UUID;
public enum ModIDs {
NULL(0,0),
ZNI(0x9f, 0x9f),
OTE(5292022,1182023), // The date range of mod creation, then the day when this feature was added
ITEM_STATS(154301182023L, 0x9f);
private UUID ID;
ModIDs(long A, long B)
{
ID=new UUID(A,B);
}
public UUID get()
{
return ID;
}
}

View file

@ -0,0 +1,58 @@
package dev.zontreck.thresholds.networking;
import dev.zontreck.thresholds.ThresholdsMod;
import dev.zontreck.thresholds.networking.packets.EnergySyncS2CPacket;
import dev.zontreck.thresholds.networking.packets.OpenVaultC2SPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
public class ModMessages {
private static SimpleChannel INSTANCE;
private static int PACKET_ID = 0;
private static int id()
{
return PACKET_ID++;
}
public static void register()
{
SimpleChannel net = NetworkRegistry.ChannelBuilder.named(new ResourceLocation(ThresholdsMod.MOD_ID, "messages"))
.networkProtocolVersion(()-> "1.0")
.clientAcceptedVersions(s->true)
.serverAcceptedVersions(s->true)
.simpleChannel();
INSTANCE=net;
net.messageBuilder(OpenVaultC2SPacket.class, id(), NetworkDirection.PLAY_TO_SERVER)
.decoder(OpenVaultC2SPacket::new)
.encoder(OpenVaultC2SPacket::toBytes)
.consumerMainThread(OpenVaultC2SPacket::handle)
.add();
net.messageBuilder(EnergySyncS2CPacket.class, id(), NetworkDirection.PLAY_TO_CLIENT)
.decoder(EnergySyncS2CPacket::new)
.encoder(EnergySyncS2CPacket::toBytes)
.consumerMainThread(EnergySyncS2CPacket::handle)
.add();
}
public static <MSG> void sendToServer(MSG message){
INSTANCE.sendToServer(message);
}
public static <MSG> void sendToPlayer(MSG message, ServerPlayer player)
{
INSTANCE.send(PacketDistributor.PLAYER.with(()->player), message);
}
public static <MSG> void sendToAll(MSG message)
{
INSTANCE.send(PacketDistributor.ALL.noArg(), message);
}
}

View file

@ -0,0 +1,55 @@
package dev.zontreck.thresholds.networking.packets;
import java.util.function.Supplier;
import dev.zontreck.thresholds.blocks.entity.CompressionChamberBlockEntity;
import dev.zontreck.thresholds.blocks.entity.ItemScrubberBlockEntity;
import dev.zontreck.thresholds.blocks.entity.MagicalScrubberBlockEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
public class EnergySyncS2CPacket {
private int energy;
private BlockPos pos;
public EnergySyncS2CPacket(int amount, BlockPos pos)
{
this.energy=amount;
this.pos=pos;
}
public EnergySyncS2CPacket(FriendlyByteBuf buf)
{
energy = buf.readInt();
pos = buf.readBlockPos();
}
public void toBytes(FriendlyByteBuf buf)
{
buf.writeInt(energy);
buf.writeBlockPos(pos);
}
public void handle(Supplier<NetworkEvent.Context> ctx)
{
NetworkEvent.Context context = ctx.get();
context.enqueueWork(()->
{
// WE ARE NOW ON THE CLIENT
if(Minecraft.getInstance().level.getBlockEntity(pos) instanceof ItemScrubberBlockEntity entity)
{
entity.setEnergy(energy);
} else if(Minecraft.getInstance().level.getBlockEntity(pos) instanceof MagicalScrubberBlockEntity entity)
{
entity.setEnergy(energy);
} else if(Minecraft.getInstance().level.getBlockEntity(pos) instanceof CompressionChamberBlockEntity entity)
{
entity.setEnergy(energy);
}
});
}
}

View file

@ -0,0 +1,38 @@
package dev.zontreck.thresholds.networking.packets;
import dev.zontreck.thresholds.commands.vaults.StarterCommand;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkEvent;
import java.util.function.Supplier;
// This packet is only ever sent from the client to the server when requesting to open vaults using the EaseOfUse Buttons
public class OpenStarterVaultC2SPacket {
public OpenStarterVaultC2SPacket()
{
}
public OpenStarterVaultC2SPacket(FriendlyByteBuf buf)
{
}
public void toBytes(FriendlyByteBuf buf)
{
}
public boolean handle(Supplier<NetworkEvent.Context> supplier)
{
NetworkEvent.Context ctx = supplier.get();
ctx.enqueueWork(()->{
// On server now
ServerPlayer player = ctx.getSender();
StarterCommand.doOpen(player);
});
return true;
}
}

Some files were not shown because too many files have changed in this diff Show more