-
Notifications
You must be signed in to change notification settings - Fork 4
Add Splinter #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
cpaca
wants to merge
57
commits into
TraceLTRC:master
Choose a base branch
from
cpaca:Splinter
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Add Splinter #30
Changes from 34 commits
Commits
Show all changes
57 commits
Select commit
Hold shift + click to select a range
8852047
Create SplinterBook
cpaca 3e9d9ed
Create Splinter.java
cpaca 48d3bd1
Add Splinter to EnchantmentManager
cpaca cc62ac6
Add validity checker
cpaca f80031a
Implement the bulk of Splinter
cpaca b44319d
Make splinter charge its own function
cpaca 8edc9e0
Implement addAdjacentBlocks
cpaca fbc149a
There's no way a wildcard import is needed there.
cpaca 974c8b6
Add book to CollectionManager
cpaca ee2889c
Bugfixes
cpaca c1bab3e
Stop Splinter from changing materials
cpaca 883a8a4
Update src/main/java/xyz/holocons/mc/holoitemsrevamp/enchantment/Spli…
cpaca 02f3418
Split splinter validation for location and type.
cpaca 19cc7a1
semicolon
cpaca 14e7a10
Basic refactor of Splinter
cpaca 22443ce
Reorganize splinter veinmine-one-block
cpaca 2319b75
This is pre-checked already
cpaca e77dd1d
Remove unused variable
cpaca 96cecca
dumb inversion error
cpaca 35a04b9
Make splinter break multiple blocks per tick
cpaca 78d6f05
Start of splinter v2
cpaca 4f67107
Update src/main/java/xyz/holocons/mc/holoitemsrevamp/enchantment/Spli…
cpaca 5dbafd9
Update src/main/java/xyz/holocons/mc/holoitemsrevamp/enchantment/Spli…
cpaca 884a8a1
Fix non-compile bug
cpaca 679ea87
Separate into is-shroom and is-log checks
cpaca fe66194
Wrong mushroom type check
cpaca a212ecc
Add isTrunkBlock function
cpaca 8241e2f
Implement getPossibleBranches
cpaca 835ce96
Trunks shouldn't return theirself
cpaca c514425
Implement getLegalNextMaterials
cpaca 257bf7c
Implement scheduleSplinterAbility
cpaca d499b16
Fix tryCleanupSplinterData using new function
cpaca 2cb8e2d
Finish up onBlockBreak
cpaca 84f59d9
Forgot shroom branches also go downwards
cpaca 87b8a39
Begin rework
dlee13 bd562cd
Pre-increment and pre-decrement
dlee13 57e0166
Avoid storing player objects
dlee13 a1880e5
Merge branch 'master' into Splinter
cpaca f6c8446
Fix logic for removing context
dlee13 acc138a
Merge branch 'Splinter' of https://github.com/cpaca/HoloItems into Sp…
dlee13 aece464
Add missing check
dlee13 d11f42e
Add null check for player
cpaca 8c7320d
Move null check
dlee13 067f589
Merge branch 'master' into Splinter
dlee13 c505c98
Remove comment
dlee13 3ceadc8
Implement search for mushroom stem and brown mushroom block
dlee13 2fc8a42
Implement search for red mushroom block
dlee13 735a263
Merge branch 'master' into Splinter
dlee13 e58d635
Fix Splinter stopping too early
dlee13 97bcc55
Add special case splinter types
dlee13 382d9b5
Implement cherry
dlee13 c5b8e18
Implement acacia
dlee13 417cca1
Implement generic branch
dlee13 843ea78
Fix edge case for oak
dlee13 5c6b90a
Fix typo
dlee13 4b3e9fb
Merge branch 'master' into Splinter
dlee13 c42929e
Begin to implement mangrove
dlee13 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
290 changes: 290 additions & 0 deletions
290
src/main/java/xyz/holocons/mc/holoitemsrevamp/enchantment/Splinter.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,290 @@ | ||
| package xyz.holocons.mc.holoitemsrevamp.enchantment; | ||
|
|
||
| import com.destroystokyo.paper.MaterialSetTag; | ||
| import com.destroystokyo.paper.MaterialTags; | ||
| import com.strangeone101.holoitemsapi.enchantment.CustomEnchantment; | ||
| import com.strangeone101.holoitemsapi.enchantment.EnchantmentAbility; | ||
| import net.kyori.adventure.text.Component; | ||
| import net.kyori.adventure.text.format.NamedTextColor; | ||
| import net.kyori.adventure.text.format.TextDecoration; | ||
| import org.bukkit.*; | ||
| import org.bukkit.block.Block; | ||
| import org.bukkit.block.data.BlockData; | ||
| import org.bukkit.block.data.Orientable; | ||
| import org.bukkit.enchantments.Enchantment; | ||
| import org.bukkit.entity.Player; | ||
| import org.bukkit.event.block.BlockBreakEvent; | ||
| import org.bukkit.inventory.ItemStack; | ||
| import org.bukkit.scheduler.BukkitRunnable; | ||
| import org.jetbrains.annotations.NotNull; | ||
| import xyz.holocons.mc.holoitemsrevamp.HoloItemsRevamp; | ||
| import xyz.holocons.mc.holoitemsrevamp.integration.Integrations; | ||
|
|
||
| import java.util.*; | ||
|
|
||
| public class Splinter extends CustomEnchantment implements EnchantmentAbility { | ||
|
|
||
| private final HoloItemsRevamp plugin; | ||
|
|
||
| private final MaterialSetTag COMPATIBLE_MATERIALS; | ||
|
|
||
| private static final Map<Player, ActiveSplinter> splinters = new HashMap<>(); | ||
|
|
||
| public Splinter(HoloItemsRevamp plugin){ | ||
| super(plugin, "splinter"); | ||
| this.plugin = plugin; | ||
| var materialSetTagKey = new NamespacedKey(plugin, "splinter_materials"); | ||
| this.COMPATIBLE_MATERIALS = new MaterialSetTag(materialSetTagKey, this::isCompatibleMaterial).lock(); | ||
| } | ||
|
|
||
| @Override | ||
| public int getMaxLevel() { | ||
| return 1; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean conflictsWith(@NotNull Enchantment enchantment) { | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean canEnchantItem(@NotNull ItemStack itemStack) { | ||
| return MaterialTags.AXES.isTagged(itemStack); | ||
| } | ||
|
|
||
| @Override | ||
| public @NotNull Component displayName(int i) { | ||
| return Component.text() | ||
| .color(NamedTextColor.GRAY) | ||
| .decoration(TextDecoration.ITALIC, false) | ||
| .append(Component.text("Splinter")) | ||
| .build(); | ||
| } | ||
|
|
||
| @Override | ||
| public int getCostMultiplier() { | ||
| return 12; | ||
| } | ||
|
|
||
| @Override | ||
| public void onBlockBreak(BlockBreakEvent event, ItemStack itemStack) { | ||
| Block blockBroken = event.getBlock(); | ||
| if(isInvalidSplinterType(blockBroken.getType()) || isInvalidSplinterLocation(blockBroken.getLocation())){ | ||
| return; | ||
| } | ||
| // Presuming the block is a log - ie, it has an orientation. | ||
| var player = event.getPlayer(); | ||
| tryCleanupSplinterData(player, blockBroken); | ||
|
|
||
| boolean isTree = isLogBlock(blockBroken.getType()); | ||
| boolean isShroom = isShroomBlock(blockBroken.getType()); | ||
| boolean isTrunk = isTrunkBlock(blockBroken); | ||
| if(isTree && isTrunk){ | ||
| handleTreeTrunkBroken(player, blockBroken); | ||
| } | ||
| else if(isTree){ | ||
| // && !isTrunk | ||
| // aka && isBranch | ||
| handleTreeBranchBroken(player, blockBroken); | ||
| } | ||
| else if(isShroom && isTrunk){ | ||
| handleShroomStemBroken(player, blockBroken); | ||
| } | ||
| else if(isShroom){ | ||
| // && !isTrunk | ||
| // aka && isBranch | ||
| handleShroomBlockBroken(player, blockBroken); | ||
| } | ||
| // else{} here shouldnt be reachable since anything else would be an invalid splinter type | ||
| } | ||
|
|
||
| /** | ||
| * Try to cleanup a player's Splinter data. If the data is scheduled for cleanup, but the newTrunk isn't a valid | ||
| * new trunk block, it will delete the data from the map entirely. | ||
| * @param player The player's | ||
| * @param newTrunk The proposed new trunk block | ||
| */ | ||
| private void tryCleanupSplinterData(Player player, Block newTrunk){ | ||
| final var activeSplinter = splinters.get(player); | ||
| // if(!shouldCleanup) | ||
| if(activeSplinter != null && activeSplinter.scheduledSplinters != 0){ | ||
| // there is still a splinter going, so don't cleanup until that one's done | ||
| return; | ||
| } | ||
|
|
||
| splinters.remove(player); | ||
|
|
||
| if(!isTrunkBlock(newTrunk)){ | ||
| return; | ||
| } | ||
|
|
||
| ActiveSplinter newData = new ActiveSplinter(); | ||
| newData.origin = newTrunk; | ||
| newData.remainingCharges = 32; // In the future we can make this based on enchLevel | ||
| newData.scheduledSplinters = 0; | ||
| splinters.put(player, newData); | ||
| } | ||
|
|
||
| private void handleTreeTrunkBroken(Player player, Block trunkBlock){ | ||
| // TODO | ||
| } | ||
|
|
||
| private void handleTreeBranchBroken(Player player, Block branchBlock){ | ||
| // TODO | ||
| } | ||
|
|
||
| private void handleShroomStemBroken(Player player, Block stemBlock){ | ||
| // aka the shroom stem | ||
| // TODO | ||
| } | ||
|
|
||
| private void handleShroomBlockBroken(Player player, Block branchBlock){ | ||
| // TODO | ||
| } | ||
|
|
||
| private void scheduleSplinterAbility(Player player, Block block) { | ||
| var data = splinters.get(player); | ||
| if(data.remainingCharges <= 0){ | ||
| // No power left to schedule anything. | ||
| return; | ||
| } | ||
| int splinterDelay = data.scheduledSplinters; | ||
| // Update and save data | ||
| data.remainingCharges -= 1; | ||
| data.scheduledSplinters += 1; | ||
| splinters.put(player, data); | ||
|
|
||
| // Schedule a splinter | ||
| new BukkitRunnable(){ | ||
| @Override | ||
| public void run() { | ||
| // Break the block | ||
| // TODO: Check if the player is holding a Splinter axe first. | ||
| // I got the itemStack to check for splinter, but idk how to check for splinter. | ||
| var activeItem = player.getActiveItem(); | ||
| player.breakBlock(block); | ||
|
|
||
| // ... then update the data. | ||
| var updatedData = splinters.get(player); | ||
| updatedData.scheduledSplinters -= 1; | ||
| splinters.put(player, updatedData); | ||
| } | ||
| }.runTaskLater(plugin, splinterDelay); | ||
| } | ||
|
|
||
| /** | ||
| * Gets the potential next-branch blocks from this starting branch block. The trunk block is used since branches | ||
| * don't "curl in" on theirself, they continue to go farther from the trunk. If the branch is actually part | ||
| * of the trunk, all 8 adjacent blocks plus the 8 additional branches are returned. | ||
| */ | ||
| private List<Block> getPossibleBranches(Block trunk, Block branch){ | ||
| // Since the main operations afaik will be append and iterator, this is slightly better than arraylist. | ||
| // Not by much. | ||
| List<Block> ret = new LinkedList<>(); | ||
|
|
||
| int deltaX = branch.getX() - trunk.getX(); | ||
| int deltaZ = branch.getZ() - trunk.getZ(); | ||
|
|
||
| int[] relXs = getRelsToCheck(deltaX); | ||
| int[] relZs = getRelsToCheck(deltaZ); | ||
|
|
||
| boolean isShroom = isShroomBlock(branch.getType()); | ||
|
|
||
| for(int relX : relXs){ | ||
| for(int relZ : relZs){ | ||
| if(relX == 0 && relZ == 0){ | ||
| continue; | ||
| } | ||
| if(isShroom){ | ||
| // Remember shroom branches also go downwards | ||
| ret.add(branch.getRelative(relX, -1, relZ)); | ||
| } | ||
| ret.add(branch.getRelative(relX, 0, relZ)); | ||
| ret.add(branch.getRelative(relX, 1, relZ)); | ||
| } | ||
| } | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
| private int[] getRelsToCheck(int delta){ | ||
| // "Get relatives to check" | ||
| if(delta > 0){ | ||
| return new int[]{1}; | ||
| } | ||
| else if(delta < 0){ | ||
| return new int[]{-1}; | ||
| } | ||
| else{ | ||
| // start == 0 | ||
| return new int[]{-1, 0, 1}; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * In summary: Log-splinters should only continue with other log-splinters, but shroom-splinters should be able | ||
| * to move from stem to mushroom block. (That said, mushroom block shouldn't be able to move back to stem.) | ||
| * Note: This will also return an empty list (aka "no legal next material") if the baseMaterial is not a legal | ||
| * splinter material. | ||
| */ | ||
| private List<Material> getLegalNextMaterials(Block block){ | ||
| List<Material> ret = new LinkedList<>(); | ||
| if(isLogBlock(block.getType())){ | ||
| ret.add(block.getType()); | ||
| } | ||
| else if(isShroomBlock(block.getType())){ | ||
| ret.add(block.getType()); | ||
| if(isTrunkBlock(block)){ | ||
| // shroom trunks (aka stems) should also be able to go to shroom leaves (aka mushroom blocks) | ||
| ret.add(Material.RED_MUSHROOM_BLOCK); | ||
| ret.add(Material.BROWN_MUSHROOM_BLOCK); | ||
| } | ||
| } | ||
| // else: return empty list, aka unchanged | ||
| return ret; | ||
| } | ||
|
|
||
| private boolean isInvalidSplinterType(Material type) { | ||
| return !this.COMPATIBLE_MATERIALS.isTagged(type); | ||
| } | ||
|
|
||
| private boolean isInvalidSplinterLocation(Location loc){ | ||
| return !Integrations.WORLDGUARD.canUseEnchantment(loc, Splinter.class); | ||
| } | ||
|
|
||
| private boolean isCompatibleMaterial(Material material) { | ||
| return isLogBlock(material) || isShroomBlock(material); | ||
| } | ||
|
|
||
| private boolean isLogBlock(Material material){ | ||
| // Remember later: All log-blocks are orientable. (shrooms are compatible-material but not orientable.) | ||
| return Tag.LOGS.isTagged(material); | ||
| } | ||
|
|
||
| private boolean isShroomBlock(Material material){ | ||
| return MaterialTags.MUSHROOM_BLOCKS.isTagged(material); | ||
| } | ||
|
|
||
| private boolean isTrunkBlock(Block block){ | ||
| var material = block.getType(); | ||
| if(isLogBlock(material)){ | ||
| if(block.getBlockData() instanceof Orientable orientable){ | ||
| return orientable.getAxis() == Axis.Y; | ||
| } | ||
| // non-orientable log shouldn't be possible, but just in case: | ||
| return false; | ||
| } | ||
| else if(isShroomBlock(material)){ | ||
| return Material.MUSHROOM_STEM == material; | ||
| } | ||
| else{ | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| private static class ActiveSplinter { | ||
| Block origin; | ||
| int remainingCharges; | ||
| int scheduledSplinters; | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.