From 6e7f4295ddb08a9c71bc9f95bcf99d3367468f1a Mon Sep 17 00:00:00 2001 From: DauphalXir <3013875189@qq.com> Date: Fri, 23 Aug 2024 20:04:06 +0800 Subject: [PATCH] test --- .../common/entity/EntityTimeAccelerator.java | 18 +- .../common/items/ModsItemsList.java | 2 + .../common/items/timeVial/EternaBottle.java | 4 - .../common/items/timeVial/EternityVial.java | 84 +++++++ .../common/items/timeVial/TimeVial.java | 40 +++- .../com/xir/NHUtilities/config/Config.java | 22 ++ .../xir/NHUtilities/loader/EventLoader.java | 5 +- .../xir/NHUtilities/loader/ItemsLoader.java | 11 +- .../xir/NHUtilities/loader/RecipeLoader.java | 73 +++++- .../com/xir/NHUtilities/main/ClientProxy.java | 5 +- .../com/xir/NHUtilities/main/NHUtilities.java | 1 + .../mixinPlugin/MixinsPackage.java | 9 +- .../GregTech/BaseMetaTileEntity_Mixin.java | 5 +- .../NHUtilities/utils/InformationHelper.java | 54 +++++ .../xir/NHUtilities/utils/TooltipsChroma.java | 44 ++++ .../assets/NHUtilities/lang/en_US.lang | 27 +++ .../assets/NHUtilities/lang/zh_CN.lang | 27 +++ .../assets/NHUtilities/shader/cosmic.frag | 182 ++++++++++++++ .../assets/NHUtilities/shader/cosmic.vert | 224 ++++++++++++++++++ .../textures/items/EternityVial.png | Bin 0 -> 1413 bytes .../textures/items/EternityVial.png.mcmeta | 6 + .../items/EternityVial_mask -back.png | Bin 0 -> 2938 bytes .../textures/items/EternityVial_mask.png | Bin 0 -> 3168 bytes .../items/EternityVial_mask.png.mcmeta | 6 + .../textures/items/EternityVial_mask2.png | Bin 0 -> 2795 bytes .../textures/items/EternityVial_mask3.png | Bin 0 -> 2596 bytes .../NHUtilities/textures/items/icon_GTNH.png | Bin 0 -> 18673 bytes 27 files changed, 819 insertions(+), 30 deletions(-) delete mode 100644 src/main/java/com/xir/NHUtilities/common/items/timeVial/EternaBottle.java create mode 100644 src/main/java/com/xir/NHUtilities/common/items/timeVial/EternityVial.java create mode 100644 src/main/java/com/xir/NHUtilities/utils/InformationHelper.java create mode 100644 src/main/java/com/xir/NHUtilities/utils/TooltipsChroma.java create mode 100644 src/main/resources/assets/NHUtilities/shader/cosmic.frag create mode 100644 src/main/resources/assets/NHUtilities/shader/cosmic.vert create mode 100644 src/main/resources/assets/NHUtilities/textures/items/EternityVial.png create mode 100644 src/main/resources/assets/NHUtilities/textures/items/EternityVial.png.mcmeta create mode 100644 src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask -back.png create mode 100644 src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask.png create mode 100644 src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask.png.mcmeta create mode 100644 src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask2.png create mode 100644 src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask3.png create mode 100644 src/main/resources/assets/NHUtilities/textures/items/icon_GTNH.png diff --git a/src/main/java/com/xir/NHUtilities/common/entity/EntityTimeAccelerator.java b/src/main/java/com/xir/NHUtilities/common/entity/EntityTimeAccelerator.java index 2ab0d39..b1c43cb 100644 --- a/src/main/java/com/xir/NHUtilities/common/entity/EntityTimeAccelerator.java +++ b/src/main/java/com/xir/NHUtilities/common/entity/EntityTimeAccelerator.java @@ -1,5 +1,7 @@ package com.xir.NHUtilities.common.entity; +import static com.xir.NHUtilities.config.Config.accelerateBlockInterval; +import static com.xir.NHUtilities.config.Config.enableBlockMode; import static com.xir.NHUtilities.config.Config.enableTimeAcceleratorBoost; import static com.xir.NHUtilities.main.NHUtilities.LOG; @@ -21,11 +23,16 @@ public class EntityTimeAccelerator extends Entity { // region Fields protected int timeRate = enableTimeAcceleratorBoost ? 8 : 4; // must be set in here for texture render init protected int remainingTime = 600; + protected boolean isGregTechMachineMode = true; protected int targetIntX; protected int targetIntY; protected int targetIntZ; + public void setGregTechMachineMode(boolean setMode) { + this.isGregTechMachineMode = setMode; + } + public int getTimeRate() { return timeRate; } @@ -50,7 +57,8 @@ public EntityTimeAccelerator(World worldIn) { super(worldIn); this.noClip = true; this.preventEntitySpawning = false; - this.setSize(0.1F, 0.1F); + // this entity setting must modify with TimeVial field double tHalfSize = 0.05D + this.setSize(0.02F, 0.02F); this.dataWatcher.addObject(2, timeRate); } @@ -78,7 +86,7 @@ private void tAccelerate() { // Referenced GTNH to control the performance in 1ms long tMaxTime = System.nanoTime() + 1000000; if (shouldAccelerate(tileEntity)) { - if (tileEntity instanceof ITileEntityTickAcceleration tileEntityITEA) { + if (isGregTechMachineMode && tileEntity instanceof ITileEntityTickAcceleration tileEntityITEA) { if (tileEntityITEA.tickAcceleration(timeRate)) return; } accelerateTileEntity(tileEntity, tMaxTime); @@ -120,7 +128,9 @@ private boolean shouldAccelerate(TileEntity tileEntity) { } private boolean shouldAccelerate(Block block) { - return block != null && block.getTickRandomly() && worldObj.getTotalWorldTime() % 10 == 0; + return enableBlockMode && block != null + && block.getTickRandomly() + && worldObj.getTotalWorldTime() % accelerateBlockInterval == 0; } // endregion @@ -129,6 +139,7 @@ private boolean shouldAccelerate(Block block) { public void readEntityFromNBT(@NotNull NBTTagCompound tagCompound) { timeRate = tagCompound.getInteger("timeRate"); this.dataWatcher.updateObject(2, tagCompound.getInteger("timeRate")); + isGregTechMachineMode = tagCompound.getBoolean("isGregTechMachineMode"); targetIntX = tagCompound.getInteger("targetIntX"); targetIntY = tagCompound.getInteger("targetIntY"); targetIntZ = tagCompound.getInteger("targetIntZ"); @@ -138,6 +149,7 @@ public void readEntityFromNBT(@NotNull NBTTagCompound tagCompound) { @Override public void writeEntityToNBT(@NotNull NBTTagCompound tagCompound) { tagCompound.setInteger("timeRate", timeRate); + tagCompound.setBoolean("isGregTechMachineMode", isGregTechMachineMode); tagCompound.setInteger("targetIntX", targetIntX); tagCompound.setInteger("targetIntY", targetIntY); tagCompound.setInteger("targetIntZ", targetIntZ); diff --git a/src/main/java/com/xir/NHUtilities/common/items/ModsItemsList.java b/src/main/java/com/xir/NHUtilities/common/items/ModsItemsList.java index 68eae91..a73ba84 100644 --- a/src/main/java/com/xir/NHUtilities/common/items/ModsItemsList.java +++ b/src/main/java/com/xir/NHUtilities/common/items/ModsItemsList.java @@ -3,6 +3,7 @@ import com.xir.NHUtilities.common.items.aItemCore.ItemBasic; import com.xir.NHUtilities.common.items.baubles.GluttonyRing; import com.xir.NHUtilities.common.items.baubles.HungerRing; +import com.xir.NHUtilities.common.items.timeVial.EternityVial; import com.xir.NHUtilities.common.items.timeVial.TimeVial; public class ModsItemsList { @@ -10,4 +11,5 @@ public class ModsItemsList { public static final ItemBasic gluttonyRing = new GluttonyRing(); public static final ItemBasic hungerRing = new HungerRing(); public static final ItemBasic timeVial = new TimeVial(); + public static final TimeVial eternityVial = new EternityVial(); } diff --git a/src/main/java/com/xir/NHUtilities/common/items/timeVial/EternaBottle.java b/src/main/java/com/xir/NHUtilities/common/items/timeVial/EternaBottle.java deleted file mode 100644 index 433707f..0000000 --- a/src/main/java/com/xir/NHUtilities/common/items/timeVial/EternaBottle.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.xir.NHUtilities.common.items.timeVial; - -public class EternaBottle extends TimeVial { -} diff --git a/src/main/java/com/xir/NHUtilities/common/items/timeVial/EternityVial.java b/src/main/java/com/xir/NHUtilities/common/items/timeVial/EternityVial.java new file mode 100644 index 0000000..6afa310 --- /dev/null +++ b/src/main/java/com/xir/NHUtilities/common/items/timeVial/EternityVial.java @@ -0,0 +1,84 @@ +package com.xir.NHUtilities.common.items.timeVial; + +import java.util.List; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +import com.xir.NHUtilities.utils.TooltipsChroma; + +import cpw.mods.fml.common.Optional; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import fox.spiteful.avaritia.items.LudicrousItems; + +// @Optional.Interface(iface = "fox.spiteful.avaritia.render.ICosmicRenderItem",modid = "Avaritia") +public class EternityVial extends TimeVial /* implements ICosmicRenderItem */ { + + // private IIcon cosmicMask; // to do ... + // private IIcon GTNH; + + public EternityVial() { + setMaxStackSize(1); + setUnlocalizedName("EternityVial"); + setTextureName("EternityVial"); + } + + // @Override + // @SideOnly(Side.CLIENT) + // public void registerIcons(IIconRegister register) { + // super.registerIcons(register); + // this.cosmicMask = register.registerIcon(NHUtilities.MODID + ":" + "EternityVial_mask3"); + // this.GTNH = register.registerIcon(NHUtilities.MODID + ":" + "icon_GTNH"); + // } + // + // @Override + // public IIcon getIcon(ItemStack stack, int pass) { + // if (pass == 1) { + // return this.GTNH; + // } + // + // return super.getIcon(stack, pass); + // } + + @Override + @Optional.Method(modid = "Avaritia") + public EnumRarity getRarity(ItemStack stack) { + return LudicrousItems.cosmic; + } + + @Override + @SideOnly(Side.CLIENT) + protected void getInfoFromNBT(@NotNull ItemStack stack, List list) { + list.add( + TooltipsChroma + .applyChromaEffect(StatCollector.translateToLocal("text.NHUtilities.EternityVial.details_0"))); + } + + @Override + protected void mergeSameVialTime(@NotNull EntityPlayer player, ItemStack stack) {} + + @Override + public void onUpdate(ItemStack stack, World worldIn, Entity playerIn, int slot, boolean isHeld) {} + + @Override + protected boolean shouldAndConsumeTimeData(@NotNull ItemStack stack, int consumedTick) { + return true; + } + + // @Override + // public IIcon getMaskTexture(ItemStack stack, EntityPlayer player) { + // return this.cosmicMask; + // } + // + // @Override + // public float getMaskMultiplier(ItemStack stack, EntityPlayer player) { + // return 1.0F; + // } +} diff --git a/src/main/java/com/xir/NHUtilities/common/items/timeVial/TimeVial.java b/src/main/java/com/xir/NHUtilities/common/items/timeVial/TimeVial.java index f35fc1a..bfbef60 100644 --- a/src/main/java/com/xir/NHUtilities/common/items/timeVial/TimeVial.java +++ b/src/main/java/com/xir/NHUtilities/common/items/timeVial/TimeVial.java @@ -6,6 +6,8 @@ import static com.xir.NHUtilities.config.Config.limitOneTimeVial; import static com.xir.NHUtilities.config.Config.timeVialDiscountValue; import static com.xir.NHUtilities.main.NHUtilities.LOG; +import static com.xir.NHUtilities.utils.InformationHelper.dividingLine; +import static com.xir.NHUtilities.utils.InformationHelper.holdShiftForDetails; import java.util.List; import java.util.Optional; @@ -16,6 +18,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; import org.jetbrains.annotations.NotNull; @@ -35,6 +38,7 @@ public class TimeVial extends ItemBasic { protected static final int MAX_ACCELERATION = enableTimeAcceleratorBoost ? 256 : 128; protected static final int NUMBER_EER = -846280; // ha,.... 114514 protected int storedTimeTick = 0; + protected final double tHalfSize = 0.01D; // 实体一半的大小 public TimeVial() { setMaxStackSize(1); @@ -46,6 +50,34 @@ public TimeVial() { @SideOnly(Side.CLIENT) public void addInformation(final @NotNull ItemStack stack, final EntityPlayer player, final List list, final boolean extraInformation) { + getInfoFromNBT(stack, list); + if (holdShiftForDetails(list)) { + list.add(dividingLine); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_0")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_1")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_2")); + list.add(dividingLine); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_3")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_4")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_5")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_6")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_7")); + list.add(dividingLine); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_7")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_8")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_9")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_10")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_11")); + list.add(dividingLine); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_12")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_13")); + list.add(StatCollector.translateToLocal("text.NHUtilities.TimeVial.details_14")); + list.add(dividingLine); + } + } + + @SideOnly(Side.CLIENT) + protected void getInfoFromNBT(@NotNull ItemStack stack, List list) { NBTTagCompound nbtTagCompound = stack.getTagCompound(); if (nbtTagCompound == null) nbtTagCompound = new NBTTagCompound(); int storedTimeSeconds = nbtTagCompound.getInteger("storedTimeTick") / 20; @@ -65,9 +97,6 @@ public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, @NotNull Wor double targetPosY = y + 0.5D; double targetPosZ = z + 0.5D; - // 实体一半的大小 - double tHalfSize = 0.05D; - // 碰撞箱的最小坐标 double minX = targetPosX - tHalfSize; double minY = targetPosY - tHalfSize; @@ -104,6 +133,7 @@ public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, @NotNull Wor } } else if (shouldAndConsumeTimeData(stack, TIME_INIT_RATE * 600)) { EntityTimeAccelerator eta = new EntityTimeAccelerator(world, x, y, z); + if (player.isSneaking()) eta.setGregTechMachineMode(false); eta.setPosition(targetPosX, targetPosY, targetPosZ); world.spawnEntityInWorld(eta); if (enableLogInfo) LOG.info( @@ -124,7 +154,7 @@ public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, @NotNull Wor return false; } - private boolean shouldAndConsumeTimeData(@NotNull ItemStack stack, int consumedTick) { + protected boolean shouldAndConsumeTimeData(@NotNull ItemStack stack, int consumedTick) { int timeTick = stack.getTagCompound() .getInteger("storedTimeTick"); if (timeTick >= consumedTick) { @@ -154,7 +184,7 @@ public void onUpdate(ItemStack stack, World worldIn, Entity playerIn, int slot, } } - private void mergeSameVialTime(@NotNull EntityPlayer player, ItemStack stack) { + protected void mergeSameVialTime(@NotNull EntityPlayer player, ItemStack stack) { for (ItemStack itemStack : player.inventory.mainInventory) { if (itemStack != null && itemStack.getItem() == this && itemStack != stack) { int thisTimeTick = stack.getTagCompound() diff --git a/src/main/java/com/xir/NHUtilities/config/Config.java b/src/main/java/com/xir/NHUtilities/config/Config.java index 235c675..dce61cb 100644 --- a/src/main/java/com/xir/NHUtilities/config/Config.java +++ b/src/main/java/com/xir/NHUtilities/config/Config.java @@ -24,12 +24,16 @@ public class Config { // region TimeVial public static boolean enableTimeVial = true; + public static boolean enableEternityVial = true; + public static boolean enableBlockMode = true; + public static int accelerateBlockInterval = 10; public static boolean enableLogInfo = false; public static boolean limitOneTimeVial = true; public static float timeVialDiscountValue = 0.9965F; // e.. public static float defaultTimeVialVolumeValue = 0.5F; public static boolean enableTimeAcceleratorBoost = false; public static boolean enableAccelerateGregTechMachine = true; + public static float accelerateGregTechMachineDiscount = 0.8F; public static boolean enableNumberMultiplierTexture = false; // endregion @@ -80,6 +84,10 @@ static File minecraftHome() { "enable GluttonyRing & AndHungerRing"); enableTimeVial = configuration .getBoolean("enableTimeVial", CATEGORY_TIME_VIAL, enableTimeVial, "enable Time Vial"); + enableEternityVial = configuration + .getBoolean("enableEternityVial", CATEGORY_TIME_VIAL, enableEternityVial, "enable Eternity Vial"); + enableBlockMode = configuration + .getBoolean("enableBlockMode", CATEGORY_TIME_VIAL, enableBlockMode, "enable Block Mode"); enableLogInfo = configuration .getBoolean("enableLogInfo", CATEGORY_TIME_VIAL, enableLogInfo, "enable log info debug"); limitOneTimeVial = configuration @@ -108,11 +116,25 @@ static File minecraftHome() { CATEGORY_TIME_VIAL, enableAccelerateGregTechMachine, "enable Accelerate GregTech Machine"); + accelerateGregTechMachineDiscount = configuration.getFloat( + "accelerateGregTechMachineDiscount", + CATEGORY_TIME_VIAL, + accelerateGregTechMachineDiscount, + 0.0F, + 1.0F, + "accelerate GregTech Machine Discount"); enableNumberMultiplierTexture = configuration.getBoolean( "enableNumberMultiplierTexture", CATEGORY_TIME_VIAL, enableNumberMultiplierTexture, "enable Number Multiplier Texture"); + accelerateBlockInterval = configuration.getInt( + "accelerateBlockInterval", + CATEGORY_TIME_VIAL, + accelerateBlockInterval, + 2, + 200, + "accelerate Block Interval"); } diff --git a/src/main/java/com/xir/NHUtilities/loader/EventLoader.java b/src/main/java/com/xir/NHUtilities/loader/EventLoader.java index 2afdc8d..9750d76 100644 --- a/src/main/java/com/xir/NHUtilities/loader/EventLoader.java +++ b/src/main/java/com/xir/NHUtilities/loader/EventLoader.java @@ -1,14 +1,15 @@ package com.xir.NHUtilities.loader; +import static com.xir.NHUtilities.config.Config.enableGluttonyRingAndHungerRing; + import net.minecraftforge.common.MinecraftForge; import com.xir.NHUtilities.common.events.GluttonyRingEvent; -import com.xir.NHUtilities.config.Config; public class EventLoader { public static void registerNHUtilitiesEvents() { - if (Config.enableGluttonyRingAndHungerRing) { + if (enableGluttonyRingAndHungerRing) { MinecraftForge.EVENT_BUS.register(new GluttonyRingEvent()); } } diff --git a/src/main/java/com/xir/NHUtilities/loader/ItemsLoader.java b/src/main/java/com/xir/NHUtilities/loader/ItemsLoader.java index 538803c..90f3ef5 100644 --- a/src/main/java/com/xir/NHUtilities/loader/ItemsLoader.java +++ b/src/main/java/com/xir/NHUtilities/loader/ItemsLoader.java @@ -1,19 +1,24 @@ package com.xir.NHUtilities.loader; +import static com.xir.NHUtilities.config.Config.enableGluttonyRingAndHungerRing; +import static com.xir.NHUtilities.config.Config.enableTimeVial; + import com.xir.NHUtilities.common.items.ModsItemsList; -import com.xir.NHUtilities.config.Config; import cpw.mods.fml.common.registry.GameRegistry; public class ItemsLoader { public static void registerNHUtilitiesItems() { - if (Config.enableGluttonyRingAndHungerRing) { + if (enableGluttonyRingAndHungerRing) { GameRegistry.registerItem(ModsItemsList.gluttonyRing, "GluttonyRing"); GameRegistry.registerItem(ModsItemsList.hungerRing, "HungerRing"); } - if (Config.enableTimeVial) { + if (enableTimeVial) { GameRegistry.registerItem(ModsItemsList.timeVial, "TimeVial"); } + if (enableTimeVial) { + GameRegistry.registerItem(ModsItemsList.eternityVial, "EternityVial"); + } } } diff --git a/src/main/java/com/xir/NHUtilities/loader/RecipeLoader.java b/src/main/java/com/xir/NHUtilities/loader/RecipeLoader.java index 8185839..0fac960 100644 --- a/src/main/java/com/xir/NHUtilities/loader/RecipeLoader.java +++ b/src/main/java/com/xir/NHUtilities/loader/RecipeLoader.java @@ -1,30 +1,91 @@ package com.xir.NHUtilities.loader; +import static com.xir.NHUtilities.config.Config.enableEternityVial; +import static com.xir.NHUtilities.config.Config.enableGluttonyRingAndHungerRing; +import static com.xir.NHUtilities.config.Config.enableTimeVial; + +import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import com.xir.NHUtilities.common.items.ModsItemsList; -import com.xir.NHUtilities.config.Config; +import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.registry.GameRegistry; +import fox.spiteful.avaritia.items.LudicrousItems; +import singulariteam.eternalsingularity.item.EternalSingularityItem; public class RecipeLoader { public static void registerNHUtilitiesRecipes() { - if (Config.enableGluttonyRingAndHungerRing) { + if (enableGluttonyRingAndHungerRing) { GameRegistry.addShapedRecipe( new ItemStack(ModsItemsList.gluttonyRing), - new Object[] { "SIS", "IAI", "SIS", 'A', Items.apple, 'S', Items.string, 'I', Items.iron_ingot }); + "SIS", + "IAI", + "SIS", + 'A', + Items.apple, + 'S', + Items.string, + 'I', + Items.iron_ingot); GameRegistry .addShapelessRecipe(new ItemStack(ModsItemsList.hungerRing), new ItemStack(ModsItemsList.gluttonyRing)); GameRegistry .addShapelessRecipe(new ItemStack(ModsItemsList.gluttonyRing), new ItemStack(ModsItemsList.hungerRing)); } - if (Config.enableTimeVial) { + if (enableTimeVial) { + GameRegistry.addShapedRecipe( + new ItemStack(ModsItemsList.timeVial), + "GGG", + "DCD", + "QBQ", + 'B', + Items.glass_bottle, + 'G', + Items.gold_ingot, + 'C', + Items.clock, + 'D', + Items.diamond, + 'Q', + new ItemStack(Items.dye, 1, 4)); GameRegistry.addShapedRecipe( new ItemStack(ModsItemsList.timeVial), - new Object[] { "GGG", "DCD", "QBQ", 'B', Items.glass_bottle, 'G', Items.gold_ingot, 'C', Items.clock, - 'D', Items.diamond, 'Q', new ItemStack(Items.dye, 1, 4) }); + "CCC", + "CTC", + "CCC", + 'C', + Blocks.cobblestone, + 'T', + ModsItemsList.timeVial); } + if (enableEternityVial) { + if (!Loader.isModLoaded("gregtech") && Loader.isModLoaded("Avaritia")) { + GameRegistry.addShapedRecipe( + new ItemStack(ModsItemsList.eternityVial), + "ICI", + "CTC", + "ICI", + 'T', + ModsItemsList.timeVial, + 'C', + new ItemStack(LudicrousItems.resource, 1, 5), + 'I', + new ItemStack(LudicrousItems.resource, 1, 6)); + } else if (Loader.isModLoaded("gregtech")) { + GameRegistry.addShapedRecipe( + new ItemStack(ModsItemsList.eternityVial), + "SSS", + "STS", + "SSS", + 'T', + ModsItemsList.timeVial, + 'S', + EternalSingularityItem.instance); + } + } + } } diff --git a/src/main/java/com/xir/NHUtilities/main/ClientProxy.java b/src/main/java/com/xir/NHUtilities/main/ClientProxy.java index b37c5c3..b9f33d6 100644 --- a/src/main/java/com/xir/NHUtilities/main/ClientProxy.java +++ b/src/main/java/com/xir/NHUtilities/main/ClientProxy.java @@ -1,8 +1,9 @@ package com.xir.NHUtilities.main; +import static com.xir.NHUtilities.config.Config.enableEnhancedTeleporterMKII; + import com.xir.NHUtilities.client.key.KeyBindings; import com.xir.NHUtilities.client.key.KeyInputHandler; -import com.xir.NHUtilities.config.Config; import com.xir.NHUtilities.loader.RenderLoader; import cpw.mods.fml.common.FMLCommonHandler; @@ -13,7 +14,7 @@ public class ClientProxy extends CommonProxy { @Override public void init(FMLInitializationEvent event) { super.init(event); - if (Config.enableEnhancedTeleporterMKII) { + if (enableEnhancedTeleporterMKII) { FMLCommonHandler.instance() .bus() .register(new KeyInputHandler()); diff --git a/src/main/java/com/xir/NHUtilities/main/NHUtilities.java b/src/main/java/com/xir/NHUtilities/main/NHUtilities.java index 9ceacff..02a1d01 100644 --- a/src/main/java/com/xir/NHUtilities/main/NHUtilities.java +++ b/src/main/java/com/xir/NHUtilities/main/NHUtilities.java @@ -16,6 +16,7 @@ modid = NHUtilities.MODID, version = Tags.VERSION, name = NHUtilities.MOD_NAME, + dependencies = " after:gregtech;" + " after:Avaritia;" + " after:DraconicEvolution;" + " after:Baubles", acceptedMinecraftVersions = "[1.7.10]") public class NHUtilities { diff --git a/src/main/java/com/xir/NHUtilities/mixinPlugin/MixinsPackage.java b/src/main/java/com/xir/NHUtilities/mixinPlugin/MixinsPackage.java index bbb136a..3eb15b9 100644 --- a/src/main/java/com/xir/NHUtilities/mixinPlugin/MixinsPackage.java +++ b/src/main/java/com/xir/NHUtilities/mixinPlugin/MixinsPackage.java @@ -1,5 +1,8 @@ package com.xir.NHUtilities.mixinPlugin; +import static com.xir.NHUtilities.config.Config.enableAccelerateGregTechMachine; +import static com.xir.NHUtilities.config.Config.enableEnhancedTeleporterMKII; + import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -7,13 +10,11 @@ import org.jetbrains.annotations.NotNull; -import com.xir.NHUtilities.config.Config; - public enum MixinsPackage { - EnhanceTeleporterMKII(Config.enableEnhancedTeleporterMKII, "DraconicEvolution", Mixins.DE_TeleporterMKII_Mixin, + EnhanceTeleporterMKII(enableEnhancedTeleporterMKII, "DraconicEvolution", Mixins.DE_TeleporterMKII_Mixin, Mixins.DE_GUITeleporter_Mixin, Mixins.DE_TeleporterPacket_Mixin), - Enable_MTEAcclerator(Config.enableAccelerateGregTechMachine, "GregTech", Mixins.GT_MTEAcclerator_Mixin); + Enable_MTEAcclerator(enableAccelerateGregTechMachine, "GregTech", Mixins.GT_MTEAcclerator_Mixin); private final Boolean isEnabledModule; private final Set targetMods = new HashSet<>(); diff --git a/src/main/java/com/xir/NHUtilities/mixins/late/GregTech/BaseMetaTileEntity_Mixin.java b/src/main/java/com/xir/NHUtilities/mixins/late/GregTech/BaseMetaTileEntity_Mixin.java index df48f71..29548d0 100644 --- a/src/main/java/com/xir/NHUtilities/mixins/late/GregTech/BaseMetaTileEntity_Mixin.java +++ b/src/main/java/com/xir/NHUtilities/mixins/late/GregTech/BaseMetaTileEntity_Mixin.java @@ -1,5 +1,6 @@ package com.xir.NHUtilities.mixins.late.GregTech; +import static com.xir.NHUtilities.config.Config.accelerateGregTechMachineDiscount; import static com.xir.NHUtilities.config.Config.enableLogInfo; import static com.xir.NHUtilities.main.NHUtilities.LOG; @@ -33,7 +34,9 @@ public boolean tickAcceleration(int tickAcceleratedRate) { int maxProgress = this.getMaxProgress(); if (maxProgress >= 2) { // obviously - tickAcceleratedRate = (int) (tickAcceleratedRate * 0.8f); // discount for accelerating gregtech machines + tickAcceleratedRate = (int) (tickAcceleratedRate * accelerateGregTechMachineDiscount); // discount for + // accelerating + // gregtech machines int newProgress = currentProgress + tickAcceleratedRate; int NHUtilities$modify = Math.min(maxProgress, newProgress); if (enableLogInfo) LOG.info("modifyArg {}", NHUtilities$modify); diff --git a/src/main/java/com/xir/NHUtilities/utils/InformationHelper.java b/src/main/java/com/xir/NHUtilities/utils/InformationHelper.java new file mode 100644 index 0000000..86399d8 --- /dev/null +++ b/src/main/java/com/xir/NHUtilities/utils/InformationHelper.java @@ -0,0 +1,54 @@ +package com.xir.NHUtilities.utils; + +import java.util.List; + +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; + +import org.lwjgl.input.Keyboard; + +/** + * referenced draconic evolution + */ +@SuppressWarnings("unused") +public final class InformationHelper { + + public static final String dividingLine = "====================="; + + public static boolean isShiftKeyDown() { + return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); + } + + public static boolean isCtrlKeyDown() { + return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); + } + + public static boolean holdShiftForDetails(List list) { + if (!isShiftKeyDown()) { + list.add( + StatCollector.translateToLocal("infohelper.NHUtilities.txt_0") + " " + + EnumChatFormatting.ITALIC + + StatCollector.translateToLocal("infohelper.NHUtilities.key_shift") + + EnumChatFormatting.RESET + + " " + + StatCollector.translateToLocal("infohelper.NHUtilities.txt_1")); + return false; + } + return true; + } + + public static boolean holdCtrlForDetails(List list) { + if (!isShiftKeyDown()) { + list.add( + StatCollector.translateToLocal("infohelper.NHUtilities.txt_0") + " " + + EnumChatFormatting.ITALIC + + StatCollector.translateToLocal("infohelper.NHUtilities.key_ctrl") + + EnumChatFormatting.RESET + + " " + + StatCollector.translateToLocal("infohelper.NHUtilities.txt_1")); + return false; + } + return true; + } + +} diff --git a/src/main/java/com/xir/NHUtilities/utils/TooltipsChroma.java b/src/main/java/com/xir/NHUtilities/utils/TooltipsChroma.java new file mode 100644 index 0000000..ee4c14a --- /dev/null +++ b/src/main/java/com/xir/NHUtilities/utils/TooltipsChroma.java @@ -0,0 +1,44 @@ +package com.xir.NHUtilities.utils; + +import static net.minecraft.util.EnumChatFormatting.*; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.EnumChatFormatting; + +import org.jetbrains.annotations.NotNull; + +/** + * referenced Avaritia mod + */ +@SuppressWarnings("unused") +public final class TooltipsChroma { + + private static final EnumChatFormatting[] CHROMA_FORMATTINGS = new EnumChatFormatting[] { RED, GOLD, YELLOW, GREEN, + AQUA, BLUE, LIGHT_PURPLE }; + + public static @NotNull String applyChromaEffect(@NotNull String input) { + return formatWithChroma(input, CHROMA_FORMATTINGS, 80.0, 1, 1); + } + + public static @NotNull String formatWithChroma(@NotNull String input, EnumChatFormatting[] colors, double delay, + int step, int posStep) { + StringBuilder formattedText = new StringBuilder(input.length() * 3); + + if (delay <= 0) { + delay = 0.001; + } + + int offset = (int) Math.floor(Minecraft.getSystemTime() / delay) % colors.length; + + for (int i = 0; i < input.length(); i++) { + char character = input.charAt(i); + + int colorIndex = ((i * posStep) + colors.length - offset) % colors.length; + + formattedText.append(colors[colorIndex].toString()); + formattedText.append(character); + } + + return formattedText.toString(); + } +} diff --git a/src/main/resources/assets/NHUtilities/lang/en_US.lang b/src/main/resources/assets/NHUtilities/lang/en_US.lang index 0c0a6d3..c04beb3 100644 --- a/src/main/resources/assets/NHUtilities/lang/en_US.lang +++ b/src/main/resources/assets/NHUtilities/lang/en_US.lang @@ -4,4 +4,31 @@ info.teleporterInfBaublesButton.txt=Support the use of-button-to open the bauble item.NHUtilities:GluttonyRing.name=GluttonyRing item.NHUtilities:HungerRing.name=HungerRing item.NHUtilities:TimeVial.name=TimeVial +item.NHUtilities:EternityVial.name=EternityVial + +# tooltips for time vial text.NHUtilities.TimeVial.tips=§ftime: §6%d hours §d%d minutes §a%d seconds +text.NHUtilities.TimeVial.details_0=Possesses 6 acceleration gradients. +text.NHUtilities.TimeVial.details_1=Default adjustable range [4->128]. +text.NHUtilities.TimeVial.details_2=Can be modified in the configuration to [8->256]. +text.NHUtilities.TimeVial.details_3=Checks every 30 seconds if the player has multiple time vials. +text.NHUtilities.TimeVial.details_4=When multiples are present, executes time accumulation, adding the most time to one vial. +text.NHUtilities.TimeVial.details_5=While setting the remaining time vials to: +text.NHUtilities.TimeVial.details_6=Uh...114514. -11 hours -45 minutes -14 seconds. +text.NHUtilities.TimeVial.details_7=Can be modified without limits in the config file. +text.NHUtilities.TimeVial.details_8=The rules for GT machine acceleration are as follows: +text.NHUtilities.TimeVial.details_9=Machines require processing time time and time must be >= 2 ticks. +text.NHUtilities.TimeVial.details_10=Executes time + acceleration multiplier * discount (default 0.8f), which is adjustable. +text.NHUtilities.TimeVial.details_11=In simple terms, adds the corresponding time to the machine's working time. +text.NHUtilities.TimeVial.details_12=Configuration file notes +text.NHUtilities.TimeVial.details_13=Allows adjusting the volume of the vial sounds and whether to enable number textures, i.e., 8x or 16x patterns. +text.NHUtilities.TimeVial.details_14=If unsure, do not modify. enableLogInfo = true + +# tooltips for time vial +text.NHUtilities.EternityVial.details_0=Eternity + +# information helper +infohelper.NHUtilities.txt_0=§6====§f[§dHold +infohelper.NHUtilities.txt_1=§dfor Details§f]§6==== +infohelper.NHUtilities.key_ctrl=§bCtrl +infohelper.NHUtilities.key_shift=§bShift diff --git a/src/main/resources/assets/NHUtilities/lang/zh_CN.lang b/src/main/resources/assets/NHUtilities/lang/zh_CN.lang index 7aa651b..54a37f2 100644 --- a/src/main/resources/assets/NHUtilities/lang/zh_CN.lang +++ b/src/main/resources/assets/NHUtilities/lang/zh_CN.lang @@ -4,4 +4,31 @@ info.teleporterInfBaublesButton.txt=支持使用-按键-打开饰品 item.NHUtilities:GluttonyRing.name=暴食指环 item.NHUtilities:HungerRing.name=饥饿指环 item.NHUtilities:TimeVial.name=时间之瓶 +item.NHUtilities:EternityVial.name=永恒之瓶 + +# tooltips for time vial text.NHUtilities.TimeVial.tips=§f时间: §6%d 小时 §d%d 分钟 §a%d 秒 +text.NHUtilities.TimeVial.details_0=拥有 6 个加速梯度 +text.NHUtilities.TimeVial.details_1=默认可调整范围[4->128] +text.NHUtilities.TimeVial.details_2=可在配置修改为[8->256] +text.NHUtilities.TimeVial.details_3=间隔 30 秒检测一次玩家是否有多个时间瓶 +text.NHUtilities.TimeVial.details_4=当有多个时执行 时间累加 添加最多时间的瓶子 +text.NHUtilities.TimeVial.details_5=同时把其余时间瓶时间修改为: +text.NHUtilities.TimeVial.details_6=额..114514. -11 小时 -45 分钟 -14秒 +text.NHUtilities.TimeVial.details_7=可在配置文件修改无限制 +text.NHUtilities.TimeVial.details_8=GT机器加速的规则如下: +text.NHUtilities.TimeVial.details_9=机器需要加工时间time且 time >= 2tick +text.NHUtilities.TimeVial.details_10=执行time + 加速倍率 * 折扣(默认0.8f) 可调整 +text.NHUtilities.TimeVial.details_11=简单说就是给机器工作时间 加上相应的时间 +text.NHUtilities.TimeVial.details_12=配置文件说明 +text.NHUtilities.TimeVial.details_13=允许调整瓶子声音大小,是否启用数字贴图 即 8x 16x的图案 +text.NHUtilities.TimeVial.details_14=如果不清楚请不要修改 enableLogInfo = true + +# tooltips for time vial +text.NHUtilities.EternityVial.details_0=Eternity + +# information helper +infohelper.NHUtilities.txt_0=§6====§f[§d按下 +infohelper.NHUtilities.txt_1=§d显示更多信息§f]§6==== +infohelper.NHUtilities.key_ctrl=§bCtrl +infohelper.NHUtilities.key_shift=§bShift diff --git a/src/main/resources/assets/NHUtilities/shader/cosmic.frag b/src/main/resources/assets/NHUtilities/shader/cosmic.frag new file mode 100644 index 0000000..5e91f4f --- /dev/null +++ b/src/main/resources/assets/NHUtilities/shader/cosmic.frag @@ -0,0 +1,182 @@ +#version 120 + +#define M_PI 3.1415926535897932384626433832795 + +const int cosmiccount = 10; +const int cosmicoutof = 101; + +uniform sampler2D texture0; +uniform vec3 lightlevel; + +uniform float time2; + +uniform float yaw; +uniform float pitch; +uniform float externalScale; + +uniform float lightmix; +uniform float opacity; + +uniform mat2 cosmicuvs[cosmiccount]; + +varying vec3 position; + +float rand2d(vec2 x) { + return fract(sin(mod(dot(x, vec2(12.9898, 78.233)), 3.14)) * 43758.5453); +} + +mat4 rotationMatrix(vec3 axis, float angle) +{ + + axis = normalize(axis); + float s = sin(angle); + float c = cos(angle); + float oc = 1.0 - c; + + return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, + oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, + oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, + 0.0, 0.0, 0.0, 1.0); +} + +void main (void) +{ + vec4 light = gl_Color; + vec4 mask = texture2D(texture0, gl_TexCoord[0].xy); + light.rgb *= lightlevel; + float correctTime = mod(time2,12000); + + float oneOverExternalScale = 1.0/externalScale; + + int uvtiles = 16; + + // background colour + vec4 col = vec4(0.1,0.0,0.0,1.0); + + float pulse = mod(correctTime,400)/400.0; + + col.g = sin(pulse*M_PI*2) * 0.075 + 0.225; + col.b = cos(pulse*M_PI*2) * 0.05 + 0.3; + + // get ray from camera to fragment + vec4 dir = normalize(vec4( -position, 0)); + + // rotate the ray to show the right bit of the sphere for the angle + float sb = sin(pitch); + float cb = cos(pitch); + dir = normalize(vec4(dir.x, dir.y * cb - dir.z * sb, dir.y * sb + dir.z * cb, 0)); + + float sa = sin(-yaw); + float ca = cos(-yaw); + dir = normalize(vec4(dir.z * sa + dir.x * ca, dir.y, dir.z * ca - dir.x * sa, 0)); + + vec4 ray; + + // draw the layers + for (int i=0; i<16; i++) { + int mult = 16-i; + + // get semi-random stuff + int j = i + 7; + float rand1 = (j * j * 4321 + j * 8) * 2.0; + int k = j + 1; + float rand2 = (k * k * k * 239 + k * 37) * 3.6; + float rand3 = rand1 * 347.4 + rand2 * 63.4; + + // random rotation matrix by random rotation around random axis + vec3 axis = normalize(vec3(sin(rand1), sin(rand2) , cos(rand3))); + + // apply + ray = dir * rotationMatrix(axis, mod(rand3, 2*M_PI)); + + // calcuate the UVs from the final ray + float rawu = 0.5 + (atan(ray.z,ray.x)/(2*M_PI)); + float rawv = 0.5 + (asin(ray.y)/M_PI); + + // get UV scaled for layers and offset by time; + float scale = mult*0.5 + 2.75; + float u = rawu * scale * externalScale; + //float v = (rawv + time * 0.00006) * scale * 0.6; + float v = (rawv + correctTime * 0.0002 * oneOverExternalScale) * scale * 0.6 * externalScale; + + vec2 tex = vec2( u, v ); + + // tile position of the current uv + int tu = int(mod(floor(u*uvtiles),uvtiles)); + int tv = int(mod(floor(v*uvtiles),uvtiles)); + + // get pseudorandom variants + int symbol = int(rand2d(vec2(tu, tv + i * 10.0)) * cosmicoutof); + int rotation = int(mod(pow(tu,float(tv)) + tu + 3 + tv*i, 8)); + bool flip = false; + if (rotation >= 4) { + rotation -= 4; + flip = true; + } + + // if it's an icon, then add the colour! + if (symbol >= 0 && symbol < cosmiccount) { + + vec2 cosmictex = vec2(1.0,1.0); + vec4 tcol = vec4(1.0,0.0,0.0,1.0); + + // get uv within the tile + float ru = clamp(mod(u,1.0)*uvtiles - tu, 0.0, 1.0); + float rv = clamp(mod(v,1.0)*uvtiles - tv, 0.0, 1.0); + + if (flip) { + ru = 1.0 - ru; + } + + float oru = ru; + float orv = rv; + + // rotate uvs if necessary + if (rotation == 1) { + oru = 1.0-rv; + orv = ru; + } else if (rotation == 2) { + oru = 1.0-ru; + orv = 1.0-rv; + } else if (rotation == 3) { + oru = rv; + orv = 1.0-ru; + } + + // get the iicon uvs for the tile + float umin = cosmicuvs[symbol][0][0]; + float umax = cosmicuvs[symbol][1][0]; + float vmin = cosmicuvs[symbol][0][1]; + float vmax = cosmicuvs[symbol][1][1]; + + // interpolate based on tile uvs + cosmictex.x = umin * (1.0-oru) + umax * oru; + cosmictex.y = vmin * (1.0-orv) + vmax * orv; + + tcol = texture2D(texture0, cosmictex); + + // set the alpha, blending out at the bunched ends + float a = tcol.r * (0.5 + (1.0/mult) * 1.0) * (1.0-smoothstep(0.15, 0.48, abs(rawv-0.5))); + + // get fancy colours + float r = (mod(rand1, 29.0)/29.0) * 0.3 + 0.4; + float g = (mod(rand2, 35.0)/35.0) * 0.4 + 0.6; + float b = (mod(rand1, 17.0)/17.0) * 0.3 + 0.7; + + // mix the colours + //col = col*(1-a) + vec4(r,g,b,1)*a; + col = col + vec4(r,g,b,1)*a; + } + } + + // apply lighting + vec3 shade = light.rgb * (lightmix) + vec3(1.0-lightmix,1.0-lightmix,1.0-lightmix); + col.rgb *= shade; + + // apply mask + col.a *= mask.a * opacity; + + col = clamp(col,0.0,1.0); + + gl_FragColor = col; +} diff --git a/src/main/resources/assets/NHUtilities/shader/cosmic.vert b/src/main/resources/assets/NHUtilities/shader/cosmic.vert new file mode 100644 index 0000000..9b319d5 --- /dev/null +++ b/src/main/resources/assets/NHUtilities/shader/cosmic.vert @@ -0,0 +1,224 @@ +#version 120 + +vec4 Ambient; +vec4 Diffuse; +vec4 Specular; + +attribute float activelights; + +varying vec3 position; + +void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3) +{ + float nDotVP; // normal . light direction + float nDotHV; // normal . light half vector + float pf; // power factor + float attenuation; // computed attenuation factor + float d; // distance from surface to light source + vec3 VP; // direction from surface to light position + vec3 halfVector; // direction of maximum highlights + + // Compute vector from surface to light position + VP = vec3 (gl_LightSource[i].position) - ecPosition3; + + // Compute distance between surface and light position + d = length(VP); + + // Normalize the vector from surface to light position + VP = normalize(VP); + + // Compute attenuation + attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + + gl_LightSource[i].linearAttenuation * d + + gl_LightSource[i].quadraticAttenuation * d * d); + + halfVector = normalize(VP + eye); + + nDotVP = max(0.0, dot(normal, VP)); + //nDotHV = max(0.0, dot(normal, halfVector)); + + //if (nDotVP == 0.0) + //{ + pf = 0.0; + //} + //else + //{ + // pf = pow(nDotHV, gl_FrontMaterial.shininess); + //} + Ambient += gl_LightSource[i].ambient * attenuation; + Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation; + //Specular += gl_LightSource[i].specular * pf * attenuation; +} + +void spotLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3) +{ + float nDotVP; // normal . light direction + float nDotHV; // normal . light half vector + float pf; // power factor + float spotDot; // cosine of angle between spotlight + float spotAttenuation; // spotlight attenuation factor + float attenuation; // computed attenuation factor + float d; // distance from surface to light source + vec3 VP; // direction from surface to light position + vec3 halfVector; // direction of maximum highlights + + // Compute vector from surface to light position + VP = vec3 (gl_LightSource[i].position) - ecPosition3; + + // Compute distance between surface and light position + d = length(VP); + + // Normalize the vector from surface to light position + VP = normalize(VP); + + // Compute attenuation + attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + + gl_LightSource[i].linearAttenuation * d + + gl_LightSource[i].quadraticAttenuation * d * d); + + // See if point on surface is inside cone of illumination + spotDot = dot(-VP, normalize(gl_LightSource[i].spotDirection)); + + if (spotDot < gl_LightSource[i].spotCosCutoff) + { + spotAttenuation = 0.0; // light adds no contribution + } + else + { + spotAttenuation = pow(spotDot, gl_LightSource[i].spotExponent); + + } + // Combine the spotlight and distance attenuation. + attenuation *= spotAttenuation; + + halfVector = normalize(VP + eye); + + nDotVP = max(0.0, dot(normal, VP)); + //nDotHV = max(0.0, dot(normal, halfVector)); + + //if (nDotVP == 0.0) + //{ + pf = 0.0; + //} + //else + //{ +// pf = pow(nDotHV, gl_FrontMaterial.shininess); +// + // } + Ambient += gl_LightSource[i].ambient * attenuation; + Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation; + //Specular += gl_LightSource[i].specular * pf * attenuation; + +} + +void directionalLight(in int i, in vec3 normal) +{ + float nDotVP; // normal . light direction + float nDotHV; // normal . light half vector + float pf; // power factor + + nDotVP = max(0.0, dot(normal, normalize(vec3 (gl_LightSource[i].position)))); + //nDotHV = max(0.0, dot(normal, vec3 (gl_LightSource[i].halfVector))); + + //if (nDotVP == 0.0) + //{ + pf = 0.0; + //} + //else + //{ +// pf = pow(nDotHV, gl_FrontMaterial.shininess); + //} + Ambient += gl_LightSource[i].ambient; + Diffuse += gl_LightSource[i].diffuse * nDotVP; + //Specular += gl_LightSource[i].specular * pf; +} + +vec3 fnormal(void) +{ + //Compute the normal + vec3 normal = gl_NormalMatrix * gl_Normal; + normal = normalize(normal); + return normal; +} + +void ProcessLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3) +{ + if (gl_LightSource[i].spotCutoff==180.0) + { + if (gl_LightSource[i].position.w==0.0) + { + directionalLight(i, normal); + } + else + { + pointLight(i, normal, eye, ecPosition3); + } + } + else + { + spotLight(i,normal,eye,ecPosition3); + } +} + +void flight(in vec3 normal, in vec4 ecPosition, float alphaFade) +{ + vec4 color; + vec3 ecPosition3; + vec3 eye; + int i; + + ecPosition3 = (vec3 (ecPosition)) / ecPosition.w; + eye = vec3 (0.0, 0.0, 1.0); + + // Clear the light intensity accumulators + Ambient = vec4 (0.0); + Diffuse = vec4 (0.0); + Specular = vec4 (0.0); + + if (activelights>0) + { + ProcessLight(0,normal,eye,ecPosition3); + } + if (activelights>1) + { + ProcessLight(1,normal,eye,ecPosition3); + } + //if (activelights>2) + //{ + // ProcessLight(2,normal,eye,ecPosition3); + //} + //if (activelights>3) + //{ + // ProcessLight(3,normal,eye,ecPosition3); + //} + + color = gl_FrontLightModelProduct.sceneColor + + Ambient * gl_FrontMaterial.ambient + + Diffuse * gl_FrontMaterial.diffuse; + color += Specular * gl_FrontMaterial.specular; + color = clamp( color, 0.0, 1.0 ); + gl_FrontColor = color; + gl_FrontColor.a *= alphaFade; +} + +void main (void) +{ + vec3 transformedNormal; + float alphaFade = 1.0; + + // Eye-coordinate position of vertex, needed in various calculations + vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; + + // Do fixed functionality vertex transform + gl_Position = ftransform(); + transformedNormal = fnormal(); + flight(transformedNormal, ecPosition, alphaFade); + + //Enable texture coordinates + gl_TexCoord[0] = gl_MultiTexCoord0; + //gl_TexCoord[1] = gl_MultiTexCoord1; + //gl_TexCoord[2] = gl_MultiTexCoord2; + //gl_TexCoord[3] = gl_MultiTexCoord3; + + position = (gl_ModelViewMatrix * gl_Vertex).xyz; +} \ No newline at end of file diff --git a/src/main/resources/assets/NHUtilities/textures/items/EternityVial.png b/src/main/resources/assets/NHUtilities/textures/items/EternityVial.png new file mode 100644 index 0000000000000000000000000000000000000000..1e3a94a45b04b9a2f97137b53d35731574122ed3 GIT binary patch literal 1413 zcmeAS@N?(olHy`uVBq!ia0vp^0zkZggAGWsTD}nhQY`6?zK#qG8~bX02Tlg^6_P!I zd>I(pxfvLG1Q{5f?`B}=n99J=70&q9iy!t)x7$D3zfgF*C13FE6!3!9>qc&oEhQjyKTG>z*!-AsNnZXL)AJ zgp0KPzMdl7=mr_d+VDVIhro8%xZmB>9qNZ(Atc7QOrV4 zhnyC09O>Twdfy|_zjJo2-~7T?RA$xvwblN6g-Xxu4qZB@_+7oCM31AviWAR^`D*^0 zFqk9E!_-yx{_;a`0Jg>C$>elV&cP?G3x_!rv7w68M zyJLR7u2A0Yi~1*F<_~Yb*Y9d!Uy}R{{0HRRWDHU z_fx-m)5nj6*RNiE`s~@W6gFvTX|tw(|LV-Gt+iQtdwYu{^Y35V+1bhYo9Bo0nKNg0 z?AvGellS12D^q$KRMyqk*T*k=C%#+?e*)|kJu*^dH?>|nba^NK$hi%g#Ce#83zv@Z0v1FtxZpNx0-zJ zoL{C+fJ%!Rlh91P>wc3PcRCz+I)lSQX=jAauI_Gb&0`UrcszCI?%hr$e}8{hpY7YX zm)YOAeS31!x31s6t9Q$59DMg~orjcsg4?ry4K6$_e;+(p@FwudjT;d%jCCE>D;GZC zRb!f@(dP13;Whuho`isjKOMLJZ8#b_z2ZxQ(b+nO$-aiI92~L^Csv)+efwO!i!tfa zzlK_O_x1@-K3AGsS!F3d@Y(X?P3B)khly*~t}SDF;RYc>|RGE zPB3WIn51^tWx;umGYyL}m?mYcDp19rx(c)xdxWLkTkHCj{noqBFV3Ip*`Z+Yon2X3 z*`Gycm5HQ9@D+CNNi(h93x6$DkloX{VEJcI0((<>}{QAiyRHn;;xHY zr%e<4S&;vYS?;H%Tj%`x?Wbq&*|u$4iS7!isS6e^bo@4hr%;%2KF37k|LpE|&H h4b-%%AgA|TKl5|vv>k0yCxOKvgQu&X%Q~loCIHg(e|`V} literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/NHUtilities/textures/items/EternityVial.png.mcmeta b/src/main/resources/assets/NHUtilities/textures/items/EternityVial.png.mcmeta new file mode 100644 index 0000000..76bf944 --- /dev/null +++ b/src/main/resources/assets/NHUtilities/textures/items/EternityVial.png.mcmeta @@ -0,0 +1,6 @@ +{ + "animation": { + "frametime": 5, + "interpolate": true + } +} diff --git a/src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask -back.png b/src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask -back.png new file mode 100644 index 0000000000000000000000000000000000000000..3eebf2c24b1f8072ba0f02382bb83c4153c629a1 GIT binary patch literal 2938 zcmbVO2~-p37LF{k3SkkbQW`?lsALZz$uq10!D9qj#H~V@3^0&nVkVG)B0{i=0*V_g z2N6VYdjbzdQ53|Dr$D6DKA)umf)<}uBvOHDweJtxv8}c}%{i0#Xa4Wr``z!}|0X%1 z%NEZtpJk52;bsH}3Bte~53W+v>EPR#`_vxX%;Z6g(+&O9H4QyMc!(;2ugyLgjhHpk@1Po8=8m&M9e2fc?fAjxj&qM1f?n9 z@U&$SP+Ahi6%)O^2#eG_;6Ms1MFh1}BExuUK5@)153KdCsYJpUM47}V`sxD`RtiH2 z{-^>buqiY$M58eXo?Hr@&0=vl?gR#nL8H<_T> z7I@+l6O>9hk4jakR1_7Hf-2&vbS{@mr7@@s1{om8SgK4ZQj=wv+oT5pj6n)Su0&87 zLGMu%izX}iM8I@B1*v?>tqhxx2?$12i{w-~g{Dtw3@C=CaPnk@WGuKCqQVkb3d@uj zz|yC%@&r_gVhQL6Tu*KPDgcmHD4dG%UM^DUR0vENkOI<}5ahjREFx77Q^Q~kO;$i~ zKnkGgrq4#s^H;zkC8~%(QORVXLMJH`7z_%HK#D?SVpN6Af5!k8h?Fp&2&%>+(>P=X zGlC9E=E-9+7t%O98f_dZM8!y4>hGbRJP#U={%a^`8L>zy`ctqN;>Do~sR$&DNJa55 zRW6Gs5~gJ2`J)n40RjVd%y-`h`}>C~&^SZ_Hn6b8euUrve>R=VW|J8d`WRiIkQXe& zlp+}f2MhQ_APxmV#JpHfChW=dV33(2b{v_(V!`BCCYw%&4D7j_ST44)qCHp#+gE9tJa&O4KJq)lZ-C zqELTZud%&%CeqBqnZO5p{x-`t|4VDgx2ewWg+~qvna# z$60uTYq2(drnKv&q#4uI7I>Rp-5c%j@Ng+ID==`KC@JYg*~uf;_5qnyKj8fcwmCkL z-@NHs31w{Wjw>oDsVpgRd3-*f-3xK+%0khekCRt zhMlen^+Qn{uA{3fKa`YRQBhH@yL1Np0LU(%k#h3gZW*?$mk&$kCDzR{-(rxBSC0;Q zg3X&|cpE^s64@45-jRI&?vm(vag2|6$xrN^AhL^dc;?&(zFr59ER8el*9O#_J-fB5 zYn`Bcd8&(;F`I)`&ZtC)cvGLq$cICzT$ekE9=Knwnh1=v=lb6c9@sL}Uyk>y*EMTQ z`bZ8t6b8*P9Ucv*PTkJ4xX^1D{Tu{Zy=F~0+THlo;2^2Jy}jT^_tWYQdjsKR!`mz* zalzKsLOW7nYtW~*j~_qY)z^IUrnyk~sH3~vxV84X_Brhu&6R}?J7RJ(F{{oqv%giF z%e8dQs6{rOv~P*r*<@sZ-&{zIerRO18gI4rGr!bj)dy9Mj*iDdN%f1qC@GQYdcH7Y znOW~IESz7s@O<^?z<}&<*nF-_n^qe}i4wT4xT4kOcXqb5;(?7ggSsi~_o)^b7neVk`<{J7t8 zdjZi#wR-1X>c%&(_E}z$_i64{N1yH0KywEn-KDcx*fIz@b^78(;X&_=xu8;E!_Jpq zz2fmR-kMac4Zd9Ko>26?SK$la^lnVMoMdm6oOxukw6lKGo8k?)X*kt$uif4u|6EMW zr3;7!{^Y^r-WM+z_s$55u~{xI6%ux5Z!_I)^k3?phFxCiuLMIw#)rdPIr$nfWBw2)Pfm?JPaU)A?jc{iPPM^jc-wxUsYq_REUqIzgsJ2ByFP?~NNX_b!>k%}lEzWczTOQ<}VwMq4{X&uiTH)9xqD*LFB&Jm|f4 zQ2u)OnS*tHfzO`7n3R&H0Mj)7OmC_SKs|nUz9N<`6-Mdyw> zM$gONxidT}$`MC6uuhPXVX7MVuAr}Z`Arq|QPVW1pW-tETus~c|BizLmI+6$$U*g_4(Hg6W`KsEkWiZ$#irv{rVdXdOmfzP@=6wy(92l~LJh1jEAez9%5K3Y z*rTrp;(DQ8JsH)nQi#-krl-7PA9loi1l7oDP|Znpmci zwBSq;2WDe1j4;Jg4o@TyNF<|}2#mm7Sj^?YYy^?PBAJlS?7UdOn?;{0i&u^9^aZ}; ztaPi@EaP%BGc!4vd=6cHJUCT?~KK0>~cX_BW8d!Ith6vn$l*Oac(?Lkr@^YkC*|% z402{;mMJYbY9%dNk~F+2RP39OnFzvxnZptYlb+0^hQGA{SD{v1&H_~vuwe-s;cI!I zWMUbgKN6P6VE8puL+XjttUp4 zDme>~!yyR041*=oRJ};Z77KMK5T^iT>vTveTOx#ol2o2pgy6b2>s2I{;grCe^?I;g zD$z+{A)gO;65?#JSb(r~2oGZ;BE1Ob>BJJ8Cw#L$#zKG=L=7Ko$Jv-p?Z~1C3RE?# zvvnrmpLf0)2xf;|WGLor133$G)*siiI){mOF!1*>cx^T_9S27LL>I4N6q#zxL@l@? z4Y2i>y5qhtcnY2I=b`Jwd|b>IB5Xb?N@XJg0nXO(MLf1nAVn}K0_#ypSL%NZ9q1I6 z@wz1aA)$BDilw8bG#u=yT-Jvt^Y@hazB>G_>HdGoaGhJ}YlU%tFTResx3*nS$c`bf zmpfm(4iWItbqwJqz>@_WG6~J*m*7~Ns8%Vo>Dl)-T$t{y9(ba1bU7g+{=Bn}Y~LUKj;(*yr|rlbRlqEU=YjK?`Q(<#%9)GjElRBS#`f_V`qlUKR1@CC zn!|N^esNpu!P+2o|JIwidD;6<-{)@q>N=Traq(SkD+VC_*yua?aS5(Yx-{L=QT8v{&BO?)8VNrIDQV1>tiiHf<`x7w z!|B25X~lQw`;7x`KD^))8WNJTeOTVsIl1la?V|cz-pXM2!oqo!XXW+Ylh&=U2ikqLspxxs3$ifb9&x8JMWy12sQwg7jzv1`wljX}5d z4F~EDUH#vShc~$`FEw`uUE6Uj@)mN_gpKbm( zV*up>xzT7hTW$Nx%G3)m2wFb2+sv6W(*^$fM~zGBJ?ixLb;Zhb(Z*rEOK)syde#2f zfs&G;ZXl1YXei@Ox`JC16x$L&7ylP!-0U)CKfqh=2r zJXmKi^vn(m^R}Qyv7hI?!W`|>Qrw-y&Lw=rsubx`_ydh zJ(s$Fi`I6Zov$6S*rmZ#!v8rxKX54b>Gqd5+F!H@7(I0H1@qbzv=$kPd@ev zuVN?*E~JCnq%1?H-KCjp;yCNkNxt{5wfERMW>(*B0|T;a9T`4_7n|g~Q~rYoyJ0;k zYWM8f4|}=VRlUc|ei>C*H)#{Vur8((b;pca~@li8l{6(PfnvB4(=~wy3V@LVM^i)KK6xM#nH+rDC zEXiDc)p#iRBj?soe{Tk|Mmudlvt?4x^M(B+Ef4J#HEpz_rq;{CMd!B23yN+v-nkfR zZf(pgrCM@_bieIT#6Un#6B81Md?uQHGOTE#QZn%P4?pA#xfPClwPV4&?%^{)Jj~Mw zJ<#^-(Z~HWFC7-td%p FzXG|zszv|+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask.png.mcmeta b/src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask.png.mcmeta new file mode 100644 index 0000000..76bf944 --- /dev/null +++ b/src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask.png.mcmeta @@ -0,0 +1,6 @@ +{ + "animation": { + "frametime": 5, + "interpolate": true + } +} diff --git a/src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask2.png b/src/main/resources/assets/NHUtilities/textures/items/EternityVial_mask2.png new file mode 100644 index 0000000000000000000000000000000000000000..e4ab36b342d4ebd43d9d876b966fc215b0b04f15 GIT binary patch literal 2795 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 literal 0 HcmV?d00001