diff --git a/.gitignore b/.gitignore index c83156d5..f3c4b9ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /bin/ +/lib/ /.settings/ /target/ /.idea/ diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/ActiveStorage.java b/src/main/java/io/github/sefiraat/crystamaehistoria/ActiveStorage.java deleted file mode 100644 index c92f2080..00000000 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/ActiveStorage.java +++ /dev/null @@ -1,74 +0,0 @@ -package io.github.sefiraat.crystamaehistoria; - -import io.github.sefiraat.crystamaehistoria.magic.CastInformation; -import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicProjectile; -import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicSummon; -import io.github.sefiraat.crystamaehistoria.runnables.spells.SpellTick; -import io.github.thebusybiscuit.slimefun4.libraries.dough.blocks.BlockPosition; -import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair; -import lombok.Getter; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Entity; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class ActiveStorage { - - @Getter - private final Map> projectileMap = new HashMap<>(); - @Getter - private final Map> strikeMap = new HashMap<>(); - @Getter - private final Map tickingCastables = new HashMap<>(); - @Getter - private final Map blocksToRemove = new HashMap<>(); - @Getter - private final Map summonedEntities = new HashMap<>(); - - public void removeProjectile(MagicProjectile magicProjectile) { - projectileMap.remove(magicProjectile); - } - - public void clearAll() { - // Cancels all outstanding spells being cast - for (SpellTick spellTick : tickingCastables.keySet()) { - spellTick.cancel(); - } - tickingCastables.clear(); - - // Clear all projectiles created from spells - for (MagicProjectile magicProjectile : projectileMap.keySet()) { - magicProjectile.kill(); - } - projectileMap.clear(); - - // Clear all spawned entities created from spells - for (MagicSummon magicSummon : summonedEntities.keySet()) { - magicSummon.kill(); - } - summonedEntities.clear(); - - // Remove all temporary blocks - removeBlocks(true); - blocksToRemove.clear(); - } - - public void removeBlocks(boolean forceRemoveAll) { - long time = System.currentTimeMillis(); - for (Map.Entry entry : blocksToRemove.entrySet()) { - if (forceRemoveAll || entry.getValue() < time) { - entry.getKey().getBlock().setType(Material.AIR); - } - } - } - - public void stopBlockRemoval(Block block) { - BlockPosition blockPosition = new BlockPosition(block); - blocksToRemove.remove(blockPosition); - } - - -} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/CrystamaeHistoria.java b/src/main/java/io/github/sefiraat/crystamaehistoria/CrystamaeHistoria.java index eb964f8f..5706d0cf 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/CrystamaeHistoria.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/CrystamaeHistoria.java @@ -9,14 +9,13 @@ import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicProjectile; import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicSummon; import io.github.sefiraat.crystamaehistoria.runnables.RunnableManager; -import io.github.sefiraat.crystamaehistoria.runnables.spells.SpellTick; +import io.github.sefiraat.crystamaehistoria.runnables.spells.SpellTickRunnable; import io.github.sefiraat.crystamaehistoria.slimefun.Structure; import io.github.sefiraat.crystamaehistoria.stories.StoriesManager; import io.github.sefiraat.crystamaehistoria.utils.CrystaTag; import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair; import org.apache.commons.lang.Validate; import org.bstats.bukkit.Metrics; -import org.bukkit.entity.Entity; import org.bukkit.plugin.PluginManager; import javax.annotation.Nonnull; @@ -33,7 +32,7 @@ public class CrystamaeHistoria extends AbstractAddon { private StoriesManager storiesManager; private ListenerManager listenerManager; private RunnableManager runnableManager; - private ActiveStorage activeStorage; + private SpellMemory spellMemory; private EffectManager effectManager; public CrystamaeHistoria() { @@ -60,8 +59,8 @@ public static StoriesManager getStoriesManager() { return instance.storiesManager; } - public static ActiveStorage getActiveStorage() { - return instance.activeStorage; + public static SpellMemory getActiveStorage() { + return instance.spellMemory; } public static EffectManager getEffectManager() { @@ -78,17 +77,17 @@ public static PluginManager getPluginManager() { @Nonnull public static Map> getProjectileMap() { - return instance.activeStorage.getProjectileMap(); + return instance.spellMemory.getProjectileMap(); } @Nonnull public static Map> getStrikeMap() { - return instance.activeStorage.getStrikeMap(); + return instance.spellMemory.getStrikeMap(); } @Nonnull public static Map getSummonedEntityMap() { - return instance.activeStorage.getSummonedEntities(); + return instance.spellMemory.getSummonedEntities(); } @Nonnull @@ -108,8 +107,8 @@ public static CastInformation getStrikeCastInfo(UUID lightningStrike) { } @Nonnull - public static Map getTickingMap() { - return instance.activeStorage.getTickingCastables(); + public static Map getTickingMap() { + return instance.spellMemory.getTickingCastables(); } @Override @@ -125,7 +124,7 @@ public void enable() { this.storiesManager = new StoriesManager(); this.listenerManager = new ListenerManager(); this.runnableManager = new RunnableManager(); - this.activeStorage = new ActiveStorage(); + this.spellMemory = new SpellMemory(); this.effectManager = new EffectManager(this); structure.setup(); @@ -138,7 +137,7 @@ public void enable() { @Override protected void disable() { - activeStorage.clearAll(); + spellMemory.clearAll(); saveConfig(); instance = null; } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/SpellMemory.java b/src/main/java/io/github/sefiraat/crystamaehistoria/SpellMemory.java new file mode 100644 index 00000000..f4ccde5d --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/SpellMemory.java @@ -0,0 +1,122 @@ +package io.github.sefiraat.crystamaehistoria; + +import io.github.sefiraat.crystamaehistoria.magic.CastInformation; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicProjectile; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicSummon; +import io.github.sefiraat.crystamaehistoria.runnables.spells.SpellTickRunnable; +import io.github.thebusybiscuit.slimefun4.libraries.dough.blocks.BlockPosition; +import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +public class SpellMemory { + + @Getter + private final Map> projectileMap = new HashMap<>(); + @Getter + private final Map> strikeMap = new HashMap<>(); + @Getter + private final Map tickingCastables = new HashMap<>(); + @Getter + private final Map blocksToRemove = new HashMap<>(); + @Getter + private final Map summonedEntities = new HashMap<>(); + @Getter + private final Map playersWithFlight = new HashMap<>(); + + public void clearAll() { + // Cancels all outstanding spells being cast + for (SpellTickRunnable spellTickRunnable : tickingCastables.keySet()) { + spellTickRunnable.cancel(); + } + tickingCastables.clear(); + + // Clear all projectiles created from spells + removeProjectiles(true); + projectileMap.clear(); + + // Clear all spawned entities created from spells + removeEntities(true); + summonedEntities.clear(); + + // Remove all temporary blocks + removeBlocks(true); + blocksToRemove.clear(); + + // Remove all temporary blocks + removeFlight(true); + playersWithFlight.clear(); + } + + public void removeProjectiles(boolean forceRemoveAll) { + Set set = new HashSet<>(CrystamaeHistoria.getProjectileMap().keySet()); + for (MagicProjectile magicProjectile : set) { + long expiry = projectileMap.get(magicProjectile).getSecondValue(); + if (System.currentTimeMillis() > expiry || forceRemoveAll) { + magicProjectile.kill(); + } else { + magicProjectile.run(); + } + } + } + + public void removeEntities(boolean forceRemoveAll) { + Set set = new HashSet<>(CrystamaeHistoria.getSummonedEntityMap().keySet()); + for (MagicSummon magicSummon : set) { + long expiry = summonedEntities.get(magicSummon); + if (System.currentTimeMillis() > expiry || magicSummon.getMob() == null || forceRemoveAll) { + magicSummon.kill(); + } else { + magicSummon.run(); + } + } + } + + public void removeBlocks(boolean forceRemoveAll) { + long time = System.currentTimeMillis(); + final Set> set = new HashSet<>(blocksToRemove.entrySet()); + for (Map.Entry entry : set) { + if (forceRemoveAll || entry.getValue() < time) { + entry.getKey().getBlock().setType(Material.AIR); + blocksToRemove.remove(entry.getKey()); + } + } + } + + public void removeFlight(boolean forceRemoveAll) { + long time = System.currentTimeMillis(); + final Set> set = new HashSet<>(playersWithFlight.entrySet()); + for (Map.Entry entry : set) { + if (forceRemoveAll || entry.getValue() < time) { + Player player = Bukkit.getPlayer(entry.getKey()); + if (player != null) { + player.setAllowFlight(false); + player.setFlying(false); + playersWithFlight.remove(entry.getKey()); + } + } + } + } + + public void removeFlight(Player player) { + if (playersWithFlight.containsKey(player.getUniqueId())) { + player.setAllowFlight(false); + player.setFlying(false); + playersWithFlight.remove(player.getUniqueId()); + } + } + + public void stopBlockRemoval(Block block) { + BlockPosition blockPosition = new BlockPosition(block); + blocksToRemove.remove(blockPosition); + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/commands/GetBlockColors.java b/src/main/java/io/github/sefiraat/crystamaehistoria/commands/GetBlockColors.java new file mode 100644 index 00000000..aa7c5fbc --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/commands/GetBlockColors.java @@ -0,0 +1,59 @@ +//package io.github.sefiraat.crystamaehistoria.commands; +// +//import io.github.mooy1.infinitylib.commands.SubCommand; +//import org.bukkit.Color; +//import org.bukkit.Material; +//import org.bukkit.block.Block; +//import org.bukkit.command.CommandSender; +// import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock; +//import org.bukkit.entity.Player; +// +//import javax.annotation.ParametersAreNonnullByDefault; +//import java.io.BufferedWriter; +//import java.io.File; +//import java.io.FileWriter; +//import java.io.IOException; +//import java.util.List; +// +//public class GetBlockColors extends SubCommand { +// +// public GetBlockColors() { +// super("block_color", "Generates block colors", true); +// } +// +// @Override +// @ParametersAreNonnullByDefault +// protected void execute(CommandSender sender, String[] args) { +// if (sender instanceof Player) { +// Player player = (Player) sender; +// Block block = player.getLocation().getBlock(); +// try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File("block_colors.yml")))) { +// for (Material material : Material.values()) { +// if (material.isBlock()) { +// block.setType(material); +// Color color = Color.fromRGB(((CraftBlock) block).getNMS().getBlock().s().al); +// writeLine(writer, +// material.name() + ": [" + +// + color.getRed() + ", " +// + color.getGreen() + ", " +// + color.getBlue() + "]" +// ); +// } +// } +// } catch (IOException exception) { +// exception.printStackTrace(); +// } +// } +// } +// +// private static void writeLine(BufferedWriter writer, String line) throws IOException { +// writer.write(line); +// writer.newLine(); +// } +// +// @Override +// protected void complete(CommandSender commandSender, String[] strings, List list) { +// +// } +// +//} \ No newline at end of file diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/config/ConfigManager.java b/src/main/java/io/github/sefiraat/crystamaehistoria/config/ConfigManager.java index 099cb531..43d624f0 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/config/ConfigManager.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/config/ConfigManager.java @@ -15,6 +15,7 @@ public class ConfigManager { private final FileConfiguration blocks; private final FileConfiguration stories; private final FileConfiguration research; + private final FileConfiguration blockColors; public ConfigManager() { this.blocks = getConfig("blocks.yml"); @@ -23,6 +24,8 @@ public ConfigManager() { this.stories.options().copyDefaults(true); this.research = getConfig("research.yml"); this.research.options().copyDefaults(true); + this.blockColors = getConfig("block_colors.yml"); + this.blockColors.options().copyDefaults(true); } /** diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/RemovalBlocksListener.java b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/BlockRemovalListener.java similarity index 96% rename from src/main/java/io/github/sefiraat/crystamaehistoria/listeners/RemovalBlocksListener.java rename to src/main/java/io/github/sefiraat/crystamaehistoria/listeners/BlockRemovalListener.java index 6a6482a1..ca456f1e 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/RemovalBlocksListener.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/BlockRemovalListener.java @@ -11,7 +11,7 @@ import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.player.PlayerBucketFillEvent; -public class RemovalBlocksListener implements Listener { +public class BlockRemovalListener implements Listener { @EventHandler public void onRemovableBlockBreak(BlockBreakEvent event) { diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/realisationaltar/CrystalBreakListener.java b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/CrystalBreakListener.java similarity index 83% rename from src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/realisationaltar/CrystalBreakListener.java rename to src/main/java/io/github/sefiraat/crystamaehistoria/listeners/CrystalBreakListener.java index 7809dfdc..5537fd90 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/realisationaltar/CrystalBreakListener.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/CrystalBreakListener.java @@ -1,6 +1,8 @@ -package io.github.sefiraat.crystamaehistoria.slimefun.machines.realisationaltar; +package io.github.sefiraat.crystamaehistoria.listeners; import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; +import io.github.sefiraat.crystamaehistoria.slimefun.machines.realisationaltar.RealisationAltar; +import io.github.sefiraat.crystamaehistoria.slimefun.machines.realisationaltar.RealisationAltarCache; import io.github.sefiraat.crystamaehistoria.stories.Story; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryRarity; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryShardProfile; @@ -27,7 +29,7 @@ public void onBreakCrystal(BlockBreakEvent event) { private void handleCrystal(Block block) { BlockPosition blockPosition = new BlockPosition(block); - for (RealisationAltarCache cache : RealisationAltar.CACHE_MAP.values()) { + for (RealisationAltarCache cache : RealisationAltar.getCaches().values()) { Pair pair = cache.getCrystalStoryMap().get(blockPosition); if (pair != null) { StoryRarity rarity = pair.getFirstValue(); diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/ListenerManager.java b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/ListenerManager.java index bef49610..be98d79c 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/ListenerManager.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/ListenerManager.java @@ -1,7 +1,6 @@ package io.github.sefiraat.crystamaehistoria.listeners; import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; -import io.github.sefiraat.crystamaehistoria.slimefun.machines.realisationaltar.CrystalBreakListener; import org.bukkit.event.Listener; public class ListenerManager { @@ -11,7 +10,8 @@ public ListenerManager() { addListener(new PlayerInteract()); addListener(new SpellEffectListener()); addListener(new CrystalBreakListener()); - addListener(new RemovalBlocksListener()); + addListener(new BlockRemovalListener()); + addListener(new MaintenanceListener()); } private void addListener(Listener listener) { diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/MaintenanceListener.java b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/MaintenanceListener.java new file mode 100644 index 00000000..b2645c35 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/MaintenanceListener.java @@ -0,0 +1,17 @@ +package io.github.sefiraat.crystamaehistoria.listeners; + +import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.LiquefactionBasin; +import me.mrCookieSlime.Slimefun.api.BlockStorage; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.CauldronLevelChangeEvent; + +public class MaintenanceListener implements Listener { + + @EventHandler + public void onRemovableBlockBreak(CauldronLevelChangeEvent event) { + if (BlockStorage.check(event.getBlock()) instanceof LiquefactionBasin) { + event.setCancelled(true); + } + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/PlayerInteract.java b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/PlayerInteract.java index fc4a5ea3..5ac0064c 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/PlayerInteract.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/PlayerInteract.java @@ -2,9 +2,9 @@ import io.github.sefiraat.crystamaehistoria.magic.CastInformation; import io.github.sefiraat.crystamaehistoria.magic.CastResult; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.InstanceStave; import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.SpellSlot; import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.Stave; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.StaveStorage; import io.github.sefiraat.crystamaehistoria.utils.Keys; import io.github.sefiraat.crystamaehistoria.utils.datatypes.DataTypeMethods; import io.github.sefiraat.crystamaehistoria.utils.datatypes.PersistentStaveDataType; @@ -23,28 +23,28 @@ public class PlayerInteract implements Listener { @EventHandler public void onInteract(PlayerInteractEvent e) { - Player player = e.getPlayer(); - ItemStack stave = player.getInventory().getItemInMainHand(); - SlimefunItem slimefunItem = SlimefunItem.getByItem(stave); + final Player player = e.getPlayer(); + final ItemStack stack = player.getInventory().getItemInMainHand(); + final SlimefunItem slimefunItem = SlimefunItem.getByItem(stack); if (slimefunItem instanceof Stave) { - Stave sfStave = (Stave) slimefunItem; - StaveStorage staveStorage = new StaveStorage(stave); + Stave stave = (Stave) slimefunItem; + InstanceStave staveInstance = new InstanceStave(stack); SpellSlot slot = SpellSlot.getByPlayerAndAction(player, e.getAction()); if (slot == null) { return; } - CastInformation castInformation = new CastInformation(player, sfStave.getLevel()); - CastResult castResult = staveStorage.tryCastSpell(slot, castInformation); + CastInformation castInformation = new CastInformation(player, stave.getLevel()); + CastResult castResult = staveInstance.tryCastSpell(slot, castInformation); if (castResult == CastResult.CAST_SUCCESS) { - ItemMeta itemMeta = stave.getItemMeta(); + ItemMeta itemMeta = stack.getItemMeta(); DataTypeMethods.setCustom( itemMeta, Keys.PDC_STAVE_STORAGE, PersistentStaveDataType.TYPE, - staveStorage.getSpellInstanceMap() + staveInstance.getSpellInstanceMap() ); - stave.setItemMeta(itemMeta); - StaveStorage.setStaveLore(stave, staveStorage); + stack.setItemMeta(itemMeta); + staveInstance.buildLore(); player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent( ThemeType.SUCCESS.getColor() + "Casting spell: " + castInformation.getSpellType().getId() )); diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/SpellEffectListener.java b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/SpellEffectListener.java index d27b2057..ab3c2ec6 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/SpellEffectListener.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/listeners/SpellEffectListener.java @@ -12,6 +12,7 @@ import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.LightningStrike; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -23,8 +24,12 @@ import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityInteractEvent; import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.player.PlayerEggThrowEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.weather.LightningStrikeEvent; import org.bukkit.inventory.ItemStack; @@ -150,10 +155,27 @@ public void onMagicSummonDeath(EntityDeathEvent event) { } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onMagicSummonChangeBlock(EntityChangeBlockEvent event) { + public void onRideRavager(EntityChangeBlockEvent event) { NamespacedKey key = Keys.PDC_IS_SPAWN_OWNER; if (DataTypeMethods.hasCustom(event.getEntity(), key, PersistentUUIDDataType.TYPE)) { event.setCancelled(true); } } + +// // TODO Will not work until you can teleport entities with passengers +// @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) +// public void onRideRavager(PlayerInteractEntityEvent event) { +// NamespacedKey key = Keys.PDC_IS_SPAWN_OWNER; +// UUID uuid = DataTypeMethods.getCustom(event.getRightClicked(), key, PersistentUUIDDataType.TYPE); +// if (uuid != null && uuid.equals(event.getPlayer().getUniqueId()) && event.getRightClicked().getType() == EntityType.RAVAGER) { +// event.getRightClicked().addPassenger(event.getPlayer()); +// } +// } + + @EventHandler + public void onPlayerLogout(PlayerQuitEvent event) { + CrystamaeHistoria.getActiveStorage().removeFlight(event.getPlayer()); + } + + } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/SpellType.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/SpellType.java index d62be7e8..27cbfcf6 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/SpellType.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/SpellType.java @@ -12,7 +12,11 @@ import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Bright; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.CallLightning; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Chaos; +import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Compass; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Deity; +import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Gravity; +import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Hearthstone; +import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.PhantomsFlight; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.EarthNova; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.EndermansVeil; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.EtherealFlow; @@ -49,6 +53,7 @@ import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Tempest; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.TimeCompression; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.TimeDilation; +import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Tracer; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.Vacuum; import io.github.sefiraat.crystamaehistoria.magic.spells.tier1.WitherWeather; import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.LiquefactionBasinCache; @@ -72,6 +77,7 @@ public enum SpellType { BRIGHT(new Bright()), CALL_LIGHTNING(new CallLightning()), CHAOS(new Chaos()), + COMPASS(new Compass()), DEITY(new Deity()), EARTH_NOVA(new EarthNova()), ENDERMANS_VEIL(new EndermansVeil()), @@ -81,8 +87,10 @@ public enum SpellType { FIRE_NOVA(new FireNova()), FLAME_SPRITE(new FlameSprite()), FROST_NOVA(new FrostNova()), + GRAVITY(new Gravity()), HEAL(new Heal()), HEALING_MIST(new HealingMist()), + HEARTHSTONE(new Hearthstone()), HELLSCAPE(new Hellscape()), HOLY_COW(new HolyCow()), GYROSCOPIC(new Gyroscopic()), @@ -92,6 +100,7 @@ public enum SpellType { LEECH_BOMB(new LeechBomb()), LOVE_POTION(new LovePotion()), OVIPAROUS(new Oviparous()), + PHANTOMS_FLIGHT(new PhantomsFlight()), POISON_NOVA(new PoisonNova()), PRISM(new Prism()), PROTECTORATE(new Protectorate()), @@ -109,6 +118,7 @@ public enum SpellType { TEMPEST(new Tempest()), TIME_COMPRESSION(new TimeCompression()), TIME_DILATION(new TimeDilation()), + TRACER(new Tracer()), VACUUM(new Vacuum()), WITHER_WEATHER(new WitherWeather()); diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/plates/PlateStorage.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/InstancePlate.java similarity index 74% rename from src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/plates/PlateStorage.java rename to src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/InstancePlate.java index 96e705e1..2db0d83e 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/plates/PlateStorage.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/InstancePlate.java @@ -1,9 +1,9 @@ -package io.github.sefiraat.crystamaehistoria.slimefun.tools.plates; +package io.github.sefiraat.crystamaehistoria.magic.spells.core; +import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; import io.github.sefiraat.crystamaehistoria.magic.CastInformation; import io.github.sefiraat.crystamaehistoria.magic.CastResult; import io.github.sefiraat.crystamaehistoria.magic.SpellType; -import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; import io.github.sefiraat.crystamaehistoria.utils.theme.ThemeType; import lombok.Getter; import lombok.Setter; @@ -13,9 +13,10 @@ import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; @Getter -public class PlateStorage { +public class InstancePlate { private final int tier; private final SpellType storedSpell; @@ -24,16 +25,16 @@ public class PlateStorage { @Setter private long cooldown = 0; - public PlateStorage(int tier, SpellType storedSpell, int crysta) { + public InstancePlate(int tier, SpellType storedSpell, int crysta) { this.tier = tier; this.storedSpell = storedSpell; this.crysta = crysta; } - public static void setPlateLore(ItemStack itemStack, PlateStorage plateStorage) { + public static void setPlateLore(ItemStack itemStack, InstancePlate instancePlate) { - String magic = plateStorage != null ? ThemeType.toTitleCase(plateStorage.storedSpell.getId()) : "None"; - String crysta = plateStorage != null ? String.valueOf(plateStorage.crysta) : "0"; + String magic = instancePlate != null ? ThemeType.toTitleCase(instancePlate.storedSpell.getId()) : "None"; + String crysta = instancePlate != null ? String.valueOf(instancePlate.crysta) : "0"; final String[] lore = new String[]{ "A magically charged plate storing magic", @@ -65,7 +66,9 @@ public CastResult tryCastSpell(CastInformation castInformation) { if (cooldown <= System.currentTimeMillis()) { spell.castSpell(castInformation); this.crysta -= crystaCost; - this.cooldown = System.currentTimeMillis() + (spell.getCooldown(castInformation) * 1000L); + final long cdSeconds = (long) (spell.getCooldownSeconds(castInformation) * 1000); + CrystamaeHistoria.log(Level.WARNING, String.valueOf(cdSeconds)); + this.cooldown = System.currentTimeMillis() + cdSeconds; return CastResult.CAST_SUCCESS; } else { return CastResult.ON_COOLDOWN; diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/stave/StaveStorage.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/InstanceStave.java similarity index 60% rename from src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/stave/StaveStorage.java rename to src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/InstanceStave.java index 9e040abb..461d690a 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/stave/StaveStorage.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/InstanceStave.java @@ -1,8 +1,8 @@ -package io.github.sefiraat.crystamaehistoria.slimefun.tools.stave; +package io.github.sefiraat.crystamaehistoria.magic.spells.core; import io.github.sefiraat.crystamaehistoria.magic.CastInformation; import io.github.sefiraat.crystamaehistoria.magic.CastResult; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.PlateStorage; +import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.SpellSlot; import io.github.sefiraat.crystamaehistoria.utils.Keys; import io.github.sefiraat.crystamaehistoria.utils.datatypes.DataTypeMethods; import io.github.sefiraat.crystamaehistoria.utils.datatypes.PersistentStaveDataType; @@ -12,22 +12,23 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.Map; -public class StaveStorage { +public class InstanceStave { @Getter - private final Map spellInstanceMap = new EnumMap<>(SpellSlot.class); + public final ItemStack itemStack; - public StaveStorage() { - - } + @Getter + private final Map spellInstanceMap = new EnumMap<>(SpellSlot.class); - public StaveStorage(ItemStack itemStack) { - Map map = DataTypeMethods.getCustom( + public InstanceStave(@Nonnull ItemStack itemStack) { + this.itemStack = itemStack; + final Map map = DataTypeMethods.getCustom( itemStack.getItemMeta(), Keys.PDC_STAVE_STORAGE, PersistentStaveDataType.TYPE @@ -37,7 +38,7 @@ public StaveStorage(ItemStack itemStack) { } } - public static void setStaveLore(ItemStack itemStack, StaveStorage staveStorage) { + public void buildLore() { final String[] lore = new String[]{ "A stave with the ability to hold", "magically charged plates.", @@ -49,12 +50,12 @@ public static void setStaveLore(ItemStack itemStack, StaveStorage staveStorage) finalLore.add(passiveColor + s); } - for (SpellSlot slot : SpellSlot.cashedValues) { - PlateStorage plateStorage = staveStorage.spellInstanceMap.get(slot); - if (plateStorage != null) { + for (SpellSlot slot : SpellSlot.getCashedValues()) { + final InstancePlate instancePlate = this.spellInstanceMap.get(slot); + if (instancePlate != null) { finalLore.add(""); - String magic = ThemeType.toTitleCase(plateStorage.getStoredSpell().getId()); - String crysta = String.valueOf(plateStorage.getCrysta()); + final String magic = ThemeType.toTitleCase(instancePlate.getStoredSpell().getId()); + final String crysta = String.valueOf(instancePlate.getCrysta()); finalLore.add(ThemeType.RARITY_MYTHICAL.getColor() + ThemeType.toTitleCase(slot.name())); finalLore.add(ThemeType.PASSIVE.getColor() + "Spell: " + ThemeType.NOTICE.getColor() + magic); finalLore.add(ThemeType.PASSIVE.getColor() + "Crysta: " + ThemeType.NOTICE.getColor() + crysta); @@ -62,19 +63,19 @@ public static void setStaveLore(ItemStack itemStack, StaveStorage staveStorage) } finalLore.add(""); finalLore.add(ThemeType.applyThemeToString(ThemeType.CLICK_INFO, ThemeType.STAVE.getLoreLine())); - final ItemMeta itemMeta = itemStack.getItemMeta(); + final ItemMeta itemMeta = this.itemStack.getItemMeta(); itemMeta.setLore(finalLore); - itemStack.setItemMeta(itemMeta); + this.itemStack.setItemMeta(itemMeta); } - public void setSlot(SpellSlot spellSlot, PlateStorage plateStorage) { - spellInstanceMap.put(spellSlot, plateStorage); + public void setSlot(SpellSlot spellSlot, InstancePlate instancePlate) { + spellInstanceMap.put(spellSlot, instancePlate); } public CastResult tryCastSpell(SpellSlot slot, CastInformation castInformation) { - PlateStorage plateStorage = spellInstanceMap.get(slot); - if (plateStorage != null) { - return plateStorage.tryCastSpell(castInformation); + InstancePlate instancePlate = spellInstanceMap.get(slot); + if (instancePlate != null) { + return instancePlate.tryCastSpell(castInformation); } else { return CastResult.CAST_FAIL_SLOT_EMPTY; } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/Spell.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/Spell.java index 6c3faa65..1f5c4692 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/Spell.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/Spell.java @@ -2,7 +2,7 @@ import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; import io.github.sefiraat.crystamaehistoria.magic.CastInformation; -import io.github.sefiraat.crystamaehistoria.runnables.spells.SpellTick; +import io.github.sefiraat.crystamaehistoria.runnables.spells.SpellTickRunnable; import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; import io.github.sefiraat.crystamaehistoria.utils.theme.ThemeType; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; @@ -105,12 +105,11 @@ public void castSpell(CastInformation castInformation) { if (spellCore.isTickingSpell()) { registerTicker(castInformation, spellCore.getTickInterval(), spellCore.getNumberOfTicks()); } - } @ParametersAreNonnullByDefault - public int getCooldown(CastInformation castInformation) { - return spellCore.isCooldownMultiplied() ? spellCore.getCooldownSeconds() * (3 - castInformation.getStaveLevel()) : spellCore.getCooldownSeconds(); + public double getCooldownSeconds(CastInformation castInformation) { + return spellCore.isCooldownDivided() ? spellCore.getCooldownSeconds() / castInformation.getStaveLevel() : spellCore.getCooldownSeconds(); } @ParametersAreNonnullByDefault @@ -199,7 +198,6 @@ protected void displayParticleEffect(Location location, Particle particle, doubl } } - @ParametersAreNonnullByDefault protected void displayParticleEffect(Entity entity, double rangeRadius, int numberOfParticles, Particle.DustOptions dustOptions) { displayParticleEffect(entity.getLocation(), rangeRadius, numberOfParticles, dustOptions); @@ -221,41 +219,63 @@ protected void displayParticleEffect(Location location, double rangeRadius, int } @ParametersAreNonnullByDefault - protected void pullEntity(UUID caster, Location pullToLocation, Entity pushed, double force) { - Vector vector = pushed.getLocation().toVector().subtract(pullToLocation.toVector()).normalize().multiply(-force); - pushEntity(caster, vector, pushed); + protected boolean tryBreakBlock(UUID caster, Block block) { + Player player = Bukkit.getPlayer(caster); + if (player != null + && hasPermission(caster, block, Interaction.BREAK_BLOCK) + && block.getType().getHardness() < 100 + ) { + block.breakNaturally(player.getInventory().getItemInMainHand()); + return true; + } + return false; + } + + @ParametersAreNonnullByDefault + protected boolean pullEntity(UUID caster, Location pullToLocation, Entity pushed, double force) { + Vector vector = pushed.getLocation().toVector() + .subtract(pullToLocation.toVector()) + .normalize() + .multiply(-force); + return pushEntity(caster, vector, pushed); } @ParametersAreNonnullByDefault - protected void pushEntity(UUID caster, Location pushFromLocation, Entity pushed, double force) { - Vector vector = pushed.getLocation().toVector().subtract(pushFromLocation.toVector()).normalize().multiply(force); - pushEntity(caster, vector, pushed); + protected boolean pushEntity(UUID caster, Location pushFromLocation, Entity pushed, double force) { + Vector vector = pushed.getLocation().toVector() + .subtract(pushFromLocation.toVector()) + .normalize() + .multiply(force); + return pushEntity(caster, vector, pushed); } @ParametersAreNonnullByDefault - protected void pushEntity(UUID caster, Vector vector, Entity pushed) { + protected boolean pushEntity(UUID caster, Vector vector, Entity pushed) { Interaction interaction = pushed instanceof Player ? Interaction.ATTACK_PLAYER : Interaction.INTERACT_ENTITY; if (hasPermission(caster, pushed.getLocation(), interaction)) { pushed.setVelocity(vector); + return true; } + return false; } @ParametersAreNonnullByDefault - protected void damageEntity(LivingEntity livingEntity, UUID caster, double damage) { - damageEntity(livingEntity, caster, damage, null, 0); + protected boolean damageEntity(LivingEntity livingEntity, UUID caster, double damage) { + return damageEntity(livingEntity, caster, damage, null, 0); } @ParametersAreNonnullByDefault - protected void damageEntity(LivingEntity livingEntity, UUID caster, double damage, @Nullable Location knockbackOrigin, double knockbackForce) { + protected boolean damageEntity(LivingEntity livingEntity, UUID caster, double damage, @Nullable Location knockbackOrigin, double knockbackForce) { Interaction interaction = livingEntity instanceof Player ? Interaction.ATTACK_PLAYER : Interaction.ATTACK_ENTITY; if (hasPermission(caster, livingEntity.getLocation(), interaction)) { Player player = Bukkit.getPlayer(caster); livingEntity.damage(damage, player); + if (knockbackOrigin != null && knockbackForce > 0) { + pushEntity(caster, knockbackOrigin, livingEntity, knockbackForce); + } + return true; } - - if (knockbackOrigin != null && knockbackForce > 0) { - pushEntity(caster, knockbackOrigin, livingEntity, knockbackForce); - } + return false; } /** @@ -289,23 +309,6 @@ protected void registerLightningStrike(LightningStrike lightningStrike, CastInfo CrystamaeHistoria.getActiveStorage().getStrikeMap().put(lightningStrike.getUniqueId(), new Pair<>(castInformation, expiry)); } - /** - * Used to register the projectile's events to the definition and then - * the projectile/definition to the projectileMap. Used when detecting - * the projectile hitting targets. - * - * @param magicProjectile The {@link MagicProjectile} being stored - * @param castInformation The {@link CastInformation} with the stave information - */ - @ParametersAreNonnullByDefault - private void registerProjectile(MagicProjectile magicProjectile, CastInformation castInformation, long projectileDuration) { - castInformation.setBeforeProjectileHitEvent(spellCore.getBeforeProjectileHitEvent()); - castInformation.setProjectileHitEvent(spellCore.getProjectileHitEvent()); - castInformation.setAfterProjectileHitEvent(spellCore.getAfterProjectileHitEvent()); - Long expiry = System.currentTimeMillis() + projectileDuration; - CrystamaeHistoria.getActiveStorage().getProjectileMap().put(magicProjectile, new Pair<>(castInformation, expiry)); - } - /** * Used to register the projectile's events to the definition and then * the projectile/definition to the projectileMap. Used when detecting @@ -321,7 +324,7 @@ protected void registerTicker(CastInformation castInformation, long period, int castInformation.setTickEvent(spellCore.getTickEvent()); castInformation.setAfterTicksEvent(spellCore.getAfterAllTicksEvent()); - final SpellTick ticker = new SpellTick(castInformation, tickAmount); + final SpellTickRunnable ticker = new SpellTickRunnable(castInformation, tickAmount); CrystamaeHistoria.getActiveStorage().getTickingCastables().put(ticker, tickAmount); ticker.runTaskTimer(CrystamaeHistoria.getInstance(), 0, period); } @@ -415,5 +418,4 @@ protected boolean hasPermission(UUID player, Location location, Interaction inte OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player); return Slimefun.getProtectionManager().hasPermission(offlinePlayer, location, interaction); } - } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/SpellCore.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/SpellCore.java index 1ca8eb47..20247cb6 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/SpellCore.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/SpellCore.java @@ -12,7 +12,7 @@ @Getter public class SpellCore { - private final int cooldownSeconds; + private final double cooldownSeconds; private final double range; private final int crystaCost; private final double damageAmount; @@ -22,7 +22,7 @@ public class SpellCore { private final double projectileKnockbackAmount; private final int numberOfTicks; private final int tickInterval; - private final boolean cooldownMultiplied; + private final boolean cooldownDivided; private final boolean rangeMultiplied; private final boolean crystaMultiplied; private final boolean damageMultiplied; @@ -66,7 +66,7 @@ public SpellCore(SpellCoreBuilder spellCoreBuilder) { this.projectileKnockbackAmount = spellCoreBuilder.getProjectileKnockbackAmount(); this.numberOfTicks = spellCoreBuilder.getNumberOfTicks(); this.tickInterval = spellCoreBuilder.getTickInterval(); - this.cooldownMultiplied = spellCoreBuilder.isCooldownDivided(); + this.cooldownDivided = spellCoreBuilder.isCooldownDivided(); this.rangeMultiplied = spellCoreBuilder.isRangeMultiplied(); this.crystaMultiplied = spellCoreBuilder.isCrystaMultiplied(); this.damageMultiplied = spellCoreBuilder.isDamageMultiplied(); diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/SpellCoreBuilder.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/SpellCoreBuilder.java index 2cf575a3..6d710473 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/SpellCoreBuilder.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/core/SpellCoreBuilder.java @@ -16,18 +16,18 @@ public class SpellCoreBuilder { // All - private final int cooldownSeconds; + private final double cooldownSeconds; private final double range; private final int crystaCost; private final boolean cooldownDivided; private final boolean rangeMultiplied; private final boolean crystaMultiplied; + private final Map> positiveEffectPairMap = new HashMap<>(); + private final Map> negativeEffectPairMap = new HashMap<>(); private int particleNumber = 1; - // Instant Casts private boolean isInstantCast; private Consumer instantCastEvent; - // Projectile Based Spells private boolean isProjectileSpell; private boolean isProjectileVsEntitySpell; @@ -41,7 +41,6 @@ public class SpellCoreBuilder { private Consumer projectileHitEvent; private Consumer projectileHitBlockEvent; private Consumer afterProjectileHitEvent; - // Ticking Spells private boolean isTickingSpell; private int numberOfTicks; @@ -50,27 +49,22 @@ public class SpellCoreBuilder { private boolean tickIntervalMultiplied; private Consumer tickEvent; private Consumer afterAllTicksEvent; - // Damaging Spells private boolean isDamagingSpell; private double damageAmount; private boolean damageMultiplied; private double knockbackAmount; private boolean knockbackMultiplied; - // Healing Spells private boolean isHealingSpell; private double healAmount; private boolean healMultiplied; - // Affecting spells private boolean isEffectingSpell; - private final Map> positiveEffectPairMap = new HashMap<>(); - private final Map> negativeEffectPairMap = new HashMap<>(); private boolean amplificationMultiplied; private boolean effectDurationMultiplied; - public SpellCoreBuilder(int cooldownSeconds, boolean cooldownDivided, double range, boolean rangeMultiplied, int crystaCost, boolean crystaMultiplied) { + public SpellCoreBuilder(double cooldownSeconds, boolean cooldownDivided, double range, boolean rangeMultiplied, int crystaCost, boolean crystaMultiplied) { this.cooldownSeconds = cooldownSeconds; this.cooldownDivided = cooldownDivided; this.range = range; diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AirNova.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AirNova.java index 5e5aadda..895d4561 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AirNova.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AirNova.java @@ -12,7 +12,6 @@ import org.bukkit.Particle; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; @@ -54,7 +53,7 @@ public void projectileHit(CastInformation castInformation) { livingEntity, castInformation.getCaster(), getDamage(castInformation), - castInformation.getProjectileLocation().clone().subtract(0, 1,0), + castInformation.getProjectileLocation().clone().subtract(0, 1, 0), getKnockback(castInformation) ); displayParticleEffect(livingEntity, Particle.SWEEP_ATTACK, 1, 5); diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AirSprite.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AirSprite.java index 705551d9..83cb60aa 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AirSprite.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AirSprite.java @@ -33,9 +33,9 @@ public void cast(CastInformation castInformation) { Location location = castInformation.getCastLocation(); for (int i = 0; i < castInformation.getStaveLevel(); i++) { Location spawnLocation = location.clone().add( - ThreadLocalRandom.current().nextDouble(-3,3), + ThreadLocalRandom.current().nextDouble(-3, 3), 0, - ThreadLocalRandom.current().nextDouble(-3,3) + ThreadLocalRandom.current().nextDouble(-3, 3) ); SpellUtils.summonTemporaryMob( EntityType.VEX, diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AntiPrism.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AntiPrism.java index 0178951b..36d56908 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AntiPrism.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/AntiPrism.java @@ -1,6 +1,5 @@ package io.github.sefiraat.crystamaehistoria.magic.spells.tier1; -import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; import io.github.sefiraat.crystamaehistoria.magic.CastInformation; import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicProjectile; import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; @@ -13,10 +12,8 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; -import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Break.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Break.java index f7dfd635..e468c6d9 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Break.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Break.java @@ -5,8 +5,6 @@ import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; -import io.github.thebusybiscuit.slimefun4.libraries.dough.protection.Interaction; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -25,11 +23,9 @@ public Break() { @ParametersAreNonnullByDefault public void cast(CastInformation castInformation) { - Player caster = Bukkit.getPlayer(castInformation.getCaster()); - Block block = caster.getTargetBlockExact((int) getRange(castInformation)); - if (hasPermission(caster, block.getLocation(), Interaction.BREAK_BLOCK)) { - block.breakNaturally(caster.getInventory().getItemInMainHand()); - } + Player player = castInformation.getCasterAsPlayer(); + Block block = player.getTargetBlockExact((int) getRange(castInformation)); + tryBreakBlock(castInformation.getCaster(), block); } @Nonnull diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Chaos.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Chaos.java index 290a72ff..7b0d6d7f 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Chaos.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Chaos.java @@ -5,10 +5,8 @@ import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.MagicalPlate; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; import io.github.sefiraat.crystamaehistoria.utils.SpellUtils; -import io.github.thebusybiscuit.slimefun4.libraries.dough.protection.Interaction; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -74,9 +72,7 @@ public void onHitEntity(CastInformation castInformation) { } public void onHitBlock(CastInformation castInformation) { - if (hasPermission(castInformation.getCaster(), castInformation.getHitBlock(), Interaction.BREAK_BLOCK)) { - castInformation.getHitBlock().breakNaturally(); - } + tryBreakBlock(castInformation.getCaster(), castInformation.getHitBlock()); } @Nonnull diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Compass.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Compass.java new file mode 100644 index 00000000..d14ba579 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Compass.java @@ -0,0 +1,100 @@ +package io.github.sefiraat.crystamaehistoria.magic.spells.tier1; + +import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; +import io.github.sefiraat.crystamaehistoria.magic.CastInformation; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; +import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; +import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; +import io.github.sefiraat.crystamaehistoria.utils.ParticleUtils; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.List; + +public class Compass extends Spell { + + public Compass() { + SpellCoreBuilder spellCoreBuilder = new SpellCoreBuilder(10, false, 20, true, 50, true) + .makeTickingSpell(this::onTick, 10, true, 20, false); + setSpellCore(spellCoreBuilder.build()); + } + + @ParametersAreNonnullByDefault + public void onTick(CastInformation castInformation) { + final Player player = castInformation.getCasterAsPlayer(); + final Location location = player.getLocation().add(0, 1.5, 0); + final ItemStack itemStack = player.getInventory().getItemInOffHand(); + final Material material = itemStack.getType(); + if (material != Material.AIR && material.isBlock()) { + final Block foundBlock = tryGetBlock(player, material, (int) getRange(castInformation)); + if (foundBlock == null) { + displayParticleEffect(location.add(location.getDirection()), Particle.VILLAGER_ANGRY, 1, 10); + } else { + final Location foundBlockLocation = foundBlock.getLocation().add(0.5, 0.5, 0.5); + final List list = (List) CrystamaeHistoria.getConfigManager().getBlockColors().getList(material.name()); + final Color color = Color.fromRGB(list.get(0), list.get(1), list.get(2)); + final Particle.DustOptions dustOptionsToBlock = new Particle.DustOptions(color, 1); + ParticleUtils.drawLine(dustOptionsToBlock, location, foundBlockLocation, 0.2); + } + } + } + + @Nullable + public Block tryGetBlock(Player player, Material material, int range) { + final Location location = player.getLocation(); + for (int x = -range; x < range; x++) { + for (int y = -range; y < range; y++) { + for (int z = -range; z < range; z++) { + Block block = location.clone().add(x, y, z).getBlock(); + if (block.getType() == material) { + return block; + } + } + } + } + return null; + } + + @Nonnull + @Override + public String getId() { + return "COMPASS"; + } + + @Nonnull + @Override + public String[] getLore() { + return new String[]{ + "Tap into the ether to find blocks.", + "Will locate blocks matching the one", + "in the caster's off-hand." + }; + } + + @Nonnull + @Override + public Material getMaterial() { + return Material.COMPASS; + } + + @NotNull + @Override + public SpellRecipe getRecipe() { + return new SpellRecipe( + 1, + StoryType.MECHANICAL, + StoryType.ALCHEMICAL, + StoryType.HUMAN + ); + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Deity.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Deity.java index 9a1f300b..b0987610 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Deity.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Deity.java @@ -7,11 +7,9 @@ import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; import io.github.sefiraat.crystamaehistoria.utils.SpellUtils; -import io.github.sefiraat.crystamaehistoria.utils.mobgoals.BoringGoal; import io.github.sefiraat.crystamaehistoria.utils.mobgoals.DeityGoal; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.Particle; import org.bukkit.entity.EntityType; import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; @@ -35,9 +33,9 @@ public void cast(CastInformation castInformation) { final UUID caster = castInformation.getCaster(); final Location location = castInformation.getCastLocation(); final Location spawnLocation = location.clone().add( - ThreadLocalRandom.current().nextDouble(-3,3), + ThreadLocalRandom.current().nextDouble(-3, 3), 0, - ThreadLocalRandom.current().nextDouble(-3,3) + ThreadLocalRandom.current().nextDouble(-3, 3) ); final MagicSummon magicSummon = SpellUtils.summonTemporaryMob( EntityType.GIANT, diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Fireball.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Fireball.java index cc5ea2ca..bed216f5 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Fireball.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Fireball.java @@ -19,18 +19,18 @@ public class Fireball extends Spell { public Fireball() { - SpellCoreBuilder spellCoreBuilder = new SpellCoreBuilder(1, true, 0, false, 1, true) + SpellCoreBuilder spellCoreBuilder = new SpellCoreBuilder(0.5, false, 0, false, 1, true) + .makeDamagingSpell(1, true, 0.5, false) .makeProjectileSpell(this::fireProjectile, 1, false, 1, false) .makeProjectileVsEntitySpell(this::projectileHit) - .addBeforeProjectileHitEntityEvent(this::beforeProjectileHit) - .makeDamagingSpell(2, true, 0.5, false); + .addBeforeProjectileHitEntityEvent(this::beforeProjectileHit); setSpellCore(spellCoreBuilder.build()); } @ParametersAreNonnullByDefault public void fireProjectile(CastInformation castInformation) { Location location = castInformation.getCastLocation(); - Location aimLocation = location.clone().add(0, 1.5, 0).add(location.getDirection().multiply(2)); + Location aimLocation = location.clone().add(0, 1.5, 0).add(location.getDirection().multiply(1)); MagicProjectile magicProjectile = SpellUtils.summonMagicProjectile(castInformation, EntityType.SMALL_FIREBALL, aimLocation); magicProjectile.setVelocity(location.getDirection(), 1.5); } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/FlameSprite.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/FlameSprite.java index 73c426f8..f24b412f 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/FlameSprite.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/FlameSprite.java @@ -33,9 +33,9 @@ public void cast(CastInformation castInformation) { Location location = castInformation.getCastLocation(); for (int i = 0; i < castInformation.getStaveLevel(); i++) { Location spawnLocation = location.clone().add( - ThreadLocalRandom.current().nextDouble(-3,3), + ThreadLocalRandom.current().nextDouble(-3, 3), 0, - ThreadLocalRandom.current().nextDouble(-3,3) + ThreadLocalRandom.current().nextDouble(-3, 3) ); SpellUtils.summonTemporaryMob( EntityType.BLAZE, diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Gravity.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Gravity.java new file mode 100644 index 00000000..3be884ab --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Gravity.java @@ -0,0 +1,78 @@ +package io.github.sefiraat.crystamaehistoria.magic.spells.tier1; + +import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; +import io.github.sefiraat.crystamaehistoria.magic.CastInformation; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; +import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; +import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +public class Gravity extends Spell { + + public Gravity() { + SpellCoreBuilder spellCoreBuilder = new SpellCoreBuilder(300, true, 0, false, 50, false) + .makeTickingSpell(this::tick, 1, false, 20, false) + .addAfterTicksEvent(this::afterAllTicks); + setSpellCore(spellCoreBuilder.build()); + } + + @ParametersAreNonnullByDefault + public void tick(CastInformation castInformation) { + Player player = castInformation.getCasterAsPlayer(); + player.setVelocity(player.getLocation().getDirection().add(new Vector(0, 5, 0))); + displayParticleEffect(player, Particle.GLOW_SQUID_INK, 2, 10); + } + + @ParametersAreNonnullByDefault + public void afterAllTicks(CastInformation castInformation) { + Player player = castInformation.getCasterAsPlayer(); + player.setAllowFlight(true); + player.setFlying(true); + long expiry = System.currentTimeMillis() + ((castInformation.getStaveLevel() * 30L) * 1000); + CrystamaeHistoria.getActiveStorage().getPlayersWithFlight().put(player.getUniqueId(), expiry); + displayParticleEffect(player, Particle.FALLING_OBSIDIAN_TEAR, 2, 20); + } + + @Nonnull + @Override + public String getId() { + return "GRAVITY"; + } + + @Nonnull + @Override + public String[] getLore() { + return new String[]{ + "Allows you to use a temporary gravity", + "pocket to fly." + }; + } + + @Nonnull + @Override + public Material getMaterial() { + return Material.FIREWORK_STAR; + } + + @NotNull + @Override + public SpellRecipe getRecipe() { + return new SpellRecipe( + 1, + StoryType.MECHANICAL, + StoryType.ALCHEMICAL, + StoryType.CELESTIAL + ); + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Gyroscopic.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Gyroscopic.java index c06f17d7..7f6c41c1 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Gyroscopic.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Gyroscopic.java @@ -5,15 +5,12 @@ import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; -import io.github.sefiraat.crystamaehistoria.utils.Keys; -import io.github.thebusybiscuit.slimefun4.libraries.dough.data.persistent.PersistentDataAPI; import io.github.thebusybiscuit.slimefun4.libraries.dough.protection.Interaction; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Mob; import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/HarmonysSonata.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/HarmonysSonata.java index 5e842280..22d26847 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/HarmonysSonata.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/HarmonysSonata.java @@ -7,9 +7,9 @@ import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; import io.github.thebusybiscuit.slimefun4.libraries.dough.protection.Interaction; import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag; -import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Particle; import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -49,7 +49,7 @@ && hasPermission(castInformation.getCaster(), block, Interaction.PLACE_BLOCK) .findAny() .orElse(Material.DANDELION); if (Tag.TALL_FLOWERS.isTagged(material)) { - final Block upper = block.getRelative(BlockFace.UP); + final Block upper = block.getRelative(BlockFace.UP); if (upper.getType() == Material.AIR) { block.setType(material, false); upper.setType(material, false); @@ -66,6 +66,7 @@ && hasPermission(castInformation.getCaster(), block, Interaction.PLACE_BLOCK) block.setType(material); } block.getRelative(BlockFace.DOWN).setType(Material.GRASS_BLOCK); + displayParticleEffect(block.getLocation(), Particle.FIREWORKS_SPARK, 0.5, 3); } } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Hearthstone.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Hearthstone.java new file mode 100644 index 00000000..6244f1d9 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Hearthstone.java @@ -0,0 +1,89 @@ +package io.github.sefiraat.crystamaehistoria.magic.spells.tier1; + +import io.github.sefiraat.crystamaehistoria.magic.CastInformation; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicProjectile; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; +import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; +import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; +import io.github.sefiraat.crystamaehistoria.utils.SpellUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +public class Hearthstone extends Spell { + + public Hearthstone() { + SpellCoreBuilder spellCoreBuilder = new SpellCoreBuilder(300, true, 0, false, 50, false) + .makeTickingSpell(this::tick, 10, false, 10, false) + .addAfterTicksEvent(this::afterAllTicks); + setSpellCore(spellCoreBuilder.build()); + } + + @ParametersAreNonnullByDefault + public void tick(CastInformation castInformation) { + int sizeCast = 2; + int stepSize = 3; + Location middle = castInformation.getCasterAsPlayer().getLocation().add(0, 1, 0); + for (double i = 0; i < 360; i += stepSize) { + double angle = (i * Math.PI / 180); + int sx = (int) (sizeCast * Math.cos(angle)); + int sz = (int) (sizeCast * Math.sin(angle)); + Location spawn = middle.clone().add(sx, 0, sz); + displayParticleEffect(spawn, Particle.DRIPPING_HONEY, 0.1, 1); + } + } + + @ParametersAreNonnullByDefault + public void afterAllTicks(CastInformation castInformation) { + Player caster = Bukkit.getPlayer(castInformation.getCaster()); + Location location = caster.getBedSpawnLocation(); + if (location == null) { + Location casterLocation = caster.getLocation(); + displayParticleEffect(casterLocation.add(casterLocation.getDirection()), Particle.VILLAGER_ANGRY, 1, 10); + } else { + caster.teleportAsync(location, PlayerTeleportEvent.TeleportCause.PLUGIN); + } + } + + @Nonnull + @Override + public String getId() { + return "HEARTHSTONE"; + } + + @Nonnull + @Override + public String[] getLore() { + return new String[]{ + "Sends you back to your last bed if", + "possible. Takes time to cast, movement", + "stops the cast." + }; + } + + @Nonnull + @Override + public Material getMaterial() { + return Material.RED_BED; + } + + @NotNull + @Override + public SpellRecipe getRecipe() { + return new SpellRecipe( + 1, + StoryType.MECHANICAL, + StoryType.HUMAN, + StoryType.PHILOSOPHICAL + ); + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/HolyCow.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/HolyCow.java index cb5952f0..85ed2a9e 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/HolyCow.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/HolyCow.java @@ -33,9 +33,9 @@ public void cast(CastInformation castInformation) { Location location = castInformation.getCastLocation(); for (int i = 0; i < castInformation.getStaveLevel(); i++) { Location spawnLocation = location.clone().add( - ThreadLocalRandom.current().nextDouble(-3,3), + ThreadLocalRandom.current().nextDouble(-3, 3), 0, - ThreadLocalRandom.current().nextDouble(-3,3) + ThreadLocalRandom.current().nextDouble(-3, 3) ); SpellUtils.summonTemporaryMob( EntityType.COW, diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/LeechBomb.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/LeechBomb.java index be14606a..081e0777 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/LeechBomb.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/LeechBomb.java @@ -8,7 +8,6 @@ import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; import io.github.sefiraat.crystamaehistoria.utils.SpellUtils; -import io.github.sefiraat.crystamaehistoria.utils.mobgoals.FiendGoal; import io.github.sefiraat.crystamaehistoria.utils.mobgoals.LeechGoal; import org.bukkit.Location; import org.bukkit.Material; diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/PhantomsFlight.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/PhantomsFlight.java new file mode 100644 index 00000000..476c9989 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/PhantomsFlight.java @@ -0,0 +1,93 @@ +package io.github.sefiraat.crystamaehistoria.magic.spells.tier1; + +import io.github.sefiraat.crystamaehistoria.magic.CastInformation; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicSummon; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; +import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; +import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; +import io.github.sefiraat.crystamaehistoria.utils.SpellUtils; +import io.github.sefiraat.crystamaehistoria.utils.mobgoals.FlyingPhantomGoal; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.entity.Bat; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Phantom; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +// TODO UNUSED +public class PhantomsFlight extends Spell { + + public PhantomsFlight() { + SpellCoreBuilder spellCoreBuilder = new SpellCoreBuilder(5, true, 0, false, 50, true) + .makeInstantSpell(this::cast); + setSpellCore(spellCoreBuilder.build()); + } + + @ParametersAreNonnullByDefault + public void cast(CastInformation castInformation) { + final UUID caster = castInformation.getCaster(); + final Location location = castInformation.getCastLocation(); + final Location spawnLocation = location.clone().add( + ThreadLocalRandom.current().nextDouble(-3, 3), + 0, + ThreadLocalRandom.current().nextDouble(-3, 3) + ); + final MagicSummon magicSummon = SpellUtils.summonTemporaryMob( + EntityType.BAT, + caster, + spawnLocation, + new FlyingPhantomGoal(caster), + castInformation.getStaveLevel() * 300, + this::onTick + ); + Bat bat = (Bat) magicSummon.getMob(); + bat.setInvisible(true); + bat.setInvulnerable(true); + bat.addPassenger(castInformation.getCasterAsPlayer()); + } + + public void onTick(MagicSummon magicSummon) { + displayParticleEffect(magicSummon.getMob(), Particle.SPORE_BLOSSOM_AIR, 1, 2); + } + + @Nonnull + @Override + public String getId() { + return "PHANTOMS_FLIGHT"; + } + + @Nonnull + @Override + public String[] getLore() { + return new String[]{ + "Summons a dragon to ride.", + "Getting off the dragon will make", + "it fly away." + }; + } + + @Nonnull + @Override + public Material getMaterial() { + return Material.DRAGON_EGG; + } + + @NotNull + @Override + public SpellRecipe getRecipe() { + return new SpellRecipe( + 1, + StoryType.ANIMAL, + StoryType.CELESTIAL, + StoryType.PHILOSOPHICAL + ); + } + +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Ravage.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Ravage.java index 87fcd486..6695185e 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Ravage.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Ravage.java @@ -7,7 +7,7 @@ import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; import io.github.sefiraat.crystamaehistoria.utils.SpellUtils; -import io.github.sefiraat.crystamaehistoria.utils.mobgoals.BoringGoal; +import io.github.sefiraat.crystamaehistoria.utils.mobgoals.RidableGroundGoal; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; @@ -22,6 +22,8 @@ public class Ravage extends Spell { + // TODO Riding ravagers removed until Paper patches + public Ravage() { SpellCoreBuilder spellCoreBuilder = new SpellCoreBuilder(5, true, 0, false, 50, true) .makeInstantSpell(this::cast) @@ -37,15 +39,15 @@ public void cast(CastInformation castInformation) { final UUID caster = castInformation.getCaster(); final Location location = castInformation.getCastLocation(); final Location spawnLocation = location.clone().add( - ThreadLocalRandom.current().nextDouble(-3,3), + ThreadLocalRandom.current().nextDouble(-3, 3), 0, - ThreadLocalRandom.current().nextDouble(-3,3) + ThreadLocalRandom.current().nextDouble(-3, 3) ); final MagicSummon magicSummon = SpellUtils.summonTemporaryMob( EntityType.RAVAGER, caster, spawnLocation, - new BoringGoal(caster), + new RidableGroundGoal(caster), 300, this::onTick ); diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/RemnantOfWar.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/RemnantOfWar.java index 34f6d59c..6ea998a2 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/RemnantOfWar.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/RemnantOfWar.java @@ -35,9 +35,9 @@ public void cast(CastInformation castInformation) { UUID caster = castInformation.getCaster(); Location location = castInformation.getCastLocation(); Location spawnLocation = location.clone().add( - ThreadLocalRandom.current().nextDouble(-3,3), + ThreadLocalRandom.current().nextDouble(-3, 3), 0, - ThreadLocalRandom.current().nextDouble(-3,3) + ThreadLocalRandom.current().nextDouble(-3, 3) ); MagicSummon magicSummon = SpellUtils.summonTemporaryMob( EntityType.ZOMBIE, diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/SpawnFiends.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/SpawnFiends.java index fce3ff72..61650dda 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/SpawnFiends.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/SpawnFiends.java @@ -32,9 +32,9 @@ public void cast(CastInformation castInformation) { Location location = castInformation.getCastLocation(); for (int i = 0; i < castInformation.getStaveLevel(); i++) { Location spawnLocation = location.clone().add( - ThreadLocalRandom.current().nextDouble(-3,3), + ThreadLocalRandom.current().nextDouble(-3, 3), 0, - ThreadLocalRandom.current().nextDouble(-3,3) + ThreadLocalRandom.current().nextDouble(-3, 3) ); Phantom phantom = (Phantom) SpellUtils.summonTemporaryMob( EntityType.PHANTOM, diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Tracer.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Tracer.java new file mode 100644 index 00000000..5dfb0011 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/Tracer.java @@ -0,0 +1,122 @@ +package io.github.sefiraat.crystamaehistoria.magic.spells.tier1; + +import io.github.sefiraat.crystamaehistoria.magic.CastInformation; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; +import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; +import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; +import io.github.sefiraat.crystamaehistoria.utils.ParticleUtils; +import org.apache.commons.lang.Validate; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.entity.Ambient; +import org.bukkit.entity.Animals; +import org.bukkit.entity.Boss; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Monster; +import org.bukkit.entity.NPC; +import org.bukkit.entity.Player; +import org.bukkit.entity.WaterMob; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +public class Tracer extends Spell { + + public static final Map COLOR_MAP = new LinkedHashMap<>(); + + static { + COLOR_MAP.put("player", Color.fromRGB(255, 255, 255)); + COLOR_MAP.put("npc", Color.fromRGB(240, 180, 40)); + COLOR_MAP.put("boss", Color.fromRGB(255, 25, 30)); + COLOR_MAP.put("monster", Color.fromRGB(190, 25, 30)); + COLOR_MAP.put("water", Color.fromRGB(45, 45, 220)); + COLOR_MAP.put("animal", Color.fromRGB(50, 230, 30)); + COLOR_MAP.put("ambient", Color.fromRGB(150, 150, 150)); + } + + public Tracer() { + SpellCoreBuilder spellCoreBuilder = new SpellCoreBuilder(10, false, 40, true, 10, true) + .makeTickingSpell(this::onTick, 10, true, 20, false); + setSpellCore(spellCoreBuilder.build()); + } + + @ParametersAreNonnullByDefault + public void onTick(CastInformation castInformation) { + final Player player = castInformation.getCasterAsPlayer(); + final Location location = player.getLocation().add(0, 1.5, 0); + final Collection entityList = location.getNearbyLivingEntities(getRange(castInformation)); + for (LivingEntity livingEntity : entityList) { + if (livingEntity.getUniqueId() == castInformation.getCaster()) { + continue; + } + + Particle.DustOptions dustOptions = null; + if (livingEntity instanceof Player) { + dustOptions = new Particle.DustOptions(COLOR_MAP.get("player"), 1); + } else if (livingEntity instanceof NPC) { + dustOptions = new Particle.DustOptions(COLOR_MAP.get("npc"), 1); + } else if (livingEntity instanceof Boss) { + dustOptions = new Particle.DustOptions(COLOR_MAP.get("boss"), 1); + } else if (livingEntity instanceof Monster) { + dustOptions = new Particle.DustOptions(COLOR_MAP.get("monster"), 1); + } else if (livingEntity instanceof WaterMob) { + dustOptions = new Particle.DustOptions(COLOR_MAP.get("water"), 1); + } else if (livingEntity instanceof Animals) { + dustOptions = new Particle.DustOptions(COLOR_MAP.get("animal"), 1); + } else if (livingEntity instanceof Ambient) { + dustOptions = new Particle.DustOptions(COLOR_MAP.get("ambient"), 1); + } + + Validate.notNull( + dustOptions, + "Dust Options is null, something be bad: " + livingEntity.getType().name() + ); + + ParticleUtils.drawLine( + dustOptions, + location, + livingEntity.getLocation(), + 0.2 + ); + } + } + + @Nonnull + @Override + public String getId() { + return "TRACER"; + } + + @Nonnull + @Override + public String[] getLore() { + return new String[]{ + "Shows you all nearby living things", + "color coded by type." + }; + } + + @Nonnull + @Override + public Material getMaterial() { + return Material.LEAD; + } + + @NotNull + @Override + public SpellRecipe getRecipe() { + return new SpellRecipe( + 1, + StoryType.MECHANICAL, + StoryType.HISTORICAL, + StoryType.ANIMAL + ); + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/WitherWeather.java b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/WitherWeather.java index 14fa3e59..66316ae6 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/WitherWeather.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/magic/spells/tier1/WitherWeather.java @@ -1,7 +1,6 @@ package io.github.sefiraat.crystamaehistoria.magic.spells.tier1; import io.github.sefiraat.crystamaehistoria.magic.CastInformation; -import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicProjectile; import io.github.sefiraat.crystamaehistoria.magic.spells.core.Spell; import io.github.sefiraat.crystamaehistoria.magic.spells.core.SpellCoreBuilder; import io.github.sefiraat.crystamaehistoria.slimefun.machines.liquefactionbasin.SpellRecipe; diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/RunnableManager.java b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/RunnableManager.java index f432fc25..00efd94c 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/RunnableManager.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/RunnableManager.java @@ -1,30 +1,18 @@ package io.github.sefiraat.crystamaehistoria.runnables; import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; -import io.github.sefiraat.crystamaehistoria.runnables.spells.SummonedEntityTick; -import io.github.sefiraat.crystamaehistoria.runnables.spells.TemporaryBlocksTick; -import io.github.sefiraat.crystamaehistoria.runnables.spells.ProjectileTick; +import io.github.sefiraat.crystamaehistoria.runnables.spells.TemporaryEffectsRunnable; import lombok.Getter; public class RunnableManager { @Getter - public final TemporaryBlocksTick temporaryBlocksTick; - @Getter - public final ProjectileTick projectileTick; - @Getter - public final SummonedEntityTick summonedEntityTick; + public final TemporaryEffectsRunnable temporaryEffectsRunnable; public RunnableManager() { CrystamaeHistoria plugin = CrystamaeHistoria.getInstance(); - this.temporaryBlocksTick = new TemporaryBlocksTick(); - this.temporaryBlocksTick.runTaskTimer(plugin, 1, 20); - - this.projectileTick = new ProjectileTick(); - this.projectileTick.runTaskTimer(plugin, 1, 2); - - this.summonedEntityTick = new SummonedEntityTick(); - this.summonedEntityTick.runTaskTimer(plugin, 1, 20); + this.temporaryEffectsRunnable = new TemporaryEffectsRunnable(); + this.temporaryEffectsRunnable.runTaskTimer(plugin, 1, 20); } } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/ProjectileTick.java b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/ProjectileTick.java deleted file mode 100644 index 907bfa9e..00000000 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/ProjectileTick.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.github.sefiraat.crystamaehistoria.runnables.spells; - -import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; -import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicProjectile; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.HashSet; -import java.util.Set; - -public class ProjectileTick extends BukkitRunnable { - - @Override - public void run() { - Set set = new HashSet<>(CrystamaeHistoria.getProjectileMap().keySet()); - for (MagicProjectile magicProjectile : set) { - long expiry = CrystamaeHistoria.getProjectileMap().get(magicProjectile).getSecondValue(); - if (System.currentTimeMillis() > expiry) { - magicProjectile.kill(); - } else { - magicProjectile.run(); - } - } - } -} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SpellTick.java b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SpellTickRunnable.java similarity index 87% rename from src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SpellTick.java rename to src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SpellTickRunnable.java index 8bdcf7ea..794217d1 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SpellTick.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SpellTickRunnable.java @@ -6,13 +6,13 @@ import javax.annotation.ParametersAreNonnullByDefault; -public class SpellTick extends BukkitRunnable { +public class SpellTickRunnable extends BukkitRunnable { private final CastInformation castInformation; private int numberOfRuns; @ParametersAreNonnullByDefault - public SpellTick(CastInformation castInformation, int numberOfRuns) { + public SpellTickRunnable(CastInformation castInformation, int numberOfRuns) { this.castInformation = castInformation; this.numberOfRuns = numberOfRuns; } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SummonedEntityTick.java b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SummonedEntityTick.java deleted file mode 100644 index d22ff6bd..00000000 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/SummonedEntityTick.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.github.sefiraat.crystamaehistoria.runnables.spells; - -import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; -import io.github.sefiraat.crystamaehistoria.magic.spells.core.MagicSummon; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.HashSet; -import java.util.Set; - -public class SummonedEntityTick extends BukkitRunnable { - - @Override - public void run() { - Set set = new HashSet<>(CrystamaeHistoria.getSummonedEntityMap().keySet()); - for (MagicSummon magicSummon : set) { - long expiry = CrystamaeHistoria.getSummonedEntityMap().get(magicSummon); - if (System.currentTimeMillis() > expiry || magicSummon.getMob() == null) { - magicSummon.kill(); - } else { - magicSummon.run(); - } - } - } -} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/TemporaryBlocksTick.java b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/TemporaryBlocksTick.java deleted file mode 100644 index 381e0387..00000000 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/TemporaryBlocksTick.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.sefiraat.crystamaehistoria.runnables.spells; - -import io.github.sefiraat.crystamaehistoria.ActiveStorage; -import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; -import org.bukkit.scheduler.BukkitRunnable; - -public class TemporaryBlocksTick extends BukkitRunnable { - - @Override - public void run() { - ActiveStorage storage = CrystamaeHistoria.getActiveStorage(); - storage.removeBlocks(false); - } -} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/TemporaryEffectsRunnable.java b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/TemporaryEffectsRunnable.java new file mode 100644 index 00000000..a37cf0e6 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/runnables/spells/TemporaryEffectsRunnable.java @@ -0,0 +1,34 @@ +package io.github.sefiraat.crystamaehistoria.runnables.spells; + +import io.github.sefiraat.crystamaehistoria.SpellMemory; +import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; +import org.bukkit.scheduler.BukkitRunnable; + +public class TemporaryEffectsRunnable extends BukkitRunnable { + + @Override + public void run() { + final SpellMemory storage = CrystamaeHistoria.getActiveStorage(); + + clearExpiredProjectiles(storage); + clearMagicSummons(storage); + clearTempBlocks(storage); + removeTempFlight(storage); + } + + public void clearMagicSummons(SpellMemory storage) { + storage.removeEntities(false); + } + + public void clearTempBlocks(SpellMemory storage) { + storage.removeBlocks(false); + } + + public void clearExpiredProjectiles(SpellMemory storage) { + storage.removeProjectiles(false); + } + + public void removeTempFlight(SpellMemory storage) { + storage.removeFlight(false); + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/liquefactionbasin/LiquefactionBasin.java b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/liquefactionbasin/LiquefactionBasin.java index 35c1d3da..d6f902ff 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/liquefactionbasin/LiquefactionBasin.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/liquefactionbasin/LiquefactionBasin.java @@ -11,6 +11,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.HumanEntity; import org.bukkit.event.block.BlockBreakEvent; @@ -55,6 +56,9 @@ protected void tick(Block block, BlockMenu blockMenu) { cache.consumeItems(); cache.syncBlock(); } + if (block.getType() != Material.CAULDRON) { + block.setType(Material.CAULDRON); + } } @Override diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/liquefactionbasin/LiquefactionBasinCache.java b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/liquefactionbasin/LiquefactionBasinCache.java index 50bf6f71..9273e9a7 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/liquefactionbasin/LiquefactionBasinCache.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/liquefactionbasin/LiquefactionBasinCache.java @@ -3,12 +3,12 @@ import de.slikey.effectlib.effect.SphereEffect; import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; import io.github.sefiraat.crystamaehistoria.magic.SpellType; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.InstancePlate; import io.github.sefiraat.crystamaehistoria.slimefun.machines.DisplayStandHolder; import io.github.sefiraat.crystamaehistoria.slimefun.materials.Crystal; import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.BlankPlate; import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.ChargedPlate; import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.MagicalPlate; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.PlateStorage; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryRarity; import io.github.sefiraat.crystamaehistoria.stories.definition.StoryType; import io.github.sefiraat.crystamaehistoria.utils.ArmourStandUtils; @@ -239,9 +239,9 @@ private void processBlankPlate(Item item, BlankPlate plate) { private void processChargedPlate(Item item, ChargedPlate plate) { final ItemStack itemStack = item.getItemStack(); final ItemMeta itemMeta = itemStack.getItemMeta(); - final PlateStorage plateStorage = DataTypeMethods.getCustom(itemMeta, Keys.PDC_PLATE_STORAGE, PersistentPlateDataType.TYPE); + final InstancePlate instancePlate = DataTypeMethods.getCustom(itemMeta, Keys.PDC_PLATE_STORAGE, PersistentPlateDataType.TYPE); - if (plateStorage == null) { + if (instancePlate == null) { CrystamaeHistoria.log( Level.SEVERE, "The charged plate used has not been configured correctly. /sf cheat charged plates will not" + @@ -251,7 +251,7 @@ private void processChargedPlate(Item item, ChargedPlate plate) { return; } - final SpellType currentSpellType = plateStorage.getStoredSpell(); + final SpellType currentSpellType = instancePlate.getStoredSpell(); final Set set = contentMap.entrySet().stream() .sorted(Map.Entry.comparingByValue().reversed()) .limit(3) @@ -261,10 +261,10 @@ private void processChargedPlate(Item item, ChargedPlate plate) { if (set.size() == 3) { SpellType spellType = getMatchingRecipe(set, plate); if (spellType != null && spellType == currentSpellType) { - plateStorage.addCrysta(getFillLevel()); - DataTypeMethods.setCustom(itemMeta, Keys.PDC_PLATE_STORAGE, PersistentPlateDataType.TYPE, plateStorage); + instancePlate.addCrysta(getFillLevel()); + DataTypeMethods.setCustom(itemMeta, Keys.PDC_PLATE_STORAGE, PersistentPlateDataType.TYPE, instancePlate); itemStack.setItemMeta(itemMeta); - PlateStorage.setPlateLore(itemStack, plateStorage); + InstancePlate.setPlateLore(itemStack, instancePlate); summonCatalystParticles(); } emptyBasin(); diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/realisationaltar/RealisationAltar.java b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/realisationaltar/RealisationAltar.java index 6b136882..05ba6c5b 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/realisationaltar/RealisationAltar.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/realisationaltar/RealisationAltar.java @@ -33,6 +33,10 @@ public RealisationAltar(ItemGroup itemGroup, SlimefunItemStack item, RecipeType super(itemGroup, item, recipeType, recipe); } + public static Map getCaches() { + return CACHE_MAP; + } + @Override @ParametersAreNonnullByDefault protected void tick(Block block, BlockMenu blockMenu) { diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/staveconfigurator/StaveConfigurator.java b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/staveconfigurator/StaveConfigurator.java index 66536b8d..c6a9c32a 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/staveconfigurator/StaveConfigurator.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/machines/staveconfigurator/StaveConfigurator.java @@ -1,11 +1,11 @@ package io.github.sefiraat.crystamaehistoria.slimefun.machines.staveconfigurator; import io.github.mooy1.infinitylib.machines.MenuBlock; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.InstancePlate; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.InstanceStave; import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.ChargedPlate; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.PlateStorage; import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.SpellSlot; import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.Stave; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.StaveStorage; import io.github.sefiraat.crystamaehistoria.utils.Keys; import io.github.sefiraat.crystamaehistoria.utils.datatypes.DataTypeMethods; import io.github.sefiraat.crystamaehistoria.utils.datatypes.PersistentPlateDataType; @@ -82,26 +82,26 @@ protected void onNewInstance(@Nonnull BlockMenu blockMenu, @Nonnull Block b) { final ItemStack stave = blockMenu.getItemInSlot(STAVE_SLOT); final SlimefunItem sfStave = SlimefunItem.getByItem(stave); if (stave != null && sfStave instanceof Stave) { - final StaveStorage staveStorage = new StaveStorage(stave); - final Map map = staveStorage.getSpellInstanceMap(); + final InstanceStave staveInstance = new InstanceStave(stave); + final Map map = staveInstance.getSpellInstanceMap(); if (map != null) { - for (Map.Entry entry : map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { final SpellSlot spellSlot = entry.getKey(); - final PlateStorage plateStorage = map.get(spellSlot); - final ItemStack plate = ChargedPlate.getChargedPlate(plateStorage); + final InstancePlate instancePlate = map.get(spellSlot); + final ItemStack plate = ChargedPlate.getChargedPlate(instancePlate); blockMenu.replaceExistingItem(getSlot(spellSlot), plate); } } - staveStorage.getSpellInstanceMap().clear(); + staveInstance.getSpellInstanceMap().clear(); ItemMeta itemMeta = stave.getItemMeta(); DataTypeMethods.setCustom( itemMeta, Keys.PDC_STAVE_STORAGE, PersistentStaveDataType.TYPE, - staveStorage.getSpellInstanceMap() + staveInstance.getSpellInstanceMap() ); stave.setItemMeta(itemMeta); - StaveStorage.setStaveLore(stave, staveStorage); + staveInstance.buildLore(); } return false; }); @@ -109,7 +109,7 @@ protected void onNewInstance(@Nonnull BlockMenu blockMenu, @Nonnull Block b) { blockMenu.addMenuClickHandler(ADD_PLATES, (player, i, itemStack, clickAction) -> { final ItemStack stave = blockMenu.getItemInSlot(STAVE_SLOT); final SlimefunItem sfStave = SlimefunItem.getByItem(stave); - StaveStorage staveStorage = new StaveStorage(); + InstanceStave staveInstance = new InstanceStave(itemStack); if (stave != null && sfStave instanceof Stave && !platesEmpty(blockMenu) @@ -120,22 +120,22 @@ && staveIsEmpty(stave) for (SpellSlot spellSlot : SpellSlot.getCashedValues()) { ItemStack plate = blockMenu.getItemInSlot(getSlot(spellSlot)); if (plate != null && SlimefunItem.getByItem(plate) instanceof ChargedPlate) { - PlateStorage plateStorage = DataTypeMethods.getCustom( + InstancePlate instancePlate = DataTypeMethods.getCustom( plate.getItemMeta(), Keys.PDC_PLATE_STORAGE, PersistentPlateDataType.TYPE ); - staveStorage.setSlot(spellSlot, plateStorage); + staveInstance.setSlot(spellSlot, instancePlate); } } DataTypeMethods.setCustom( itemMeta, Keys.PDC_STAVE_STORAGE, PersistentStaveDataType.TYPE, - staveStorage.getSpellInstanceMap() + staveInstance.getSpellInstanceMap() ); stave.setItemMeta(itemMeta); - StaveStorage.setStaveLore(stave, staveStorage); + staveInstance.buildLore(); clearPlates(blockMenu); } return false; @@ -192,8 +192,8 @@ private boolean platesEmpty(@Nonnull BlockMenu blockMenu) { } private boolean staveIsEmpty(ItemStack stave) { - final StaveStorage staveStorage = new StaveStorage(stave); - return staveStorage.getSpellInstanceMap().size() == 0; + final InstanceStave instanceStave = new InstanceStave(stave); + return instanceStave.getSpellInstanceMap().size() == 0; } private int getSlot(@Nonnull SpellSlot spellSlot) { diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/plates/ChargedPlate.java b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/plates/ChargedPlate.java index bca2d4a2..7d9c4cdb 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/plates/ChargedPlate.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/slimefun/tools/plates/ChargedPlate.java @@ -1,6 +1,7 @@ package io.github.sefiraat.crystamaehistoria.slimefun.tools.plates; import io.github.sefiraat.crystamaehistoria.magic.SpellType; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.InstancePlate; import io.github.sefiraat.crystamaehistoria.slimefun.Materials; import io.github.sefiraat.crystamaehistoria.utils.Keys; import io.github.sefiraat.crystamaehistoria.utils.datatypes.DataTypeMethods; @@ -26,21 +27,21 @@ public ChargedPlate(ItemGroup itemGroup, SlimefunItemStack item, RecipeType reci @Nonnull @ParametersAreNonnullByDefault public static ItemStack getChargedPlate(int tier, SpellType spellType, int crysta) { - PlateStorage plateStorage = new PlateStorage(tier, spellType, crysta); - return getChargedPlate(plateStorage); + InstancePlate instancePlate = new InstancePlate(tier, spellType, crysta); + return getChargedPlate(instancePlate); } @Nonnull @ParametersAreNonnullByDefault - public static ItemStack getChargedPlate(PlateStorage plateStorage) { + public static ItemStack getChargedPlate(InstancePlate instancePlate) { ItemStack newPlate = Materials.CHARGED_PLATE_T_1.getItem().clone(); - PlateStorage.setPlateLore(newPlate, plateStorage); + InstancePlate.setPlateLore(newPlate, instancePlate); ItemMeta itemMeta = newPlate.getItemMeta(); DataTypeMethods.setCustom( itemMeta, Keys.PDC_PLATE_STORAGE, PersistentPlateDataType.TYPE, - plateStorage + instancePlate ); newPlate.setItemMeta(itemMeta); return newPlate; diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/ParticleUtils.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/ParticleUtils.java new file mode 100644 index 00000000..8f14888d --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/ParticleUtils.java @@ -0,0 +1,50 @@ +package io.github.sefiraat.crystamaehistoria.utils; + +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.util.Vector; + +import javax.annotation.Nullable; + +public class ParticleUtils { + + public static void drawLine(Particle particle, Location start, Location end, double space) { + drawLine(particle, start, end, space, null); + } + + public static void drawLine(Particle.DustOptions dustOptions, Location start, Location end, double space) { + drawLine(Particle.REDSTONE, start, end, space, dustOptions); + } + + public static void drawLine(Particle particle, Location start, Location end, double space, @Nullable Particle.DustOptions dustOptions) { + final double distance = start.distance(end); + double currentPoint = 0; + final Vector startVector = start.toVector(); + final Vector endVector = end.toVector(); + final Vector vector = endVector.clone().subtract(startVector).normalize().multiply(space); + + while (currentPoint < distance) { + if (dustOptions != null) { + start.getWorld().spawnParticle( + particle, + startVector.getX(), + startVector.getY(), + startVector.getZ(), + 1, + dustOptions + ); + } else { + start.getWorld().spawnParticle( + particle, + startVector.getX(), + startVector.getY(), + startVector.getZ(), + 1 + ); + } + currentPoint += space; + startVector.add(vector); + } + } + +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/SpellUtils.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/SpellUtils.java index e8bf9d6b..59df9cdc 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/SpellUtils.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/SpellUtils.java @@ -16,6 +16,7 @@ import org.bukkit.entity.Fireball; import org.bukkit.entity.Mob; import org.bukkit.entity.Projectile; +import org.bukkit.scheduler.BukkitRunnable; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -28,19 +29,19 @@ public class SpellUtils { // TODO Wrap projectiles in this also public static MagicSummon summonTemporaryMob(EntityType entityType, UUID caster, Location location, AbstractGoal goal) { - return summonTemporaryMob(entityType, caster, location, goal, 30); + return summonTemporaryMob(entityType, caster, location, goal, 30); } public static MagicSummon summonTemporaryMob(EntityType entityType, UUID caster, Location location, AbstractGoal goal, int timeInSeconds) { - return summonTemporaryMob(entityType, caster, location, goal, timeInSeconds * 1000L, null); + return summonTemporaryMob(entityType, caster, location, goal, timeInSeconds * 1000L, null); } - public static MagicSummon summonTemporaryMob(EntityType entityType, UUID caster, Location location, AbstractGoal goal, @Nonnull Consumer tickConsumer) { - return summonTemporaryMob(entityType, caster, location, goal, 30, tickConsumer); + public static MagicSummon summonTemporaryMob(EntityType entityType, UUID caster, Location location, AbstractGoal goal, @Nonnull Consumer tickConsumer) { + return summonTemporaryMob(entityType, caster, location, goal, 30, tickConsumer); } public static MagicSummon summonTemporaryMob(EntityType entityType, UUID caster, Location location, AbstractGoal goal, int timeInSeconds, @Nonnull Consumer tickConsumer) { - return summonTemporaryMob(entityType, caster, location, goal, timeInSeconds * 1000L, tickConsumer); + return summonTemporaryMob(entityType, caster, location, goal, timeInSeconds * 1000L, tickConsumer); } private static MagicSummon summonTemporaryMob(EntityType entityType, UUID caster, Location location, AbstractGoal goal, long duration, @Nullable Consumer tickConsumer) { @@ -48,30 +49,35 @@ private static MagicSummon summonTemporaryMob(EntityType entityT final MagicSummon magicSummon = new MagicSummon(mob.getUniqueId(), caster); final MobGoals mobGoals = Bukkit.getMobGoals(); + mobGoals.removeAllGoals(mob); + if (tickConsumer != null) { magicSummon.setTickConsumer(tickConsumer); } + CrystamaeHistoria.getSummonedEntityMap().put(magicSummon, System.currentTimeMillis() + duration); DataTypeMethods.setCustom(mob, Keys.PDC_IS_SPAWN_OWNER, PersistentUUIDDataType.TYPE, caster); goal.setSelf(mob); + mobGoals.addGoal(mob, 1, goal); + return magicSummon; } public static MagicProjectile summonMagicProjectile(CastInformation castInformation, EntityType entityType, Location location) { - return summonMagicProjectile(castInformation, entityType, location, 5); + return summonMagicProjectile(castInformation, entityType, location, 5); } public static MagicProjectile summonMagicProjectile(CastInformation castInformation, EntityType entityType, Location location, int timeInSeconds) { - return summonMagicProjectile(castInformation, entityType, location, timeInSeconds * 1000L, null); + return summonMagicProjectile(castInformation, entityType, location, timeInSeconds * 1000L, null); } public static MagicProjectile summonMagicProjectile(CastInformation castInformation, EntityType entityType, Location location, @Nonnull Consumer tickConsumer) { - return summonMagicProjectile(castInformation, entityType, location, 30, tickConsumer); + return summonMagicProjectile(castInformation, entityType, location, 30, tickConsumer); } public static MagicProjectile summonMagicProjectile(CastInformation castInformation, EntityType entityType, Location location, int timeInSeconds, @Nonnull Consumer tickConsumer) { - return summonMagicProjectile(castInformation, entityType, location, timeInSeconds * 1000L, tickConsumer); + return summonMagicProjectile(castInformation, entityType, location, timeInSeconds * 1000L, tickConsumer); } private static MagicProjectile summonMagicProjectile(CastInformation castInformation, EntityType entityType, Location location, long duration, @Nullable Consumer tickConsumer) { diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/datatypes/PersistentPlateDataType.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/datatypes/PersistentPlateDataType.java index f8ce5a81..7ec62fe3 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/datatypes/PersistentPlateDataType.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/datatypes/PersistentPlateDataType.java @@ -1,7 +1,7 @@ package io.github.sefiraat.crystamaehistoria.utils.datatypes; import io.github.sefiraat.crystamaehistoria.magic.SpellType; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.PlateStorage; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.InstancePlate; import io.github.sefiraat.crystamaehistoria.utils.Keys; import org.bukkit.persistence.PersistentDataAdapterContext; import org.bukkit.persistence.PersistentDataContainer; @@ -10,7 +10,7 @@ import javax.annotation.Nonnull; /** - * A {@link PersistentDataType} for {@link PlateStorage}s which uses an + * A {@link PersistentDataType} for {@link InstancePlate}s which uses an * {@link Integer} array for storage purposes. * Creatively thieved from {@see PersistentUUIDDataType} * @@ -18,9 +18,9 @@ * @author Walshy */ -public class PersistentPlateDataType implements PersistentDataType { +public class PersistentPlateDataType implements PersistentDataType { - public static final PersistentDataType TYPE = new PersistentPlateDataType(); + public static final PersistentDataType TYPE = new PersistentPlateDataType(); @Override @Nonnull @@ -30,13 +30,13 @@ public Class getPrimitiveType() { @Override @Nonnull - public Class getComplexType() { - return PlateStorage.class; + public Class getComplexType() { + return InstancePlate.class; } @Override @Nonnull - public PersistentDataContainer toPrimitive(@Nonnull PlateStorage complex, @Nonnull PersistentDataAdapterContext context) { + public PersistentDataContainer toPrimitive(@Nonnull InstancePlate complex, @Nonnull PersistentDataAdapterContext context) { PersistentDataContainer container = context.newPersistentDataContainer(); container.set(Keys.PLATE_TIER, PersistentDataType.INTEGER, complex.getTier()); container.set(Keys.PLATE_SPELL, PersistentDataType.STRING, complex.getStoredSpell().getId()); @@ -47,13 +47,13 @@ public PersistentDataContainer toPrimitive(@Nonnull PlateStorage complex, @Nonnu @Override @Nonnull - public PlateStorage fromPrimitive(@Nonnull PersistentDataContainer primitive, @Nonnull PersistentDataAdapterContext context) { - PlateStorage plateStorage = new PlateStorage( + public InstancePlate fromPrimitive(@Nonnull PersistentDataContainer primitive, @Nonnull PersistentDataAdapterContext context) { + InstancePlate instancePlate = new InstancePlate( primitive.get(Keys.PLATE_TIER, PersistentDataType.INTEGER), SpellType.valueOf(primitive.get(Keys.PLATE_SPELL, PersistentDataType.STRING)), primitive.get(Keys.PLATE_CHARGES, PersistentDataType.INTEGER) ); - plateStorage.setCooldown(primitive.get(Keys.PLATE_COOLDOWN, PersistentDataType.LONG)); - return plateStorage; + instancePlate.setCooldown(primitive.get(Keys.PLATE_COOLDOWN, PersistentDataType.LONG)); + return instancePlate; } } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/datatypes/PersistentStaveDataType.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/datatypes/PersistentStaveDataType.java index cce9bff1..3b2e8f99 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/datatypes/PersistentStaveDataType.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/datatypes/PersistentStaveDataType.java @@ -1,6 +1,6 @@ package io.github.sefiraat.crystamaehistoria.utils.datatypes; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.plates.PlateStorage; +import io.github.sefiraat.crystamaehistoria.magic.spells.core.InstancePlate; import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.SpellSlot; import io.github.sefiraat.crystamaehistoria.stories.Story; import io.github.sefiraat.crystamaehistoria.utils.Keys; @@ -21,9 +21,9 @@ * @author Walshy */ -public class PersistentStaveDataType implements PersistentDataType> { +public class PersistentStaveDataType implements PersistentDataType> { - public static final PersistentDataType> TYPE = new PersistentStaveDataType(); + public static final PersistentDataType> TYPE = new PersistentStaveDataType(); @Override @Nonnull @@ -34,17 +34,17 @@ public Class getPrimitiveType() { @SuppressWarnings("unchecked") @Override @Nonnull - public Class> getComplexType() { - return (Class>) (Class) Map.class; + public Class> getComplexType() { + return (Class>) (Class) Map.class; } @Override @Nonnull - public PersistentDataContainer[] toPrimitive(@Nonnull Map complex, @Nonnull PersistentDataAdapterContext context) { + public PersistentDataContainer[] toPrimitive(@Nonnull Map complex, @Nonnull PersistentDataAdapterContext context) { PersistentDataContainer[] containers = new PersistentDataContainer[complex.size()]; int i = 0; - for (Map.Entry spellTypeEntry : complex.entrySet()) { + for (Map.Entry spellTypeEntry : complex.entrySet()) { PersistentDataContainer container = context.newPersistentDataContainer(); container.set(Keys.STAVE_SLOT, PersistentDataType.STRING, spellTypeEntry.getKey().toString()); container.set(Keys.STAVE_PLATE, PersistentPlateDataType.TYPE, spellTypeEntry.getValue()); @@ -57,12 +57,12 @@ public PersistentDataContainer[] toPrimitive(@Nonnull Map fromPrimitive(@Nonnull PersistentDataContainer[] primitive, @Nonnull PersistentDataAdapterContext context) { - Map plateStorageMap = new EnumMap<>(SpellSlot.class); + public Map fromPrimitive(@Nonnull PersistentDataContainer[] primitive, @Nonnull PersistentDataAdapterContext context) { + Map plateStorageMap = new EnumMap<>(SpellSlot.class); for (PersistentDataContainer container : primitive) { final SpellSlot spellSlot = SpellSlot.valueOf(container.get(Keys.STAVE_SLOT, PersistentDataType.STRING)); - final PlateStorage plateStorage = container.get(Keys.STAVE_PLATE, PersistentPlateDataType.TYPE); - plateStorageMap.put(spellSlot, plateStorage); + final InstancePlate instancePlate = container.get(Keys.STAVE_PLATE, PersistentPlateDataType.TYPE); + plateStorageMap.put(spellSlot, instancePlate); } return plateStorageMap; } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/AbstractGoal.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/AbstractGoal.java index 7da55008..cc0cc8a8 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/AbstractGoal.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/AbstractGoal.java @@ -3,7 +3,6 @@ import com.destroystokyo.paper.entity.ai.Goal; import com.destroystokyo.paper.entity.ai.GoalKey; import com.destroystokyo.paper.entity.ai.GoalType; -import io.github.sefiraat.crystamaehistoria.slimefun.tools.stave.Stave; import io.github.sefiraat.crystamaehistoria.utils.Keys; import io.github.sefiraat.crystamaehistoria.utils.datatypes.DataTypeMethods; import io.github.sefiraat.crystamaehistoria.utils.datatypes.PersistentUUIDDataType; @@ -69,7 +68,7 @@ public void tick() { return; } - if (self.getTarget() == null || self.getTarget().isDead()) { + if (getTickCondition() && (self.getTarget() == null || self.getTarget().isDead())) { if (getTargetsEnemies()) { final List entities = new ArrayList<>( player.getWorld().getNearbyEntitiesByType( @@ -106,9 +105,11 @@ public void tick() { ); self.getPathfinder().moveTo(location); } + + customActions(player); + } - customActions(player); } } @@ -146,6 +147,10 @@ public boolean getTargetsEnemies() { return true; } + public boolean getTickCondition() { + return true; + } + public boolean getFollowsPlayer() { return true; } diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/AbstractRidableGoal.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/AbstractRidableGoal.java new file mode 100644 index 00000000..6cd3e485 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/AbstractRidableGoal.java @@ -0,0 +1,50 @@ +package io.github.sefiraat.crystamaehistoria.utils.mobgoals; + +import io.github.sefiraat.crystamaehistoria.CrystamaeHistoria; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Mob; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.UUID; + +// TODO UNUSED +public abstract class AbstractRidableGoal extends AbstractGoal { + + protected AbstractRidableGoal(UUID owningPlayer) { + super(owningPlayer); + } + + @Override + public void tick() { + if (!this.self.getPassengers().isEmpty()) { + final Player player = Bukkit.getPlayer(owner); + final Vector eyeDirection = player.getEyeLocation().getDirection(); + final Location destination = player.getLocation().clone().add(eyeDirection); + + if (getCanFly()) { + // Flying Mobs + self.setVelocity(eyeDirection.clone().multiply(getSpeed())); + } else { + // Non-flying mobs + final Block block = destination.getBlock(); + self.getPathfinder().moveTo(self.getLocation().add(0,0,1)); + + } + + + } else { + super.tick(); + } + } + + public boolean getCanFly() { + return false; + } + + public double getSpeed() { + return 1; + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/FlyingPhantomGoal.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/FlyingPhantomGoal.java new file mode 100644 index 00000000..34b2cab4 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/FlyingPhantomGoal.java @@ -0,0 +1,30 @@ +package io.github.sefiraat.crystamaehistoria.utils.mobgoals; + +import org.bukkit.entity.Phantom; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class FlyingPhantomGoal extends AbstractRidableGoal { + + public FlyingPhantomGoal(UUID owningPlayer) { + super(owningPlayer); + } + + @Override + public void customActions(Player player) { + if (self.getPassengers().isEmpty()) { + self.remove(); + } + } + + @Override + public boolean getCanFly() { + return true; + } + + @Override + public double getSpeed() { + return 2; + } +} diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/GolemGoal.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/GolemGoal.java index cb1c522f..60a9cb22 100644 --- a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/GolemGoal.java +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/GolemGoal.java @@ -1,7 +1,6 @@ package io.github.sefiraat.crystamaehistoria.utils.mobgoals; import org.bukkit.entity.Mob; -import org.bukkit.entity.Player; import java.util.UUID; diff --git a/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/RidableGroundGoal.java b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/RidableGroundGoal.java new file mode 100644 index 00000000..6e97ae45 --- /dev/null +++ b/src/main/java/io/github/sefiraat/crystamaehistoria/utils/mobgoals/RidableGroundGoal.java @@ -0,0 +1,13 @@ +package io.github.sefiraat.crystamaehistoria.utils.mobgoals; + +import org.bukkit.entity.Mob; + +import java.util.UUID; + +public class RidableGroundGoal extends AbstractRidableGoal { + + public RidableGroundGoal(UUID owningPlayer) { + super(owningPlayer); + } + +} diff --git a/src/main/resources/block_colors.yml b/src/main/resources/block_colors.yml new file mode 100644 index 00000000..4d7f5f53 --- /dev/null +++ b/src/main/resources/block_colors.yml @@ -0,0 +1,898 @@ +AIR: [0, 0, 0] +STONE: [112, 112, 112] +GRANITE: [151, 109, 77] +POLISHED_GRANITE: [151, 109, 77] +DIORITE: [255, 252, 245] +POLISHED_DIORITE: [255, 252, 245] +ANDESITE: [112, 112, 112] +POLISHED_ANDESITE: [112, 112, 112] +DEEPSLATE: [100, 100, 100] +COBBLED_DEEPSLATE: [100, 100, 100] +POLISHED_DEEPSLATE: [100, 100, 100] +CALCITE: [209, 177, 161] +TUFF: [57, 41, 35] +DRIPSTONE_BLOCK: [76, 50, 35] +GRASS_BLOCK: [127, 178, 56] +DIRT: [151, 109, 77] +COARSE_DIRT: [151, 109, 77] +PODZOL: [129, 86, 49] +ROOTED_DIRT: [151, 109, 77] +CRIMSON_NYLIUM: [189, 48, 49] +WARPED_NYLIUM: [22, 126, 134] +COBBLESTONE: [112, 112, 112] +OAK_PLANKS: [143, 119, 72] +SPRUCE_PLANKS: [129, 86, 49] +BIRCH_PLANKS: [247, 233, 163] +JUNGLE_PLANKS: [151, 109, 77] +ACACIA_PLANKS: [216, 127, 51] +DARK_OAK_PLANKS: [102, 76, 51] +CRIMSON_PLANKS: [148, 63, 97] +WARPED_PLANKS: [58, 142, 140] +OAK_SAPLING: [0, 124, 0] +SPRUCE_SAPLING: [0, 124, 0] +BIRCH_SAPLING: [0, 124, 0] +JUNGLE_SAPLING: [0, 124, 0] +ACACIA_SAPLING: [0, 124, 0] +DARK_OAK_SAPLING: [0, 124, 0] +BEDROCK: [112, 112, 112] +SAND: [247, 233, 163] +RED_SAND: [216, 127, 51] +GRAVEL: [112, 112, 112] +COAL_ORE: [25, 25, 25] +DEEPSLATE_COAL_ORE: [25, 25, 25] +IRON_ORE: [216, 175, 147] +DEEPSLATE_IRON_ORE: [216, 175, 147] +COPPER_ORE: [216, 127, 51] +DEEPSLATE_COPPER_ORE: [216, 127, 51] +GOLD_ORE: [250, 238, 77] +DEEPSLATE_GOLD_ORE: [250, 238, 77] +REDSTONE_ORE: [240, 10, 15] +DEEPSLATE_REDSTONE_ORE: [240, 10, 15] +EMERALD_ORE: [0, 217, 58] +DEEPSLATE_EMERALD_ORE: [0, 217, 58] +LAPIS_ORE: [74, 128, 255] +DEEPSLATE_LAPIS_ORE: [74, 128, 255] +DIAMOND_ORE: [92, 219, 213] +DEEPSLATE_DIAMOND_ORE: [92, 219, 213] +NETHER_GOLD_ORE: [250, 238, 77] +NETHER_QUARTZ_ORE: [112, 2, 0] +ANCIENT_DEBRIS: [25, 25, 25] +COAL_BLOCK: [25, 25, 25] +RAW_IRON_BLOCK: [216, 175, 147] +RAW_COPPER_BLOCK: [216, 127, 51] +RAW_GOLD_BLOCK: [250, 238, 77] +AMETHYST_BLOCK: [127, 63, 178] +BUDDING_AMETHYST: [127, 63, 178] +IRON_BLOCK: [167, 167, 167] +COPPER_BLOCK: [216, 127, 51] +GOLD_BLOCK: [250, 238, 77] +DIAMOND_BLOCK: [92, 219, 213] +NETHERITE_BLOCK: [25, 25, 25] +EXPOSED_COPPER: [135, 107, 98] +WEATHERED_COPPER: [58, 142, 140] +OXIDIZED_COPPER: [22, 126, 134] +CUT_COPPER: [216, 127, 51] +EXPOSED_CUT_COPPER: [135, 107, 98] +WEATHERED_CUT_COPPER: [58, 142, 140] +OXIDIZED_CUT_COPPER: [22, 126, 134] +CUT_COPPER_STAIRS: [216, 127, 51] +EXPOSED_CUT_COPPER_STAIRS: [135, 107, 98] +WEATHERED_CUT_COPPER_STAIRS: [58, 142, 140] +OXIDIZED_CUT_COPPER_STAIRS: [22, 126, 134] +CUT_COPPER_SLAB: [216, 127, 51] +EXPOSED_CUT_COPPER_SLAB: [135, 107, 98] +WEATHERED_CUT_COPPER_SLAB: [58, 142, 140] +OXIDIZED_CUT_COPPER_SLAB: [22, 126, 134] +WAXED_COPPER_BLOCK: [216, 127, 51] +WAXED_EXPOSED_COPPER: [135, 107, 98] +WAXED_WEATHERED_COPPER: [58, 142, 140] +WAXED_OXIDIZED_COPPER: [22, 126, 134] +WAXED_CUT_COPPER: [216, 127, 51] +WAXED_EXPOSED_CUT_COPPER: [135, 107, 98] +WAXED_WEATHERED_CUT_COPPER: [58, 142, 140] +WAXED_OXIDIZED_CUT_COPPER: [22, 126, 134] +WAXED_CUT_COPPER_STAIRS: [216, 127, 51] +WAXED_EXPOSED_CUT_COPPER_STAIRS: [135, 107, 98] +WAXED_WEATHERED_CUT_COPPER_STAIRS: [58, 142, 140] +WAXED_OXIDIZED_CUT_COPPER_STAIRS: [22, 126, 134] +WAXED_CUT_COPPER_SLAB: [216, 127, 51] +WAXED_EXPOSED_CUT_COPPER_SLAB: [135, 107, 98] +WAXED_WEATHERED_CUT_COPPER_SLAB: [58, 142, 140] +WAXED_OXIDIZED_CUT_COPPER_SLAB: [22, 126, 134] +OAK_LOG: [143, 119, 72] +SPRUCE_LOG: [129, 86, 49] +BIRCH_LOG: [247, 233, 163] +JUNGLE_LOG: [151, 109, 77] +ACACIA_LOG: [216, 127, 51] +DARK_OAK_LOG: [102, 76, 51] +CRIMSON_STEM: [148, 63, 97] +WARPED_STEM: [58, 142, 140] +STRIPPED_OAK_LOG: [143, 119, 72] +STRIPPED_SPRUCE_LOG: [129, 86, 49] +STRIPPED_BIRCH_LOG: [247, 233, 163] +STRIPPED_JUNGLE_LOG: [151, 109, 77] +STRIPPED_ACACIA_LOG: [216, 127, 51] +STRIPPED_DARK_OAK_LOG: [102, 76, 51] +STRIPPED_CRIMSON_STEM: [148, 63, 97] +STRIPPED_WARPED_STEM: [58, 142, 140] +STRIPPED_OAK_WOOD: [143, 119, 72] +STRIPPED_SPRUCE_WOOD: [129, 86, 49] +STRIPPED_BIRCH_WOOD: [247, 233, 163] +STRIPPED_JUNGLE_WOOD: [151, 109, 77] +STRIPPED_ACACIA_WOOD: [216, 127, 51] +STRIPPED_DARK_OAK_WOOD: [102, 76, 51] +STRIPPED_CRIMSON_HYPHAE: [92, 25, 29] +STRIPPED_WARPED_HYPHAE: [86, 44, 62] +OAK_WOOD: [143, 119, 72] +SPRUCE_WOOD: [129, 86, 49] +BIRCH_WOOD: [247, 233, 163] +JUNGLE_WOOD: [151, 109, 77] +ACACIA_WOOD: [76, 76, 76] +DARK_OAK_WOOD: [102, 76, 51] +CRIMSON_HYPHAE: [92, 25, 29] +WARPED_HYPHAE: [86, 44, 62] +OAK_LEAVES: [0, 124, 0] +SPRUCE_LEAVES: [0, 124, 0] +BIRCH_LEAVES: [0, 124, 0] +JUNGLE_LEAVES: [0, 124, 0] +ACACIA_LEAVES: [0, 124, 0] +DARK_OAK_LEAVES: [0, 124, 0] +AZALEA_LEAVES: [0, 124, 0] +FLOWERING_AZALEA_LEAVES: [0, 124, 0] +SPONGE: [229, 229, 51] +WET_SPONGE: [229, 229, 51] +GLASS: [0, 0, 0] +TINTED_GLASS: [76, 76, 76] +LAPIS_BLOCK: [74, 128, 255] +SANDSTONE: [247, 233, 163] +CHISELED_SANDSTONE: [247, 233, 163] +CUT_SANDSTONE: [247, 233, 163] +COBWEB: [199, 199, 199] +GRASS: [0, 124, 0] +FERN: [0, 124, 0] +AZALEA: [0, 124, 0] +FLOWERING_AZALEA: [0, 124, 0] +DEAD_BUSH: [143, 119, 72] +SEAGRASS: [64, 64, 255] +SEA_PICKLE: [102, 127, 51] +WHITE_WOOL: [255, 255, 255] +ORANGE_WOOL: [216, 127, 51] +MAGENTA_WOOL: [178, 76, 216] +LIGHT_BLUE_WOOL: [102, 153, 216] +YELLOW_WOOL: [229, 229, 51] +LIME_WOOL: [127, 204, 25] +PINK_WOOL: [242, 127, 165] +GRAY_WOOL: [76, 76, 76] +LIGHT_GRAY_WOOL: [153, 153, 153] +CYAN_WOOL: [76, 127, 153] +PURPLE_WOOL: [127, 63, 178] +BLUE_WOOL: [51, 76, 178] +BROWN_WOOL: [102, 76, 51] +GREEN_WOOL: [102, 127, 51] +RED_WOOL: [153, 51, 51] +BLACK_WOOL: [25, 25, 25] +DANDELION: [0, 124, 0] +POPPY: [0, 124, 0] +BLUE_ORCHID: [0, 124, 0] +ALLIUM: [0, 124, 0] +AZURE_BLUET: [0, 124, 0] +RED_TULIP: [0, 124, 0] +ORANGE_TULIP: [0, 124, 0] +WHITE_TULIP: [0, 124, 0] +PINK_TULIP: [0, 124, 0] +OXEYE_DAISY: [0, 124, 0] +CORNFLOWER: [0, 124, 0] +LILY_OF_THE_VALLEY: [0, 124, 0] +WITHER_ROSE: [0, 124, 0] +SPORE_BLOSSOM: [0, 124, 0] +BROWN_MUSHROOM: [102, 76, 51] +RED_MUSHROOM: [153, 51, 51] +CRIMSON_FUNGUS: [112, 2, 0] +WARPED_FUNGUS: [76, 127, 153] +CRIMSON_ROOTS: [112, 2, 0] +WARPED_ROOTS: [76, 127, 153] +NETHER_SPROUTS: [76, 127, 153] +WEEPING_VINES: [112, 2, 0] +TWISTING_VINES: [76, 127, 153] +SUGAR_CANE: [0, 124, 0] +KELP: [64, 64, 255] +MOSS_CARPET: [102, 127, 51] +MOSS_BLOCK: [102, 127, 51] +HANGING_ROOTS: [151, 109, 77] +BIG_DRIPLEAF: [0, 124, 0] +SMALL_DRIPLEAF: [0, 124, 0] +BAMBOO: [0, 124, 0] +OAK_SLAB: [143, 119, 72] +SPRUCE_SLAB: [129, 86, 49] +BIRCH_SLAB: [247, 233, 163] +JUNGLE_SLAB: [151, 109, 77] +ACACIA_SLAB: [216, 127, 51] +DARK_OAK_SLAB: [102, 76, 51] +CRIMSON_SLAB: [148, 63, 97] +WARPED_SLAB: [58, 142, 140] +STONE_SLAB: [112, 112, 112] +SMOOTH_STONE_SLAB: [112, 112, 112] +SANDSTONE_SLAB: [247, 233, 163] +CUT_SANDSTONE_SLAB: [247, 233, 163] +PETRIFIED_OAK_SLAB: [143, 119, 72] +COBBLESTONE_SLAB: [112, 112, 112] +BRICK_SLAB: [153, 51, 51] +STONE_BRICK_SLAB: [112, 112, 112] +NETHER_BRICK_SLAB: [112, 2, 0] +QUARTZ_SLAB: [255, 252, 245] +RED_SANDSTONE_SLAB: [216, 127, 51] +CUT_RED_SANDSTONE_SLAB: [216, 127, 51] +PURPUR_SLAB: [178, 76, 216] +PRISMARINE_SLAB: [76, 127, 153] +PRISMARINE_BRICK_SLAB: [92, 219, 213] +DARK_PRISMARINE_SLAB: [92, 219, 213] +SMOOTH_QUARTZ: [255, 252, 245] +SMOOTH_RED_SANDSTONE: [216, 127, 51] +SMOOTH_SANDSTONE: [247, 233, 163] +SMOOTH_STONE: [112, 112, 112] +BRICKS: [153, 51, 51] +BOOKSHELF: [143, 119, 72] +MOSSY_COBBLESTONE: [112, 112, 112] +OBSIDIAN: [25, 25, 25] +TORCH: [0, 0, 0] +END_ROD: [0, 0, 0] +CHORUS_PLANT: [127, 63, 178] +CHORUS_FLOWER: [127, 63, 178] +PURPUR_BLOCK: [178, 76, 216] +PURPUR_PILLAR: [178, 76, 216] +PURPUR_STAIRS: [178, 76, 216] +SPAWNER: [112, 112, 112] +OAK_STAIRS: [143, 119, 72] +CHEST: [143, 119, 72] +CRAFTING_TABLE: [143, 119, 72] +FARMLAND: [151, 109, 77] +FURNACE: [112, 112, 112] +LADDER: [0, 0, 0] +COBBLESTONE_STAIRS: [112, 112, 112] +SNOW: [255, 255, 255] +ICE: [160, 160, 255] +SNOW_BLOCK: [255, 255, 255] +CACTUS: [0, 124, 0] +CLAY: [164, 168, 184] +JUKEBOX: [151, 109, 77] +OAK_FENCE: [143, 119, 72] +SPRUCE_FENCE: [129, 86, 49] +BIRCH_FENCE: [247, 233, 163] +JUNGLE_FENCE: [151, 109, 77] +ACACIA_FENCE: [216, 127, 51] +DARK_OAK_FENCE: [102, 76, 51] +CRIMSON_FENCE: [148, 63, 97] +WARPED_FENCE: [58, 142, 140] +PUMPKIN: [216, 127, 51] +CARVED_PUMPKIN: [216, 127, 51] +JACK_O_LANTERN: [216, 127, 51] +NETHERRACK: [112, 2, 0] +SOUL_SAND: [102, 76, 51] +SOUL_SOIL: [102, 76, 51] +BASALT: [25, 25, 25] +POLISHED_BASALT: [25, 25, 25] +SMOOTH_BASALT: [25, 25, 25] +SOUL_TORCH: [0, 0, 0] +GLOWSTONE: [247, 233, 163] +INFESTED_STONE: [164, 168, 184] +INFESTED_COBBLESTONE: [164, 168, 184] +INFESTED_STONE_BRICKS: [164, 168, 184] +INFESTED_MOSSY_STONE_BRICKS: [164, 168, 184] +INFESTED_CRACKED_STONE_BRICKS: [164, 168, 184] +INFESTED_CHISELED_STONE_BRICKS: [164, 168, 184] +INFESTED_DEEPSLATE: [100, 100, 100] +STONE_BRICKS: [112, 112, 112] +MOSSY_STONE_BRICKS: [112, 112, 112] +CRACKED_STONE_BRICKS: [112, 112, 112] +CHISELED_STONE_BRICKS: [112, 112, 112] +DEEPSLATE_BRICKS: [100, 100, 100] +CRACKED_DEEPSLATE_BRICKS: [100, 100, 100] +DEEPSLATE_TILES: [100, 100, 100] +CRACKED_DEEPSLATE_TILES: [100, 100, 100] +CHISELED_DEEPSLATE: [100, 100, 100] +BROWN_MUSHROOM_BLOCK: [151, 109, 77] +RED_MUSHROOM_BLOCK: [153, 51, 51] +MUSHROOM_STEM: [199, 199, 199] +IRON_BARS: [0, 0, 0] +CHAIN: [0, 0, 0] +GLASS_PANE: [0, 0, 0] +MELON: [127, 204, 25] +VINE: [0, 124, 0] +GLOW_LICHEN: [127, 167, 150] +BRICK_STAIRS: [153, 51, 51] +STONE_BRICK_STAIRS: [112, 112, 112] +MYCELIUM: [127, 63, 178] +LILY_PAD: [0, 124, 0] +NETHER_BRICKS: [112, 2, 0] +CRACKED_NETHER_BRICKS: [112, 2, 0] +CHISELED_NETHER_BRICKS: [112, 2, 0] +NETHER_BRICK_FENCE: [112, 2, 0] +NETHER_BRICK_STAIRS: [112, 2, 0] +ENCHANTING_TABLE: [153, 51, 51] +END_PORTAL_FRAME: [102, 127, 51] +END_STONE: [247, 233, 163] +END_STONE_BRICKS: [247, 233, 163] +DRAGON_EGG: [25, 25, 25] +SANDSTONE_STAIRS: [247, 233, 163] +ENDER_CHEST: [112, 112, 112] +EMERALD_BLOCK: [0, 217, 58] +SPRUCE_STAIRS: [129, 86, 49] +BIRCH_STAIRS: [247, 233, 163] +JUNGLE_STAIRS: [151, 109, 77] +CRIMSON_STAIRS: [148, 63, 97] +WARPED_STAIRS: [58, 142, 140] +COMMAND_BLOCK: [102, 76, 51] +BEACON: [92, 219, 213] +COBBLESTONE_WALL: [112, 112, 112] +MOSSY_COBBLESTONE_WALL: [112, 112, 112] +BRICK_WALL: [153, 51, 51] +PRISMARINE_WALL: [76, 127, 153] +RED_SANDSTONE_WALL: [216, 127, 51] +MOSSY_STONE_BRICK_WALL: [112, 112, 112] +GRANITE_WALL: [151, 109, 77] +STONE_BRICK_WALL: [112, 112, 112] +NETHER_BRICK_WALL: [112, 2, 0] +ANDESITE_WALL: [112, 112, 112] +RED_NETHER_BRICK_WALL: [112, 2, 0] +SANDSTONE_WALL: [247, 233, 163] +END_STONE_BRICK_WALL: [247, 233, 163] +DIORITE_WALL: [255, 252, 245] +BLACKSTONE_WALL: [25, 25, 25] +POLISHED_BLACKSTONE_WALL: [25, 25, 25] +POLISHED_BLACKSTONE_BRICK_WALL: [25, 25, 25] +COBBLED_DEEPSLATE_WALL: [100, 100, 100] +POLISHED_DEEPSLATE_WALL: [100, 100, 100] +DEEPSLATE_BRICK_WALL: [100, 100, 100] +DEEPSLATE_TILE_WALL: [100, 100, 100] +ANVIL: [167, 167, 167] +CHIPPED_ANVIL: [167, 167, 167] +DAMAGED_ANVIL: [167, 167, 167] +CHISELED_QUARTZ_BLOCK: [255, 252, 245] +QUARTZ_BLOCK: [255, 252, 245] +QUARTZ_BRICKS: [255, 252, 245] +QUARTZ_PILLAR: [255, 252, 245] +QUARTZ_STAIRS: [255, 252, 245] +WHITE_TERRACOTTA: [209, 177, 161] +ORANGE_TERRACOTTA: [159, 82, 36] +MAGENTA_TERRACOTTA: [149, 87, 108] +LIGHT_BLUE_TERRACOTTA: [112, 108, 138] +YELLOW_TERRACOTTA: [186, 133, 36] +LIME_TERRACOTTA: [103, 117, 53] +PINK_TERRACOTTA: [160, 77, 78] +GRAY_TERRACOTTA: [57, 41, 35] +LIGHT_GRAY_TERRACOTTA: [135, 107, 98] +CYAN_TERRACOTTA: [87, 92, 92] +PURPLE_TERRACOTTA: [122, 73, 88] +BLUE_TERRACOTTA: [76, 62, 92] +BROWN_TERRACOTTA: [76, 50, 35] +GREEN_TERRACOTTA: [76, 82, 42] +RED_TERRACOTTA: [142, 60, 46] +BLACK_TERRACOTTA: [37, 22, 16] +BARRIER: [0, 0, 0] +LIGHT: [0, 0, 0] +HAY_BLOCK: [229, 229, 51] +WHITE_CARPET: [255, 255, 255] +ORANGE_CARPET: [216, 127, 51] +MAGENTA_CARPET: [178, 76, 216] +LIGHT_BLUE_CARPET: [102, 153, 216] +YELLOW_CARPET: [229, 229, 51] +LIME_CARPET: [127, 204, 25] +PINK_CARPET: [242, 127, 165] +GRAY_CARPET: [76, 76, 76] +LIGHT_GRAY_CARPET: [153, 153, 153] +CYAN_CARPET: [76, 127, 153] +PURPLE_CARPET: [127, 63, 178] +BLUE_CARPET: [51, 76, 178] +BROWN_CARPET: [102, 76, 51] +GREEN_CARPET: [102, 127, 51] +RED_CARPET: [153, 51, 51] +BLACK_CARPET: [25, 25, 25] +TERRACOTTA: [216, 127, 51] +PACKED_ICE: [160, 160, 255] +ACACIA_STAIRS: [216, 127, 51] +DARK_OAK_STAIRS: [102, 76, 51] +DIRT_PATH: [151, 109, 77] +SUNFLOWER: [0, 124, 0] +LILAC: [0, 124, 0] +ROSE_BUSH: [0, 124, 0] +PEONY: [0, 124, 0] +TALL_GRASS: [0, 124, 0] +LARGE_FERN: [0, 124, 0] +WHITE_STAINED_GLASS: [255, 255, 255] +ORANGE_STAINED_GLASS: [216, 127, 51] +MAGENTA_STAINED_GLASS: [178, 76, 216] +LIGHT_BLUE_STAINED_GLASS: [102, 153, 216] +YELLOW_STAINED_GLASS: [229, 229, 51] +LIME_STAINED_GLASS: [127, 204, 25] +PINK_STAINED_GLASS: [242, 127, 165] +GRAY_STAINED_GLASS: [76, 76, 76] +LIGHT_GRAY_STAINED_GLASS: [153, 153, 153] +CYAN_STAINED_GLASS: [76, 127, 153] +PURPLE_STAINED_GLASS: [127, 63, 178] +BLUE_STAINED_GLASS: [51, 76, 178] +BROWN_STAINED_GLASS: [102, 76, 51] +GREEN_STAINED_GLASS: [102, 127, 51] +RED_STAINED_GLASS: [153, 51, 51] +BLACK_STAINED_GLASS: [25, 25, 25] +WHITE_STAINED_GLASS_PANE: [0, 0, 0] +ORANGE_STAINED_GLASS_PANE: [0, 0, 0] +MAGENTA_STAINED_GLASS_PANE: [0, 0, 0] +LIGHT_BLUE_STAINED_GLASS_PANE: [0, 0, 0] +YELLOW_STAINED_GLASS_PANE: [0, 0, 0] +LIME_STAINED_GLASS_PANE: [0, 0, 0] +PINK_STAINED_GLASS_PANE: [0, 0, 0] +GRAY_STAINED_GLASS_PANE: [0, 0, 0] +LIGHT_GRAY_STAINED_GLASS_PANE: [0, 0, 0] +CYAN_STAINED_GLASS_PANE: [0, 0, 0] +PURPLE_STAINED_GLASS_PANE: [0, 0, 0] +BLUE_STAINED_GLASS_PANE: [0, 0, 0] +BROWN_STAINED_GLASS_PANE: [0, 0, 0] +GREEN_STAINED_GLASS_PANE: [0, 0, 0] +RED_STAINED_GLASS_PANE: [0, 0, 0] +BLACK_STAINED_GLASS_PANE: [0, 0, 0] +PRISMARINE: [76, 127, 153] +PRISMARINE_BRICKS: [92, 219, 213] +DARK_PRISMARINE: [92, 219, 213] +PRISMARINE_STAIRS: [76, 127, 153] +PRISMARINE_BRICK_STAIRS: [92, 219, 213] +DARK_PRISMARINE_STAIRS: [92, 219, 213] +SEA_LANTERN: [255, 252, 245] +RED_SANDSTONE: [216, 127, 51] +CHISELED_RED_SANDSTONE: [216, 127, 51] +CUT_RED_SANDSTONE: [216, 127, 51] +RED_SANDSTONE_STAIRS: [216, 127, 51] +REPEATING_COMMAND_BLOCK: [127, 63, 178] +CHAIN_COMMAND_BLOCK: [102, 127, 51] +MAGMA_BLOCK: [112, 2, 0] +NETHER_WART_BLOCK: [153, 51, 51] +WARPED_WART_BLOCK: [20, 180, 133] +RED_NETHER_BRICKS: [112, 2, 0] +BONE_BLOCK: [247, 233, 163] +STRUCTURE_VOID: [0, 0, 0] +SHULKER_BOX: [127, 63, 178] +WHITE_SHULKER_BOX: [255, 255, 255] +ORANGE_SHULKER_BOX: [216, 127, 51] +MAGENTA_SHULKER_BOX: [178, 76, 216] +LIGHT_BLUE_SHULKER_BOX: [102, 153, 216] +YELLOW_SHULKER_BOX: [229, 229, 51] +LIME_SHULKER_BOX: [127, 204, 25] +PINK_SHULKER_BOX: [242, 127, 165] +GRAY_SHULKER_BOX: [76, 76, 76] +LIGHT_GRAY_SHULKER_BOX: [153, 153, 153] +CYAN_SHULKER_BOX: [76, 127, 153] +PURPLE_SHULKER_BOX: [122, 73, 88] +BLUE_SHULKER_BOX: [51, 76, 178] +BROWN_SHULKER_BOX: [102, 76, 51] +GREEN_SHULKER_BOX: [102, 127, 51] +RED_SHULKER_BOX: [153, 51, 51] +BLACK_SHULKER_BOX: [25, 25, 25] +WHITE_GLAZED_TERRACOTTA: [255, 255, 255] +ORANGE_GLAZED_TERRACOTTA: [216, 127, 51] +MAGENTA_GLAZED_TERRACOTTA: [178, 76, 216] +LIGHT_BLUE_GLAZED_TERRACOTTA: [102, 153, 216] +YELLOW_GLAZED_TERRACOTTA: [229, 229, 51] +LIME_GLAZED_TERRACOTTA: [127, 204, 25] +PINK_GLAZED_TERRACOTTA: [242, 127, 165] +GRAY_GLAZED_TERRACOTTA: [76, 76, 76] +LIGHT_GRAY_GLAZED_TERRACOTTA: [153, 153, 153] +CYAN_GLAZED_TERRACOTTA: [76, 127, 153] +PURPLE_GLAZED_TERRACOTTA: [127, 63, 178] +BLUE_GLAZED_TERRACOTTA: [51, 76, 178] +BROWN_GLAZED_TERRACOTTA: [102, 76, 51] +GREEN_GLAZED_TERRACOTTA: [102, 127, 51] +RED_GLAZED_TERRACOTTA: [153, 51, 51] +BLACK_GLAZED_TERRACOTTA: [25, 25, 25] +WHITE_CONCRETE: [255, 255, 255] +ORANGE_CONCRETE: [216, 127, 51] +MAGENTA_CONCRETE: [178, 76, 216] +LIGHT_BLUE_CONCRETE: [102, 153, 216] +YELLOW_CONCRETE: [229, 229, 51] +LIME_CONCRETE: [127, 204, 25] +PINK_CONCRETE: [242, 127, 165] +GRAY_CONCRETE: [76, 76, 76] +LIGHT_GRAY_CONCRETE: [153, 153, 153] +CYAN_CONCRETE: [76, 127, 153] +PURPLE_CONCRETE: [127, 63, 178] +BLUE_CONCRETE: [51, 76, 178] +BROWN_CONCRETE: [102, 76, 51] +GREEN_CONCRETE: [102, 127, 51] +RED_CONCRETE: [153, 51, 51] +BLACK_CONCRETE: [25, 25, 25] +WHITE_CONCRETE_POWDER: [255, 255, 255] +ORANGE_CONCRETE_POWDER: [216, 127, 51] +MAGENTA_CONCRETE_POWDER: [178, 76, 216] +LIGHT_BLUE_CONCRETE_POWDER: [102, 153, 216] +YELLOW_CONCRETE_POWDER: [229, 229, 51] +LIME_CONCRETE_POWDER: [127, 204, 25] +PINK_CONCRETE_POWDER: [242, 127, 165] +GRAY_CONCRETE_POWDER: [76, 76, 76] +LIGHT_GRAY_CONCRETE_POWDER: [153, 153, 153] +CYAN_CONCRETE_POWDER: [76, 127, 153] +PURPLE_CONCRETE_POWDER: [127, 63, 178] +BLUE_CONCRETE_POWDER: [51, 76, 178] +BROWN_CONCRETE_POWDER: [102, 76, 51] +GREEN_CONCRETE_POWDER: [102, 127, 51] +RED_CONCRETE_POWDER: [153, 51, 51] +BLACK_CONCRETE_POWDER: [25, 25, 25] +TURTLE_EGG: [247, 233, 163] +DEAD_TUBE_CORAL_BLOCK: [76, 76, 76] +DEAD_BRAIN_CORAL_BLOCK: [76, 76, 76] +DEAD_BUBBLE_CORAL_BLOCK: [76, 76, 76] +DEAD_FIRE_CORAL_BLOCK: [76, 76, 76] +DEAD_HORN_CORAL_BLOCK: [76, 76, 76] +TUBE_CORAL_BLOCK: [51, 76, 178] +BRAIN_CORAL_BLOCK: [242, 127, 165] +BUBBLE_CORAL_BLOCK: [127, 63, 178] +FIRE_CORAL_BLOCK: [153, 51, 51] +HORN_CORAL_BLOCK: [229, 229, 51] +TUBE_CORAL: [51, 76, 178] +BRAIN_CORAL: [242, 127, 165] +BUBBLE_CORAL: [127, 63, 178] +FIRE_CORAL: [153, 51, 51] +HORN_CORAL: [229, 229, 51] +DEAD_BRAIN_CORAL: [76, 76, 76] +DEAD_BUBBLE_CORAL: [76, 76, 76] +DEAD_FIRE_CORAL: [76, 76, 76] +DEAD_HORN_CORAL: [76, 76, 76] +DEAD_TUBE_CORAL: [76, 76, 76] +TUBE_CORAL_FAN: [51, 76, 178] +BRAIN_CORAL_FAN: [242, 127, 165] +BUBBLE_CORAL_FAN: [127, 63, 178] +FIRE_CORAL_FAN: [153, 51, 51] +HORN_CORAL_FAN: [229, 229, 51] +DEAD_TUBE_CORAL_FAN: [76, 76, 76] +DEAD_BRAIN_CORAL_FAN: [76, 76, 76] +DEAD_BUBBLE_CORAL_FAN: [76, 76, 76] +DEAD_FIRE_CORAL_FAN: [76, 76, 76] +DEAD_HORN_CORAL_FAN: [76, 76, 76] +BLUE_ICE: [160, 160, 255] +CONDUIT: [92, 219, 213] +POLISHED_GRANITE_STAIRS: [151, 109, 77] +SMOOTH_RED_SANDSTONE_STAIRS: [216, 127, 51] +MOSSY_STONE_BRICK_STAIRS: [112, 112, 112] +POLISHED_DIORITE_STAIRS: [255, 252, 245] +MOSSY_COBBLESTONE_STAIRS: [112, 112, 112] +END_STONE_BRICK_STAIRS: [247, 233, 163] +STONE_STAIRS: [112, 112, 112] +SMOOTH_SANDSTONE_STAIRS: [247, 233, 163] +SMOOTH_QUARTZ_STAIRS: [255, 252, 245] +GRANITE_STAIRS: [151, 109, 77] +ANDESITE_STAIRS: [112, 112, 112] +RED_NETHER_BRICK_STAIRS: [112, 2, 0] +POLISHED_ANDESITE_STAIRS: [112, 112, 112] +DIORITE_STAIRS: [255, 252, 245] +COBBLED_DEEPSLATE_STAIRS: [100, 100, 100] +POLISHED_DEEPSLATE_STAIRS: [100, 100, 100] +DEEPSLATE_BRICK_STAIRS: [100, 100, 100] +DEEPSLATE_TILE_STAIRS: [100, 100, 100] +POLISHED_GRANITE_SLAB: [151, 109, 77] +SMOOTH_RED_SANDSTONE_SLAB: [216, 127, 51] +MOSSY_STONE_BRICK_SLAB: [112, 112, 112] +POLISHED_DIORITE_SLAB: [255, 252, 245] +MOSSY_COBBLESTONE_SLAB: [112, 112, 112] +END_STONE_BRICK_SLAB: [247, 233, 163] +SMOOTH_SANDSTONE_SLAB: [247, 233, 163] +SMOOTH_QUARTZ_SLAB: [255, 252, 245] +GRANITE_SLAB: [151, 109, 77] +ANDESITE_SLAB: [112, 112, 112] +RED_NETHER_BRICK_SLAB: [112, 2, 0] +POLISHED_ANDESITE_SLAB: [112, 112, 112] +DIORITE_SLAB: [255, 252, 245] +COBBLED_DEEPSLATE_SLAB: [100, 100, 100] +POLISHED_DEEPSLATE_SLAB: [100, 100, 100] +DEEPSLATE_BRICK_SLAB: [100, 100, 100] +DEEPSLATE_TILE_SLAB: [100, 100, 100] +SCAFFOLDING: [247, 233, 163] +REDSTONE_TORCH: [0, 0, 0] +REDSTONE_BLOCK: [255, 0, 0] +REPEATER: [0, 0, 0] +COMPARATOR: [0, 0, 0] +PISTON: [112, 112, 112] +STICKY_PISTON: [112, 112, 112] +SLIME_BLOCK: [127, 178, 56] +HONEY_BLOCK: [216, 127, 51] +OBSERVER: [112, 112, 112] +HOPPER: [112, 112, 112] +DISPENSER: [112, 112, 112] +DROPPER: [112, 112, 112] +LECTERN: [143, 119, 72] +TARGET: [255, 252, 245] +LEVER: [0, 0, 0] +LIGHTNING_ROD: [216, 127, 51] +DAYLIGHT_DETECTOR: [143, 119, 72] +SCULK_SENSOR: [76, 127, 153] +TRIPWIRE_HOOK: [0, 0, 0] +TRAPPED_CHEST: [143, 119, 72] +TNT: [255, 0, 0] +REDSTONE_LAMP: [0, 0, 0] +NOTE_BLOCK: [143, 119, 72] +STONE_BUTTON: [0, 0, 0] +POLISHED_BLACKSTONE_BUTTON: [0, 0, 0] +OAK_BUTTON: [0, 0, 0] +SPRUCE_BUTTON: [0, 0, 0] +BIRCH_BUTTON: [0, 0, 0] +JUNGLE_BUTTON: [0, 0, 0] +ACACIA_BUTTON: [0, 0, 0] +DARK_OAK_BUTTON: [0, 0, 0] +CRIMSON_BUTTON: [0, 0, 0] +WARPED_BUTTON: [0, 0, 0] +STONE_PRESSURE_PLATE: [112, 112, 112] +POLISHED_BLACKSTONE_PRESSURE_PLATE: [25, 25, 25] +LIGHT_WEIGHTED_PRESSURE_PLATE: [250, 238, 77] +HEAVY_WEIGHTED_PRESSURE_PLATE: [167, 167, 167] +OAK_PRESSURE_PLATE: [143, 119, 72] +SPRUCE_PRESSURE_PLATE: [129, 86, 49] +BIRCH_PRESSURE_PLATE: [247, 233, 163] +JUNGLE_PRESSURE_PLATE: [151, 109, 77] +ACACIA_PRESSURE_PLATE: [216, 127, 51] +DARK_OAK_PRESSURE_PLATE: [102, 76, 51] +CRIMSON_PRESSURE_PLATE: [148, 63, 97] +WARPED_PRESSURE_PLATE: [58, 142, 140] +IRON_DOOR: [167, 167, 167] +OAK_DOOR: [143, 119, 72] +SPRUCE_DOOR: [129, 86, 49] +BIRCH_DOOR: [247, 233, 163] +JUNGLE_DOOR: [151, 109, 77] +ACACIA_DOOR: [216, 127, 51] +DARK_OAK_DOOR: [102, 76, 51] +CRIMSON_DOOR: [148, 63, 97] +WARPED_DOOR: [58, 142, 140] +IRON_TRAPDOOR: [167, 167, 167] +OAK_TRAPDOOR: [143, 119, 72] +SPRUCE_TRAPDOOR: [129, 86, 49] +BIRCH_TRAPDOOR: [247, 233, 163] +JUNGLE_TRAPDOOR: [151, 109, 77] +ACACIA_TRAPDOOR: [216, 127, 51] +DARK_OAK_TRAPDOOR: [102, 76, 51] +CRIMSON_TRAPDOOR: [148, 63, 97] +WARPED_TRAPDOOR: [58, 142, 140] +OAK_FENCE_GATE: [143, 119, 72] +SPRUCE_FENCE_GATE: [129, 86, 49] +BIRCH_FENCE_GATE: [247, 233, 163] +JUNGLE_FENCE_GATE: [151, 109, 77] +ACACIA_FENCE_GATE: [216, 127, 51] +DARK_OAK_FENCE_GATE: [102, 76, 51] +CRIMSON_FENCE_GATE: [148, 63, 97] +WARPED_FENCE_GATE: [58, 142, 140] +POWERED_RAIL: [0, 0, 0] +DETECTOR_RAIL: [0, 0, 0] +RAIL: [0, 0, 0] +ACTIVATOR_RAIL: [0, 0, 0] +STRUCTURE_BLOCK: [153, 153, 153] +JIGSAW: [153, 153, 153] +WHEAT: [0, 124, 0] +OAK_SIGN: [143, 119, 72] +SPRUCE_SIGN: [129, 86, 49] +BIRCH_SIGN: [247, 233, 163] +JUNGLE_SIGN: [151, 109, 77] +ACACIA_SIGN: [216, 127, 51] +DARK_OAK_SIGN: [102, 76, 51] +CRIMSON_SIGN: [148, 63, 97] +WARPED_SIGN: [58, 142, 140] +DRIED_KELP_BLOCK: [102, 127, 51] +CAKE: [0, 0, 0] +WHITE_BED: [255, 255, 255] +ORANGE_BED: [216, 127, 51] +MAGENTA_BED: [178, 76, 216] +LIGHT_BLUE_BED: [102, 153, 216] +YELLOW_BED: [229, 229, 51] +LIME_BED: [127, 204, 25] +PINK_BED: [242, 127, 165] +GRAY_BED: [76, 76, 76] +LIGHT_GRAY_BED: [153, 153, 153] +CYAN_BED: [76, 127, 153] +PURPLE_BED: [127, 63, 178] +BLUE_BED: [51, 76, 178] +BROWN_BED: [102, 76, 51] +GREEN_BED: [102, 127, 51] +RED_BED: [153, 51, 51] +BLACK_BED: [25, 25, 25] +NETHER_WART: [153, 51, 51] +BREWING_STAND: [167, 167, 167] +CAULDRON: [112, 112, 112] +FLOWER_POT: [0, 0, 0] +SKELETON_SKULL: [0, 0, 0] +WITHER_SKELETON_SKULL: [0, 0, 0] +PLAYER_HEAD: [0, 0, 0] +ZOMBIE_HEAD: [0, 0, 0] +CREEPER_HEAD: [0, 0, 0] +DRAGON_HEAD: [0, 0, 0] +WHITE_BANNER: [143, 119, 72] +ORANGE_BANNER: [143, 119, 72] +MAGENTA_BANNER: [143, 119, 72] +LIGHT_BLUE_BANNER: [143, 119, 72] +YELLOW_BANNER: [143, 119, 72] +LIME_BANNER: [143, 119, 72] +PINK_BANNER: [143, 119, 72] +GRAY_BANNER: [143, 119, 72] +LIGHT_GRAY_BANNER: [143, 119, 72] +CYAN_BANNER: [143, 119, 72] +PURPLE_BANNER: [143, 119, 72] +BLUE_BANNER: [143, 119, 72] +BROWN_BANNER: [143, 119, 72] +GREEN_BANNER: [143, 119, 72] +RED_BANNER: [143, 119, 72] +BLACK_BANNER: [143, 119, 72] +LOOM: [143, 119, 72] +COMPOSTER: [143, 119, 72] +BARREL: [143, 119, 72] +SMOKER: [112, 112, 112] +BLAST_FURNACE: [112, 112, 112] +CARTOGRAPHY_TABLE: [143, 119, 72] +FLETCHING_TABLE: [143, 119, 72] +GRINDSTONE: [167, 167, 167] +SMITHING_TABLE: [143, 119, 72] +STONECUTTER: [112, 112, 112] +BELL: [250, 238, 77] +LANTERN: [167, 167, 167] +SOUL_LANTERN: [167, 167, 167] +CAMPFIRE: [129, 86, 49] +SOUL_CAMPFIRE: [129, 86, 49] +SHROOMLIGHT: [153, 51, 51] +BEE_NEST: [229, 229, 51] +BEEHIVE: [143, 119, 72] +HONEYCOMB_BLOCK: [216, 127, 51] +LODESTONE: [167, 167, 167] +CRYING_OBSIDIAN: [25, 25, 25] +BLACKSTONE: [25, 25, 25] +BLACKSTONE_SLAB: [25, 25, 25] +BLACKSTONE_STAIRS: [25, 25, 25] +GILDED_BLACKSTONE: [25, 25, 25] +POLISHED_BLACKSTONE: [25, 25, 25] +POLISHED_BLACKSTONE_SLAB: [25, 25, 25] +POLISHED_BLACKSTONE_STAIRS: [25, 25, 25] +CHISELED_POLISHED_BLACKSTONE: [25, 25, 25] +POLISHED_BLACKSTONE_BRICKS: [25, 25, 25] +POLISHED_BLACKSTONE_BRICK_SLAB: [25, 25, 25] +POLISHED_BLACKSTONE_BRICK_STAIRS: [25, 25, 25] +CRACKED_POLISHED_BLACKSTONE_BRICKS: [25, 25, 25] +RESPAWN_ANCHOR: [25, 25, 25] +CANDLE: [247, 233, 163] +WHITE_CANDLE: [199, 199, 199] +ORANGE_CANDLE: [216, 127, 51] +MAGENTA_CANDLE: [178, 76, 216] +LIGHT_BLUE_CANDLE: [102, 153, 216] +YELLOW_CANDLE: [229, 229, 51] +LIME_CANDLE: [127, 204, 25] +PINK_CANDLE: [242, 127, 165] +GRAY_CANDLE: [76, 76, 76] +LIGHT_GRAY_CANDLE: [153, 153, 153] +CYAN_CANDLE: [76, 127, 153] +PURPLE_CANDLE: [127, 63, 178] +BLUE_CANDLE: [51, 76, 178] +BROWN_CANDLE: [102, 76, 51] +GREEN_CANDLE: [102, 127, 51] +RED_CANDLE: [153, 51, 51] +BLACK_CANDLE: [25, 25, 25] +SMALL_AMETHYST_BUD: [127, 63, 178] +MEDIUM_AMETHYST_BUD: [127, 63, 178] +LARGE_AMETHYST_BUD: [127, 63, 178] +AMETHYST_CLUSTER: [127, 63, 178] +POINTED_DRIPSTONE: [76, 50, 35] +WATER: [64, 64, 255] +LAVA: [255, 0, 0] +TALL_SEAGRASS: [64, 64, 255] +PISTON_HEAD: [112, 112, 112] +MOVING_PISTON: [112, 112, 112] +WALL_TORCH: [0, 0, 0] +FIRE: [255, 0, 0] +SOUL_FIRE: [0, 0, 0] +REDSTONE_WIRE: [0, 0, 0] +OAK_WALL_SIGN: [143, 119, 72] +SPRUCE_WALL_SIGN: [129, 86, 49] +BIRCH_WALL_SIGN: [247, 233, 163] +ACACIA_WALL_SIGN: [216, 127, 51] +JUNGLE_WALL_SIGN: [151, 109, 77] +DARK_OAK_WALL_SIGN: [102, 76, 51] +REDSTONE_WALL_TORCH: [0, 0, 0] +SOUL_WALL_TORCH: [0, 0, 0] +NETHER_PORTAL: [0, 0, 0] +ATTACHED_PUMPKIN_STEM: [0, 124, 0] +ATTACHED_MELON_STEM: [0, 124, 0] +PUMPKIN_STEM: [0, 124, 0] +MELON_STEM: [0, 124, 0] +WATER_CAULDRON: [112, 112, 112] +LAVA_CAULDRON: [112, 112, 112] +POWDER_SNOW_CAULDRON: [112, 112, 112] +END_PORTAL: [25, 25, 25] +COCOA: [0, 124, 0] +TRIPWIRE: [0, 0, 0] +POTTED_OAK_SAPLING: [0, 0, 0] +POTTED_SPRUCE_SAPLING: [0, 0, 0] +POTTED_BIRCH_SAPLING: [0, 0, 0] +POTTED_JUNGLE_SAPLING: [0, 0, 0] +POTTED_ACACIA_SAPLING: [0, 0, 0] +POTTED_DARK_OAK_SAPLING: [0, 0, 0] +POTTED_FERN: [0, 0, 0] +POTTED_DANDELION: [0, 0, 0] +POTTED_POPPY: [0, 0, 0] +POTTED_BLUE_ORCHID: [0, 0, 0] +POTTED_ALLIUM: [0, 0, 0] +POTTED_AZURE_BLUET: [0, 0, 0] +POTTED_RED_TULIP: [0, 0, 0] +POTTED_ORANGE_TULIP: [0, 0, 0] +POTTED_WHITE_TULIP: [0, 0, 0] +POTTED_PINK_TULIP: [0, 0, 0] +POTTED_OXEYE_DAISY: [0, 0, 0] +POTTED_CORNFLOWER: [0, 0, 0] +POTTED_LILY_OF_THE_VALLEY: [0, 0, 0] +POTTED_WITHER_ROSE: [0, 0, 0] +POTTED_RED_MUSHROOM: [0, 0, 0] +POTTED_BROWN_MUSHROOM: [0, 0, 0] +POTTED_DEAD_BUSH: [0, 0, 0] +POTTED_CACTUS: [0, 0, 0] +CARROTS: [0, 124, 0] +POTATOES: [0, 124, 0] +SKELETON_WALL_SKULL: [0, 0, 0] +WITHER_SKELETON_WALL_SKULL: [0, 0, 0] +ZOMBIE_WALL_HEAD: [0, 0, 0] +PLAYER_WALL_HEAD: [0, 0, 0] +CREEPER_WALL_HEAD: [0, 0, 0] +DRAGON_WALL_HEAD: [0, 0, 0] +WHITE_WALL_BANNER: [143, 119, 72] +ORANGE_WALL_BANNER: [143, 119, 72] +MAGENTA_WALL_BANNER: [143, 119, 72] +LIGHT_BLUE_WALL_BANNER: [143, 119, 72] +YELLOW_WALL_BANNER: [143, 119, 72] +LIME_WALL_BANNER: [143, 119, 72] +PINK_WALL_BANNER: [143, 119, 72] +GRAY_WALL_BANNER: [143, 119, 72] +LIGHT_GRAY_WALL_BANNER: [143, 119, 72] +CYAN_WALL_BANNER: [143, 119, 72] +PURPLE_WALL_BANNER: [143, 119, 72] +BLUE_WALL_BANNER: [143, 119, 72] +BROWN_WALL_BANNER: [143, 119, 72] +GREEN_WALL_BANNER: [143, 119, 72] +RED_WALL_BANNER: [143, 119, 72] +BLACK_WALL_BANNER: [143, 119, 72] +BEETROOTS: [0, 124, 0] +END_GATEWAY: [25, 25, 25] +FROSTED_ICE: [160, 160, 255] +KELP_PLANT: [64, 64, 255] +DEAD_TUBE_CORAL_WALL_FAN: [76, 76, 76] +DEAD_BRAIN_CORAL_WALL_FAN: [76, 76, 76] +DEAD_BUBBLE_CORAL_WALL_FAN: [76, 76, 76] +DEAD_FIRE_CORAL_WALL_FAN: [76, 76, 76] +DEAD_HORN_CORAL_WALL_FAN: [76, 76, 76] +TUBE_CORAL_WALL_FAN: [51, 76, 178] +BRAIN_CORAL_WALL_FAN: [242, 127, 165] +BUBBLE_CORAL_WALL_FAN: [127, 63, 178] +FIRE_CORAL_WALL_FAN: [153, 51, 51] +HORN_CORAL_WALL_FAN: [229, 229, 51] +BAMBOO_SAPLING: [143, 119, 72] +POTTED_BAMBOO: [0, 0, 0] +VOID_AIR: [0, 0, 0] +CAVE_AIR: [0, 0, 0] +BUBBLE_COLUMN: [64, 64, 255] +SWEET_BERRY_BUSH: [0, 124, 0] +WEEPING_VINES_PLANT: [112, 2, 0] +TWISTING_VINES_PLANT: [76, 127, 153] +CRIMSON_WALL_SIGN: [148, 63, 97] +WARPED_WALL_SIGN: [58, 142, 140] +POTTED_CRIMSON_FUNGUS: [0, 0, 0] +POTTED_WARPED_FUNGUS: [0, 0, 0] +POTTED_CRIMSON_ROOTS: [0, 0, 0] +POTTED_WARPED_ROOTS: [0, 0, 0] +CANDLE_CAKE: [0, 0, 0] +WHITE_CANDLE_CAKE: [0, 0, 0] +ORANGE_CANDLE_CAKE: [0, 0, 0] +MAGENTA_CANDLE_CAKE: [0, 0, 0] +LIGHT_BLUE_CANDLE_CAKE: [0, 0, 0] +YELLOW_CANDLE_CAKE: [0, 0, 0] +LIME_CANDLE_CAKE: [0, 0, 0] +PINK_CANDLE_CAKE: [0, 0, 0] +GRAY_CANDLE_CAKE: [0, 0, 0] +LIGHT_GRAY_CANDLE_CAKE: [0, 0, 0] +CYAN_CANDLE_CAKE: [0, 0, 0] +PURPLE_CANDLE_CAKE: [0, 0, 0] +BLUE_CANDLE_CAKE: [0, 0, 0] +BROWN_CANDLE_CAKE: [0, 0, 0] +GREEN_CANDLE_CAKE: [0, 0, 0] +RED_CANDLE_CAKE: [0, 0, 0] +BLACK_CANDLE_CAKE: [0, 0, 0] +POWDER_SNOW: [255, 255, 255] +CAVE_VINES: [0, 124, 0] +CAVE_VINES_PLANT: [0, 124, 0] +BIG_DRIPLEAF_STEM: [0, 124, 0] +POTTED_AZALEA_BUSH: [0, 0, 0] +POTTED_FLOWERING_AZALEA_BUSH: [0, 0, 0] \ No newline at end of file