Adds in the time bottle from time in a bottle. With plans to add an energy variant
This commit is contained in:
parent
b954fead1c
commit
de845ddffd
23 changed files with 734 additions and 2 deletions
|
@ -8,11 +8,15 @@ import java.util.UUID;
|
|||
|
||||
import dev.zontreck.ariaslib.util.DelayedExecutorService;
|
||||
import dev.zontreck.essentials.client.Keybindings;
|
||||
import dev.zontreck.essentials.client.renderer.TimeBoostEntityRenderer;
|
||||
import dev.zontreck.essentials.commands.teleport.TeleportActioner;
|
||||
import dev.zontreck.essentials.configs.client.AEClientConfig;
|
||||
import dev.zontreck.essentials.configs.server.AEServerConfig;
|
||||
import dev.zontreck.essentials.entities.ModEntities;
|
||||
import dev.zontreck.essentials.events.TeleportEvent;
|
||||
import dev.zontreck.essentials.gui.HeartsRenderer;
|
||||
import dev.zontreck.essentials.client.renderer.HeartsRenderer;
|
||||
import dev.zontreck.essentials.items.CreativeModeTabs;
|
||||
import dev.zontreck.essentials.items.ModItems;
|
||||
import dev.zontreck.essentials.networking.ModMessages;
|
||||
import dev.zontreck.essentials.rtp.RTPCaches;
|
||||
import dev.zontreck.essentials.rtp.RTPCachesEventHandlers;
|
||||
|
@ -21,6 +25,7 @@ import dev.zontreck.essentials.util.CommandCooldowns;
|
|||
import dev.zontreck.libzontreck.util.ChatHelpers;
|
||||
import dev.zontreck.libzontreck.util.ServerUtilities;
|
||||
import dev.zontreck.libzontreck.vectors.WorldPosition;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderers;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
@ -76,6 +81,10 @@ public class AriasEssentials {
|
|||
MinecraftForge.EVENT_BUS.register(new RTPCachesEventHandlers());
|
||||
MinecraftForge.EVENT_BUS.register(new CommandCooldowns());
|
||||
MinecraftForge.EVENT_BUS.register(RTPCachesEventHandlers.class);
|
||||
|
||||
ModItems.register(bus);
|
||||
ModEntities.register(bus);
|
||||
CreativeModeTabs.register(bus);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -142,6 +151,7 @@ public class AriasEssentials {
|
|||
|
||||
LOGGER.info("Client setup");
|
||||
|
||||
EntityRenderers.register(ModEntities.TIAB_ENTITY.get(), TimeBoostEntityRenderer::new);
|
||||
MinecraftForge.EVENT_BUS.register(new HeartsRenderer());
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package dev.zontreck.essentials.gui;
|
||||
package dev.zontreck.essentials.client.renderer;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
@ -0,0 +1,60 @@
|
|||
package dev.zontreck.essentials.client.renderer;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import dev.zontreck.essentials.entities.TimeBoostEntity;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class TimeBoostEntityRenderer extends EntityRenderer<TimeBoostEntity>
|
||||
{
|
||||
|
||||
public TimeBoostEntityRenderer(EntityRendererProvider.Context erp) {
|
||||
super(erp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void render(TimeBoostEntity entity, float entityYaw, float partialTicks, PoseStack matrixStack, MultiBufferSource bufferIn, int packedLightIn) {
|
||||
String timeRate = "x" + 2 * entity.getTimeRate();
|
||||
float paddingLeftRight = 2 * entity.getTimeRate() < 10 ? 0.11F : 0.19F;
|
||||
drawText(matrixStack, bufferIn, timeRate, new Vector3f(-paddingLeftRight, 0.064F, 0.51F), Axis.YP.rotationDegrees(0), ChatFormatting.WHITE.getColor()); // Front
|
||||
drawText(matrixStack, bufferIn, timeRate, new Vector3f(paddingLeftRight, 0.064F, -0.51F), Axis.YP.rotationDegrees(180F), ChatFormatting.WHITE.getColor()); // Back
|
||||
drawText(matrixStack, bufferIn, timeRate, new Vector3f(0.51F, 0.064F, paddingLeftRight), Axis.YP.rotationDegrees(90F), ChatFormatting.WHITE.getColor()); // Right
|
||||
drawText(matrixStack, bufferIn, timeRate, new Vector3f(-0.51F, 0.064F, -paddingLeftRight), Axis.YP.rotationDegrees(-90F), ChatFormatting.WHITE.getColor()); // Left
|
||||
drawText(matrixStack, bufferIn, timeRate, new Vector3f(-paddingLeftRight, 0.51F, -0.064F), Axis.XP.rotationDegrees(90F), ChatFormatting.WHITE.getColor()); // Top
|
||||
drawText(matrixStack, bufferIn, timeRate, new Vector3f(-paddingLeftRight, -0.51F, 0.064F), Axis.XP.rotationDegrees(-90F), ChatFormatting.WHITE.getColor()); // Bottom
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTextureLocation(TimeBoostEntity entity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawText(PoseStack matrixStack, MultiBufferSource source, String text, Vector3f translateVector, Quaternionf rotate, int color) {
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(translateVector.x(), translateVector.y(), translateVector.z());
|
||||
matrixStack.scale(0.02F, -0.02F, 0.02F);
|
||||
matrixStack.mulPose(rotate);
|
||||
getFont().drawInBatch(
|
||||
text,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
false,
|
||||
matrixStack.last().pose(),
|
||||
source,
|
||||
Font.DisplayMode.NORMAL,
|
||||
0,
|
||||
color
|
||||
);
|
||||
matrixStack.popPose();
|
||||
}
|
||||
}
|
13
src/main/java/dev/zontreck/essentials/configs/NBTKeys.java
Normal file
13
src/main/java/dev/zontreck/essentials/configs/NBTKeys.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package dev.zontreck.essentials.configs;
|
||||
|
||||
|
||||
public class NBTKeys {
|
||||
// for time in a bottle item
|
||||
public static final String STORED_TIME = "storedTime";
|
||||
public static final String TOTAL_ACCUMULATED_TIME = "totalAccumulatedTime";
|
||||
|
||||
// for time accelerator entity
|
||||
public static final String ENTITY_TIME_RATE = "timeRate";
|
||||
public static final String ENTITY_REMAINING_TIME = "remainingTime";
|
||||
public static final String ENTITY_POS = "position";
|
||||
}
|
|
@ -4,6 +4,7 @@ import dev.zontreck.ariaslib.util.Lists;
|
|||
import dev.zontreck.essentials.configs.server.sections.*;
|
||||
import dev.zontreck.essentials.util.EssentialsDatastore;
|
||||
import dev.zontreck.essentials.util.Maps;
|
||||
import dev.zontreck.libzontreck.chat.ChatColor;
|
||||
import dev.zontreck.libzontreck.util.SNbtIo;
|
||||
import net.minecraft.nbt.*;
|
||||
|
||||
|
@ -20,6 +21,7 @@ public class AEServerConfig
|
|||
public Back back;
|
||||
public Teleportation teleport;
|
||||
public Messages messages;
|
||||
public Bottles bottles;
|
||||
|
||||
|
||||
|
||||
|
@ -38,6 +40,10 @@ public class AEServerConfig
|
|||
config.back = Back.deserialize(tag.getCompound(Back.TAG_NAME));
|
||||
config.teleport = Teleportation.deserialize(tag.getCompound(Teleportation.TAG_NAME));
|
||||
config.messages = Messages.deserialize(tag.getCompound(Messages.TAG_NAME));
|
||||
if(tag.contains(Bottles.TAG_NAME))
|
||||
{
|
||||
config.bottles = Bottles.deserialize(tag.getCompound(Bottles.TAG_NAME));
|
||||
} else config.bottles = new Bottles();
|
||||
|
||||
|
||||
return config;
|
||||
|
@ -88,6 +94,7 @@ public class AEServerConfig
|
|||
"witherstormmod:bowels"
|
||||
);
|
||||
messages = new Messages();
|
||||
bottles = new Bottles();
|
||||
|
||||
|
||||
|
||||
|
@ -116,6 +123,7 @@ public class AEServerConfig
|
|||
tag.put(Back.TAG_NAME, back.serialize());
|
||||
tag.put(Teleportation.TAG_NAME, teleport.serialize());
|
||||
tag.put(Messages.TAG_NAME, messages.serialize());
|
||||
tag.put(Bottles.TAG_NAME, bottles.serialize());
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package dev.zontreck.essentials.configs.server.sections;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
public class Bottles {
|
||||
public static final String TAG_NAME = "bottles";
|
||||
public static final String TAG_DURATION = "durationEachUse";
|
||||
public static final String TAG_TICKS = "ticks";
|
||||
public static final String TAG_RANDOM_TICKS = "avgRandomTicks";
|
||||
public static final String TAG_MAX_TIME_RATE = "maxTimeRate";
|
||||
public static final String TAG_STORED_TIME = "maxTime";
|
||||
|
||||
public static final String TAG_MESSAGE_STORED_TIME = "msg_storedTime";
|
||||
public static final String TAG_MESSAGE_ACCUMULATED_TIME = "msg_accumulatedTime";
|
||||
|
||||
|
||||
|
||||
|
||||
public int eachUseDuration = 30;
|
||||
public int ticks = 20;
|
||||
public int avgRandomTicks = 512;
|
||||
public int maxTimeRate = 8;
|
||||
public int maxTime = (60 * 60 * 24 * 30); // 30 days is the default
|
||||
public String storedTimeStr = "!Dark_Green!Stored Time: [0]:[1]:[2]";
|
||||
public String accumulatedTimeStr = "!Gray!Total Accumulated Time: [0]:[1]:[2]";
|
||||
|
||||
|
||||
|
||||
public CompoundTag serialize()
|
||||
{
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt(TAG_DURATION, eachUseDuration);
|
||||
tag.putInt(TAG_TICKS, ticks);
|
||||
tag.putInt(TAG_RANDOM_TICKS, avgRandomTicks);
|
||||
tag.putInt(TAG_MAX_TIME_RATE, maxTimeRate);
|
||||
tag.putString(TAG_MESSAGE_STORED_TIME, storedTimeStr);
|
||||
tag.putString(TAG_MESSAGE_ACCUMULATED_TIME, accumulatedTimeStr);
|
||||
tag.putInt(TAG_STORED_TIME, maxTime);
|
||||
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static Bottles deserialize(CompoundTag tag)
|
||||
{
|
||||
Bottles bottles = new Bottles();
|
||||
if(tag.contains(TAG_DURATION))
|
||||
{
|
||||
bottles.eachUseDuration = tag.getInt(TAG_DURATION);
|
||||
}
|
||||
|
||||
if(tag.contains(TAG_TICKS))
|
||||
bottles.ticks = tag.getInt(TAG_TICKS);
|
||||
|
||||
if(tag.contains(TAG_RANDOM_TICKS))
|
||||
bottles.avgRandomTicks = tag.getInt(TAG_RANDOM_TICKS);
|
||||
|
||||
if(tag.contains(TAG_MAX_TIME_RATE))
|
||||
bottles.maxTimeRate = tag.getInt(TAG_MAX_TIME_RATE);
|
||||
|
||||
if(tag.contains(TAG_MESSAGE_STORED_TIME))
|
||||
bottles.storedTimeStr = tag.getString(TAG_MESSAGE_STORED_TIME);
|
||||
|
||||
if(tag.contains(TAG_MESSAGE_ACCUMULATED_TIME))
|
||||
bottles.accumulatedTimeStr = tag.getString(TAG_MESSAGE_ACCUMULATED_TIME);
|
||||
|
||||
if(tag.contains(TAG_STORED_TIME))
|
||||
bottles.maxTime = tag.getInt(TAG_STORED_TIME);
|
||||
|
||||
|
||||
|
||||
|
||||
return bottles;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package dev.zontreck.essentials.entities;
|
||||
|
||||
import dev.zontreck.essentials.AriasEssentials;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
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<EntityType<?>> REGISTER = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, AriasEssentials.MODID);
|
||||
|
||||
public static RegistryObject<EntityType<TimeBoostEntity>> TIAB_ENTITY = REGISTER.register("tiab_entity_type", ()->EntityType.Builder.<TimeBoostEntity>of(TimeBoostEntity::new, MobCategory.MISC)
|
||||
.sized(0.1f, 0.1f)
|
||||
.build(new ResourceLocation(AriasEssentials.MODID, "tiab_entity_type").toString())
|
||||
);
|
||||
|
||||
|
||||
public static void register(IEventBus bus) {
|
||||
REGISTER.register(bus);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package dev.zontreck.essentials.entities;
|
||||
|
||||
import dev.zontreck.essentials.configs.NBTKeys;
|
||||
import dev.zontreck.essentials.configs.server.AEServerConfig;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.Level;
|
||||
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.minecraftforge.network.NetworkHooks;
|
||||
|
||||
public class TimeBoostEntity extends Entity
|
||||
{
|
||||
private static final EntityDataAccessor<Integer> timeRate = SynchedEntityData.defineId(TimeBoostEntity.class, EntityDataSerializers.INT);
|
||||
|
||||
private int remainingTime;
|
||||
private BlockPos position;
|
||||
|
||||
|
||||
public TimeBoostEntity(EntityType entityType, Level worldIn) {
|
||||
super(entityType, worldIn);
|
||||
entityData.set(timeRate, 1);
|
||||
}
|
||||
|
||||
|
||||
public TimeBoostEntity(Level worldIn, BlockPos pos, double posX, double posY, double posZ) {
|
||||
this(ModEntities.TIAB_ENTITY.get(), worldIn);
|
||||
this.position = pos;
|
||||
this.setPos(posX, posY, posZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void defineSynchedData() {
|
||||
entityData.define(timeRate, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag compound) {
|
||||
entityData.set(timeRate, compound.getInt(NBTKeys.ENTITY_TIME_RATE));
|
||||
setRemainingTime(compound.getInt(NBTKeys.ENTITY_REMAINING_TIME));
|
||||
this.position = NbtUtils.readBlockPos(compound.getCompound(NBTKeys.ENTITY_POS));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAdditionalSaveData(CompoundTag compound) {
|
||||
compound.putInt(NBTKeys.ENTITY_TIME_RATE, getTimeRate());
|
||||
compound.putInt(NBTKeys.ENTITY_REMAINING_TIME, getRemainingTime());
|
||||
compound.put(NBTKeys.ENTITY_POS, NbtUtils.writeBlockPos(this.position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<ClientGamePacketListener> getAddEntityPacket() {
|
||||
return NetworkHooks.getEntitySpawningPacket(this);
|
||||
}
|
||||
|
||||
public int getTimeRate() {
|
||||
return entityData.get(timeRate);
|
||||
}
|
||||
|
||||
public void setTimeRate(int rate) {
|
||||
entityData.set(timeRate, rate);
|
||||
}
|
||||
|
||||
public int getRemainingTime() {
|
||||
return this.remainingTime;
|
||||
}
|
||||
|
||||
public void setRemainingTime(int remainingTime) {
|
||||
this.remainingTime = remainingTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
Level level = level();
|
||||
|
||||
if(position == null)
|
||||
{
|
||||
if(!level.isClientSide)
|
||||
{
|
||||
remove(RemovalReason.KILLED);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BlockState state = level.getBlockState(position);
|
||||
ServerLevel serverWorld = level.getServer().getLevel(level.dimension());
|
||||
BlockEntity targetTE = level.getBlockEntity(position);
|
||||
|
||||
|
||||
for (int i = 0; i < getTimeRate(); i++) {
|
||||
if (targetTE != null) {
|
||||
// if is TileEntity (furnace, brewing stand, ...)
|
||||
BlockEntityTicker<BlockEntity> ticker = targetTE.getBlockState().getTicker(level, (BlockEntityType<BlockEntity>) targetTE.getType());
|
||||
if (ticker != null) {
|
||||
ticker.tick(level, position, targetTE.getBlockState(), targetTE);
|
||||
}
|
||||
} else if (serverWorld != null && state.isRandomlyTicking()) {
|
||||
// if is random ticket block (grass block, sugar cane, wheat or sapling, ...)
|
||||
if (level.random.nextInt(AEServerConfig.getInstance().bottles.avgRandomTicks) == 0) {
|
||||
state.randomTick(serverWorld, position, level.random);
|
||||
}
|
||||
} else {
|
||||
// block entity broken
|
||||
this.remove(RemovalReason.KILLED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.remainingTime -= 1;
|
||||
if (this.remainingTime <= 0 && !level.isClientSide) {
|
||||
this.remove(RemovalReason.KILLED);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package dev.zontreck.essentials.items;
|
||||
|
||||
import dev.zontreck.essentials.AriasEssentials;
|
||||
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.api.distmarker.Dist;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = AriasEssentials.MODID, value = Dist.CLIENT)
|
||||
public class CreativeModeTabs {
|
||||
public static DeferredRegister<CreativeModeTab> REGISTER = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, AriasEssentials.MODID);
|
||||
|
||||
public static void register(IEventBus bus) {
|
||||
REGISTER.register(bus);
|
||||
}
|
||||
public static final List<Supplier<? extends ItemLike>> AE_TAB_ITEMS = new ArrayList<>();
|
||||
public static RegistryObject<CreativeModeTab> AE_GAME_TAB = REGISTER.register("ariasessentials", ()->CreativeModeTab.builder()
|
||||
.icon(ModItems.TIME_IN_A_BOTTLE.get()::getDefaultInstance)
|
||||
.title(Component.translatable("itemGroup.tabs.ariasessentials"))
|
||||
.displayItems((display, output) -> AE_TAB_ITEMS.forEach(it->output.accept(it.get())))
|
||||
.build());
|
||||
|
||||
public static <T extends Item> RegistryObject<T> addToAETab(RegistryObject<T> item)
|
||||
{
|
||||
AE_TAB_ITEMS.add(item);
|
||||
return item;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package dev.zontreck.essentials.items;
|
||||
|
||||
import dev.zontreck.essentials.AriasEssentials;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = AriasEssentials.MODID)
|
||||
public class EventHandlers
|
||||
{
|
||||
}
|
20
src/main/java/dev/zontreck/essentials/items/ModItems.java
Normal file
20
src/main/java/dev/zontreck/essentials/items/ModItems.java
Normal file
|
@ -0,0 +1,20 @@
|
|||
package dev.zontreck.essentials.items;
|
||||
|
||||
import dev.zontreck.essentials.AriasEssentials;
|
||||
import dev.zontreck.essentials.items.implementation.TimeBottle;
|
||||
import net.minecraft.world.item.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 DeferredRegister<Item> REGISTRY = DeferredRegister.create(ForgeRegistries.ITEMS, AriasEssentials.MODID);
|
||||
|
||||
public static void register(IEventBus bus) {
|
||||
REGISTRY.register(bus);
|
||||
}
|
||||
|
||||
public static RegistryObject<Item> TIME_IN_A_BOTTLE = CreativeModeTabs.addToAETab(REGISTRY.register("tiab", ()->new TimeBottle()));
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
package dev.zontreck.essentials.items.abstraction;
|
||||
|
||||
import dev.zontreck.essentials.configs.server.AEServerConfig;
|
||||
import dev.zontreck.essentials.entities.TimeBoostEntity;
|
||||
import dev.zontreck.essentials.util.SoundUtilities;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractBottle extends Item {
|
||||
private static final String[] NOTES = {"C", "D", "E", "F", "G2", "A2", "B2", "C2", "D2", "E2", "F2"};
|
||||
|
||||
public AbstractBottle() {
|
||||
super(new Properties().stacksTo(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult useOn(UseOnContext context) {
|
||||
Level level = context.getLevel();
|
||||
|
||||
if (level.isClientSide) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
BlockPos pos = context.getClickedPos();
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
BlockEntity targetTE = level.getBlockEntity(pos);
|
||||
ItemStack stack = context.getItemInHand();
|
||||
Player player = context.getPlayer();
|
||||
|
||||
if (targetTE == null && !blockState.isRandomlyTicking()) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
int nextRate = 1;
|
||||
int energyRequired = getEnergyCost(nextRate);
|
||||
boolean isCreativeMode = player != null && player.isCreative();
|
||||
|
||||
Optional<TimeBoostEntity> o = level.getEntitiesOfClass(TimeBoostEntity.class, new AABB(pos)).stream().findFirst();
|
||||
|
||||
if (o.isPresent()) {
|
||||
TimeBoostEntity entityTA = o.get();
|
||||
int currentRate = entityTA.getTimeRate();
|
||||
int usedUpTime = getEachUseDuration() - entityTA.getRemainingTime();
|
||||
|
||||
if (currentRate >= Math.pow(2, AEServerConfig.getInstance().bottles.maxTimeRate - 1)) {
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
nextRate = currentRate * 2;
|
||||
int timeAdded = usedUpTime / 2;
|
||||
energyRequired = getEnergyCost(nextRate);
|
||||
|
||||
if (!canUse(stack, isCreativeMode, energyRequired)) {
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
entityTA.setTimeRate(nextRate);
|
||||
entityTA.setRemainingTime(entityTA.getRemainingTime() + timeAdded);
|
||||
} else {
|
||||
// First use
|
||||
if (!canUse(stack, isCreativeMode, energyRequired)) {
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
TimeBoostEntity entityTA = new TimeBoostEntity(level, pos, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
|
||||
entityTA.setRemainingTime(getEachUseDuration());
|
||||
level.addFreshEntity(entityTA);
|
||||
}
|
||||
|
||||
if (!isCreativeMode) {
|
||||
this.applyDamage(stack, energyRequired);
|
||||
}
|
||||
playSound(level, pos, nextRate);
|
||||
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
protected int getEachUseDuration() {
|
||||
return AEServerConfig.getInstance().bottles.ticks * AEServerConfig.getInstance().bottles.eachUseDuration;
|
||||
}
|
||||
|
||||
public int getEnergyCost(int timeRate) {
|
||||
if (timeRate <= 1) return getEachUseDuration();
|
||||
return timeRate / 2 * getEachUseDuration();
|
||||
}
|
||||
|
||||
public boolean canUse(ItemStack stack, boolean isCreativeMode, int energyRequired) {
|
||||
return getStoredEnergy(stack) >= energyRequired || isCreativeMode;
|
||||
}
|
||||
|
||||
protected abstract int getStoredEnergy(ItemStack stack);
|
||||
|
||||
protected abstract void setStoredEnergy(ItemStack stack, int energy);
|
||||
|
||||
protected abstract void applyDamage(ItemStack stack, int damage);
|
||||
|
||||
public void playSound(Level level, BlockPos pos, int nextRate) {
|
||||
switch (nextRate) {
|
||||
case 1:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[0]);
|
||||
break;
|
||||
case 2:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[1]);
|
||||
break;
|
||||
case 4:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[2]);
|
||||
break;
|
||||
case 8:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[3]);
|
||||
break;
|
||||
case 16:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[4]);
|
||||
break;
|
||||
case 32:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[5]);
|
||||
break;
|
||||
case 64:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[6]);
|
||||
break;
|
||||
case 128:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[7]);
|
||||
break;
|
||||
case 256:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[8]);
|
||||
break;
|
||||
case 512:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[9]);
|
||||
break;
|
||||
default:
|
||||
SoundUtilities.playNoteBlockHarpSound(level, pos, NOTES[10]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
|
||||
return !ItemStack.isSameItem(oldStack, newStack);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package dev.zontreck.essentials.items.implementation;
|
||||
|
||||
import dev.zontreck.essentials.configs.NBTKeys;
|
||||
import dev.zontreck.essentials.configs.server.AEServerConfig;
|
||||
import dev.zontreck.essentials.items.abstraction.AbstractBottle;
|
||||
import dev.zontreck.essentials.util.StylesUtil;
|
||||
import dev.zontreck.libzontreck.util.ChatHelpers;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TimeBottle extends AbstractBottle
|
||||
{
|
||||
|
||||
public TimeBottle() {
|
||||
super();
|
||||
}
|
||||
@Override
|
||||
public boolean isFoil(ItemStack stack) {
|
||||
sanityCheck(stack);
|
||||
|
||||
return stack.getTag().contains(NBTKeys.STORED_TIME);
|
||||
}
|
||||
|
||||
private void sanityCheck(ItemStack stack) {
|
||||
|
||||
if(!stack.hasTag() || stack.getTag()==null)
|
||||
{
|
||||
stack.setTag(new CompoundTag());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack itemStack, Level world, List<Component> tooltip, TooltipFlag flag) {
|
||||
super.appendHoverText(itemStack, world, tooltip, flag);
|
||||
|
||||
int storedTime = this.getStoredEnergy(itemStack);
|
||||
int storedSeconds = storedTime / AEServerConfig.getInstance().bottles.ticks;
|
||||
int hours = storedSeconds / 3600;
|
||||
int minutes = (storedSeconds % 3600) / 60;
|
||||
int seconds = storedSeconds % 60;
|
||||
|
||||
int totalAccumulatedTime = this.getTotalAccumulatedTime(itemStack);
|
||||
int totalAccumulatedTimeSeconds = totalAccumulatedTime / AEServerConfig.getInstance().bottles.ticks;
|
||||
int totalAccumulatedHours = totalAccumulatedTimeSeconds / 3600;
|
||||
int totalAccumulatedMinutes = (totalAccumulatedTimeSeconds % 3600) / 60;
|
||||
int totalAccumulatedSeconds = totalAccumulatedTimeSeconds % 60;
|
||||
|
||||
tooltip.add(ChatHelpers.macro(AEServerConfig.getInstance().bottles.storedTimeStr, "" + hours, "" + minutes, "" + seconds));
|
||||
|
||||
tooltip.add(ChatHelpers.macro(AEServerConfig.getInstance().bottles.accumulatedTimeStr, "" + totalAccumulatedHours, "" + totalAccumulatedMinutes, "" + totalAccumulatedSeconds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStoredEnergy(ItemStack stack) {
|
||||
return stack.getOrCreateTag().getInt(NBTKeys.STORED_TIME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStoredEnergy(ItemStack stack, int energy) {
|
||||
int newStoredTime = Math.min(energy, AEServerConfig.getInstance().bottles.maxTime);
|
||||
stack.getOrCreateTag().putInt(NBTKeys.STORED_TIME, newStoredTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyDamage(ItemStack stack, int damage) {
|
||||
setStoredEnergy(stack, getStoredEnergy(stack) - damage);
|
||||
}
|
||||
|
||||
public int getTotalAccumulatedTime(ItemStack stack) {
|
||||
return stack.getOrCreateTag().getInt(NBTKeys.TOTAL_ACCUMULATED_TIME);
|
||||
}
|
||||
|
||||
public void setTotalAccumulatedTime(ItemStack stack, int value) {
|
||||
int newValue = Math.min(value, AEServerConfig.getInstance().bottles.maxTime);
|
||||
stack.getOrCreateTag().putInt(NBTKeys.TOTAL_ACCUMULATED_TIME, newValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void inventoryTick(ItemStack itemStack, Level level, Entity entity, int itemSlot, boolean isSelected) {
|
||||
super.inventoryTick(itemStack, level, entity, itemSlot, isSelected);
|
||||
if (level.isClientSide) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (level.getGameTime() % AEServerConfig.getInstance().bottles.ticks == 0) {
|
||||
int storedTime = this.getStoredEnergy(itemStack);
|
||||
if (storedTime < AEServerConfig.getInstance().bottles.maxTime) {
|
||||
this.setStoredEnergy(itemStack, storedTime + AEServerConfig.getInstance().bottles.ticks);
|
||||
}
|
||||
|
||||
int totalAccumulatedTime = this.getTotalAccumulatedTime(itemStack);
|
||||
if (totalAccumulatedTime < AEServerConfig.getInstance().bottles.maxTime) {
|
||||
this.setTotalAccumulatedTime(itemStack, totalAccumulatedTime + AEServerConfig.getInstance().bottles.ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package dev.zontreck.essentials.util;
|
||||
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
/**
|
||||
* {@link SoundUtilities#playNoteBlockHarpSound(Level, BlockPos, String)} was taken/derrived from Time-in-a-bottle github.
|
||||
*/
|
||||
public class SoundUtilities {
|
||||
public static void playNoteBlockHarpSound(Level level, BlockPos pos, String note) {
|
||||
// https://minecraft.gamepedia.com/Note_Block
|
||||
switch (note) {
|
||||
// Octave 1
|
||||
case "F#" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.5F);
|
||||
case "G" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.529732F);
|
||||
case "G#" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.561231F);
|
||||
case "A" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.594604F);
|
||||
case "A#" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.629961F);
|
||||
case "B" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.667420F);
|
||||
case "C" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.707107F);
|
||||
case "C#" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.749154F);
|
||||
case "D" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.793701F);
|
||||
case "D#" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.840896F);
|
||||
case "E" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.890899F);
|
||||
case "F" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 0.943874F);
|
||||
|
||||
|
||||
// Octave 2
|
||||
case "F#2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1F);
|
||||
case "G2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.059463F);
|
||||
case "G#2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.122462F);
|
||||
case "A2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.189207F);
|
||||
case "A#2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.259921F);
|
||||
case "B2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.334840F);
|
||||
case "C2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.414214F);
|
||||
case "C#2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.498307F);
|
||||
case "D2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.587401F);
|
||||
case "D#2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.681793F);
|
||||
case "E2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.781797F);
|
||||
case "F2" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 1.887749F);
|
||||
case "F#3" -> level.playSound(null, pos, SoundEvents.NOTE_BLOCK_HARP.get(), SoundSource.BLOCKS, 0.5F, 2F);
|
||||
}
|
||||
}
|
||||
}
|
10
src/main/java/dev/zontreck/essentials/util/StylesUtil.java
Normal file
10
src/main/java/dev/zontreck/essentials/util/StylesUtil.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package dev.zontreck.essentials.util;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Style;
|
||||
|
||||
public class StylesUtil {
|
||||
|
||||
public static final Style GREEN = Style.EMPTY.applyFormat(ChatFormatting.GREEN);
|
||||
public static final Style GRAY = Style.EMPTY.applyFormat(ChatFormatting.GRAY);
|
||||
}
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"itemGroup.tabs.ariasessentials": "Aria's Essentials",
|
||||
|
||||
"item.ariasessentials.tiab": "Time in a Bottle",
|
||||
"item.ariasessentials.eiab": "Energy in a Bottle",
|
||||
|
||||
"key.category.ariasessentials": "Aria's Essentials",
|
||||
"key.ariasessentials.autowalk": "Auto Walk"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "ariasessentials:item/eiab"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "ariasessentials:item/tiab"
|
||||
}
|
||||
}
|
BIN
src/main/resources/assets/ariasessentials/textures/item/eiab.png
Normal file
BIN
src/main/resources/assets/ariasessentials/textures/item/eiab.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"animation": {
|
||||
"frametime": 2,
|
||||
"interpolate": true
|
||||
}
|
||||
}
|
Binary file not shown.
BIN
src/main/resources/assets/ariasessentials/textures/item/tiab.png
Normal file
BIN
src/main/resources/assets/ariasessentials/textures/item/tiab.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"animation": {
|
||||
"frametime": 2,
|
||||
"interpolate": true
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue