Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import xyz.holocons.mc.holoitemsrevamp.enchantment.Magnet;
import xyz.holocons.mc.holoitemsrevamp.enchantment.Memento;
import xyz.holocons.mc.holoitemsrevamp.enchantment.TideRider;
import xyz.holocons.mc.holoitemsrevamp.enchantment.Timefall;
import xyz.holocons.mc.holoitemsrevamp.integration.Integrations;

import java.lang.reflect.Field;
Expand Down Expand Up @@ -111,6 +112,7 @@ private static Set<CustomEnchantment> buildCustomEnchantments(HoloItemsRevamp pl
new Magnet(plugin),
new Memento(plugin),
new TideRider(plugin),
new Timefall(plugin),
new Backdash(plugin));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import xyz.holocons.mc.holoitemsrevamp.item.MagnetBook;
import xyz.holocons.mc.holoitemsrevamp.item.MementoItem;
import xyz.holocons.mc.holoitemsrevamp.item.TideRiderItem;
import xyz.holocons.mc.holoitemsrevamp.item.TimefallItem;

public class CollectionManager {

Expand Down Expand Up @@ -571,8 +572,8 @@ public List<Component> getLore() {
};
}

private static Idol buildKronii(HoloItemsRevamp plguin) {
return new Idol() {
private static Idol buildKronii(HoloItemsRevamp plugin) {
return new Idol(new TimefallItem(plugin)) {

@Override
public @NotNull String getSkinBase64() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package xyz.holocons.mc.holoitemsrevamp.enchantment;

import java.util.BitSet;
import java.util.concurrent.ThreadLocalRandom;

import org.bukkit.GameRule;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.Event.Result;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;

import com.strangeone101.holoitemsapi.enchantment.CustomEnchantment;
import com.strangeone101.holoitemsapi.enchantment.EnchantmentAbility;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import xyz.holocons.mc.holoitemsrevamp.HoloItemsRevamp;

public class Timefall extends CustomEnchantment implements EnchantmentAbility {

private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
private static final int[] TICK_COUNT_OPTIONs = { 60, 80, 100, 120 };

public Timefall(HoloItemsRevamp plugin) {
super(plugin, "timefall");
}

@Override
public int getMaxLevel() {
return 1;
}

@Override
public boolean conflictsWith(@NotNull Enchantment other) {
return false;
}

@Override
public boolean canEnchantItem(@NotNull ItemStack item) {
return item.getType() == Material.POWDER_SNOW_BUCKET;
}

@Override
public @NotNull Component displayName(int level) {
return Component.text("Timefall", NamedTextColor.GOLD)
.decoration(TextDecoration.ITALIC, false);
}

@Override
public int getCostMultiplier() {
return Integer.MAX_VALUE;
}

private static Block getBlockByIndex(Block origin, int maxX, int maxY, int index) {
final var z = index / (maxX * maxY);
index -= (z * maxX * maxY);
final var y = index / maxX;
final var x = index % maxX;
return origin.getRelative(x, y, z);
}

@Override
public void onPlayerInteract(PlayerInteractEvent event, ItemStack itemStack) {
event.setUseItemInHand(Result.DENY);
if (event.getAction() == Action.RIGHT_CLICK_BLOCK
&& event.getClickedBlock().getBlockData().getMaterial().isInteractable()) {
return;
}

final var radius = RANDOM.nextInt(3) + 2;
final var distance = (radius * 2) + 1;
final var blockCount = distance * distance * distance;

final var player = event.getPlayer();
player.setFreezeTicks(60);
player.getWorld().spawnParticle(Particle.WHITE_ASH,
player.getX(), player.getY() + radius - 1, player.getZ(), 200,
radius, radius, radius);

final var visitedBlocks = new BitSet(blockCount);
final var origin = player.getLocation().add(-radius, -1, -radius).getBlock();
final var randomTickSpeed = Math.min(player.getWorld().getGameRuleValue(GameRule.RANDOM_TICK_SPEED), 30);
final var tickCount = TICK_COUNT_OPTIONs[RANDOM.nextInt(TICK_COUNT_OPTIONs.length)];
for (var i = 0; i < tickCount; i++) {
final var blockIndex = RANDOM.nextInt(blockCount);
if (!visitedBlocks.get(blockIndex)) {
visitedBlocks.set(blockIndex);
final var block = getBlockByIndex(origin, distance, distance, blockIndex);
if (block.getBlockData().isRandomlyTicked()) {
for (var j = 0; j < randomTickSpeed; j++) {
block.randomTick();
}
}
}
}

if (visitedBlocks.get(RANDOM.nextInt(blockCount))) {
itemStack.setItemMeta(null);
itemStack.setType(Material.BUCKET);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package xyz.holocons.mc.holoitemsrevamp.item;

import java.util.List;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull;

import com.strangeone101.holoitemsapi.enchantment.EnchantManager;
import com.strangeone101.holoitemsapi.enchantment.Enchantable;
import com.strangeone101.holoitemsapi.item.CustomItem;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import xyz.holocons.mc.holoitemsrevamp.HoloItemsRevamp;

public class TimefallItem extends CustomItem implements Enchantable {

private final static String name = "timefall";
private final static Material material = Material.POWDER_SNOW_BUCKET;
private final static Component displayName = Component.text("Timefall", NamedTextColor.BLUE);

private final static List<Component> lore = List.of(
Component.text("Accelerate oxidation")
);

private final EnchantManager enchantManager;

public TimefallItem(HoloItemsRevamp plugin) {
super(plugin, name, material, displayName, lore);
this.enchantManager = plugin.getEnchantManager();
this.setStackable(false);
this.register();
}

@Override
protected Recipe getRecipe() {
final var recipe = new ShapedRecipe(getKey(), buildStack(null));
recipe.shape(
"ABA",
"BCB",
"ABA"
);
recipe.setIngredient('A', Material.SNOW);
recipe.setIngredient('B', Material.BONE_BLOCK);
recipe.setIngredient('C', Material.BUCKET);
return recipe;
}

@Override
public @NotNull Enchantment getEnchantment() {
return Enchantment.getByKey(getKey());
}

@Override
public ItemStack applyEnchantment(ItemStack itemStack) {
var enchantedStack = itemStack.clone();
var enchantedMeta = enchantedStack.hasItemMeta() ? enchantedStack.getItemMeta() : Bukkit.getItemFactory().getItemMeta(enchantedStack.getType());

if (enchantedMeta.addEnchant(getEnchantment(), 1, false)) {
enchantedStack.setItemMeta(enchantedMeta);
enchantManager.removeCustomEnchantmentLore(enchantedStack);
enchantManager.applyCustomEnchantmentLore(enchantedStack);
return enchantedStack;
} else {
return null;
}
}
}