mirror of
https://github.com/songoda/UltimateTimber.git
synced 2025-02-27 09:01:29 +01:00
Hook tree loot double drops fix, placed block detection
This commit is contained in:
parent
a5b8fab267
commit
4b35f0ee4e
@ -8,6 +8,7 @@ import com.songoda.ultimatetimber.manager.CommandManager;
|
||||
import com.songoda.ultimatetimber.manager.ConfigurationManager;
|
||||
import com.songoda.ultimatetimber.manager.HookManager;
|
||||
import com.songoda.ultimatetimber.manager.Manager;
|
||||
import com.songoda.ultimatetimber.manager.PlacedBlockManager;
|
||||
import com.songoda.ultimatetimber.manager.SaplingManager;
|
||||
import com.songoda.ultimatetimber.manager.TreeAnimationManager;
|
||||
import com.songoda.ultimatetimber.manager.TreeDefinitionManager;
|
||||
@ -40,6 +41,7 @@ public class UltimateTimber extends JavaPlugin {
|
||||
private CommandManager commandManager;
|
||||
private ConfigurationManager configurationManager;
|
||||
private HookManager hookManager;
|
||||
private PlacedBlockManager placedBlockManager;
|
||||
private SaplingManager saplingManager;
|
||||
private TreeAnimationManager treeAnimationManager;
|
||||
private TreeDefinitionManager treeDefinitionManager;
|
||||
@ -63,6 +65,7 @@ public class UltimateTimber extends JavaPlugin {
|
||||
this.commandManager = this.registerManager(CommandManager.class);
|
||||
this.configurationManager = new ConfigurationManager(this);
|
||||
this.hookManager = this.registerManager(HookManager.class);
|
||||
this.placedBlockManager = this.registerManager(PlacedBlockManager.class);
|
||||
this.saplingManager = this.registerManager(SaplingManager.class);
|
||||
this.treeAnimationManager = this.registerManager(TreeAnimationManager.class);
|
||||
this.treeDefinitionManager = this.registerManager(TreeDefinitionManager.class);
|
||||
@ -187,6 +190,15 @@ public class UltimateTimber extends JavaPlugin {
|
||||
return this.hookManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the placed block manager
|
||||
*
|
||||
* @return The PlacedBlockManager instance
|
||||
*/
|
||||
public PlacedBlockManager getPlacedBlockManager() {
|
||||
return this.placedBlockManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sapling manager
|
||||
*
|
||||
|
@ -9,8 +9,10 @@ import com.songoda.ultimatetimber.tree.ITreeBlock;
|
||||
import com.songoda.ultimatetimber.tree.TreeBlock;
|
||||
import com.songoda.ultimatetimber.tree.TreeDefinition;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -60,6 +62,11 @@ public class TreeAnimationDisintegrate extends TreeAnimation {
|
||||
}
|
||||
}
|
||||
|
||||
for (ITreeBlock<FallingBlock> fallingTreeBlock : TreeAnimationDisintegrate.this.fallingTreeBlocks.getAllTreeBlocks()) {
|
||||
FallingBlock fallingBlock = fallingTreeBlock.getBlock();
|
||||
fallingBlock.setVelocity(fallingBlock.getVelocity().clone().subtract(new Vector(0, 0.05, 0)));
|
||||
}
|
||||
|
||||
if (!toDestroy.isEmpty()) {
|
||||
ITreeBlock<Block> first = toDestroy.get(0);
|
||||
if (useCustomSound)
|
||||
|
@ -36,12 +36,13 @@ public class ConfigurationManager extends Manager {
|
||||
USE_CUSTOM_SOUNDS(SettingType.BOOLEAN),
|
||||
USE_CUSTOM_PARTICLES(SettingType.BOOLEAN),
|
||||
BONUS_LOOT_MULTIPLIER(SettingType.DOUBLE),
|
||||
IGNORE_PLACED_BLOCKS(SettingType.BOOLEAN),
|
||||
IGNORE_PLACED_BLOCKS_MEMORY_SIZE(SettingType.INT),
|
||||
HOOKS_APPLY_EXPERIENCE(SettingType.BOOLEAN),
|
||||
HOOKS_APPLY_EXTRA_DROPS(SettingType.BOOLEAN),
|
||||
HOOKS_REQUIRE_ABILITY_ACTIVE(SettingType.BOOLEAN),
|
||||
TREE_ANIMATION_TYPE(SettingType.STRING),
|
||||
SCATTER_TREE_BLOCKS_ON_GROUND(SettingType.BOOLEAN),
|
||||
MIX_ALL_TREE_TYPES(SettingType.BOOLEAN);
|
||||
SCATTER_TREE_BLOCKS_ON_GROUND(SettingType.BOOLEAN);
|
||||
|
||||
private SettingType settingType;
|
||||
private Object value = null;
|
||||
|
@ -0,0 +1,124 @@
|
||||
package com.songoda.ultimatetimber.manager;
|
||||
|
||||
import com.songoda.ultimatetimber.UltimateTimber;
|
||||
import com.songoda.ultimatetimber.adapter.IBlockData;
|
||||
import com.songoda.ultimatetimber.events.TreeFellEvent;
|
||||
import com.songoda.ultimatetimber.tree.ITreeBlock;
|
||||
import com.songoda.ultimatetimber.tree.TreeBlockType;
|
||||
import com.songoda.ultimatetimber.tree.TreeDefinition;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.LeavesDecayEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class PlacedBlockManager extends Manager implements Listener {
|
||||
|
||||
private List<Location> placedBlocks;
|
||||
private boolean ignorePlacedBlocks;
|
||||
private int maxPlacedBlockMemorySize;
|
||||
|
||||
public PlacedBlockManager(UltimateTimber ultimateTimber) {
|
||||
super(ultimateTimber);
|
||||
this.placedBlocks = new ArrayList<>();
|
||||
this.ignorePlacedBlocks = true;
|
||||
this.maxPlacedBlockMemorySize = 10000;
|
||||
Bukkit.getPluginManager().registerEvents(this, ultimateTimber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
this.placedBlocks.clear();
|
||||
this.ignorePlacedBlocks = ConfigurationManager.Setting.IGNORE_PLACED_BLOCKS.getBoolean();
|
||||
this.maxPlacedBlockMemorySize = ConfigurationManager.Setting.IGNORE_PLACED_BLOCKS_MEMORY_SIZE.getInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
this.placedBlocks.clear();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onBlockPlaced(BlockPlaceEvent event) {
|
||||
if (!this.ignorePlacedBlocks)
|
||||
return;
|
||||
|
||||
this.internalProtect(event.getBlock(), true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if (!this.ignorePlacedBlocks)
|
||||
return;
|
||||
|
||||
this.internalProtect(event.getBlock(), false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onLeafDecay(LeavesDecayEvent event) {
|
||||
if (!this.ignorePlacedBlocks)
|
||||
return;
|
||||
|
||||
this.internalProtect(event.getBlock(), false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onStructureGrow(StructureGrowEvent event) {
|
||||
if (!this.ignorePlacedBlocks)
|
||||
return;
|
||||
|
||||
for (BlockState blockState : event.getBlocks())
|
||||
this.internalProtect(blockState.getBlock(), false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onTreeFell(TreeFellEvent event) {
|
||||
if (!this.ignorePlacedBlocks)
|
||||
return;
|
||||
|
||||
for (ITreeBlock<Block> treeBlock : event.getDetectedTree().getDetectedTreeBlocks().getAllTreeBlocks())
|
||||
this.internalProtect(treeBlock.getBlock(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles when a block is placed/broken
|
||||
*/
|
||||
private void internalProtect(Block block, boolean isPlaced) {
|
||||
if (isPlaced) {
|
||||
if (this.isBlockPlaced(block))
|
||||
return;
|
||||
|
||||
this.placedBlocks.add(block.getLocation());
|
||||
if (this.placedBlocks.size() > this.maxPlacedBlockMemorySize)
|
||||
this.placedBlocks.remove(0);
|
||||
} else {
|
||||
this.placedBlocks.remove(block.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if a block is placed
|
||||
*
|
||||
* @param block The Block to check
|
||||
* @return True if the block is placed, otherwise false
|
||||
*/
|
||||
public boolean isBlockPlaced(Block block) {
|
||||
return this.placedBlocks.contains(block.getLocation());
|
||||
}
|
||||
|
||||
}
|
@ -15,7 +15,9 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
@ -221,11 +223,11 @@ public class TreeDefinitionManager extends Manager {
|
||||
|
||||
boolean addToInventory = ConfigurationManager.Setting.ADD_ITEMS_TO_INVENTORY.getBoolean();
|
||||
boolean hasBonusChance = player.hasPermission("ultimatetimber.bonusloot");
|
||||
Set<ItemStack> lootedItems = new HashSet<>();
|
||||
Set<String> lootedCommands = new HashSet<>();
|
||||
List<ItemStack> lootedItems = new ArrayList<>();
|
||||
List<String> lootedCommands = new ArrayList<>();
|
||||
|
||||
// Get the loot that we should try to drop
|
||||
Set<TreeLoot> toTry = new HashSet<>();
|
||||
List<TreeLoot> toTry = new ArrayList<>();
|
||||
if (hasSilkTouch) {
|
||||
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
|
||||
} else {
|
||||
@ -233,14 +235,20 @@ public class TreeDefinitionManager extends Manager {
|
||||
case LOG:
|
||||
toTry.addAll(treeDefinition.getLogLoot());
|
||||
toTry.addAll(this.globalLogLoot);
|
||||
if (treeDefinition.shouldDropOriginalLog())
|
||||
if (treeDefinition.shouldDropOriginalLog()) {
|
||||
if (hookManager.shouldApplyDoubleDropsHooks(player))
|
||||
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
|
||||
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
|
||||
}
|
||||
break;
|
||||
case LEAF:
|
||||
toTry.addAll(treeDefinition.getLeafLoot());
|
||||
toTry.addAll(this.globalLeafLoot);
|
||||
if (treeDefinition.shouldDropOriginalLeaf())
|
||||
if (treeDefinition.shouldDropOriginalLeaf()) {
|
||||
if (hookManager.shouldApplyDoubleDropsHooks(player))
|
||||
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
|
||||
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -267,7 +275,7 @@ public class TreeDefinitionManager extends Manager {
|
||||
|
||||
// Add to inventory or drop on ground
|
||||
if (addToInventory && player.getWorld().equals(treeBlock.getLocation().getWorld())) {
|
||||
Set<ItemStack> extraItems = new HashSet<>();
|
||||
List<ItemStack> extraItems = new ArrayList<>();
|
||||
for (ItemStack lootedItem : lootedItems)
|
||||
extraItems.addAll(player.getInventory().addItem(lootedItem).values());
|
||||
Location location = player.getLocation().clone().subtract(0.5, 0, 0.5);
|
||||
|
@ -24,6 +24,7 @@ public class TreeDetectionManager extends Manager {
|
||||
private final Set<Vector> VALID_TRUNK_OFFSETS, VALID_BRANCH_OFFSETS, VALID_LEAF_OFFSETS;
|
||||
|
||||
private TreeDefinitionManager treeDefinitionManager;
|
||||
private PlacedBlockManager placedBlockManager;
|
||||
private int maxLogBlocksAllowed, numLeavesRequiredForTree;
|
||||
private boolean onlyBreakLogsUpwards, entireTreeBase, destroyLeaves;
|
||||
|
||||
@ -57,6 +58,7 @@ public class TreeDetectionManager extends Manager {
|
||||
@Override
|
||||
public void reload() {
|
||||
this.treeDefinitionManager = this.ultimateTimber.getTreeDefinitionManager();
|
||||
this.placedBlockManager = this.ultimateTimber.getPlacedBlockManager();
|
||||
this.maxLogBlocksAllowed = ConfigurationManager.Setting.MAX_LOGS_PER_CHOP.getInt();
|
||||
this.numLeavesRequiredForTree = ConfigurationManager.Setting.LEAVES_REQUIRED_FOR_TREE.getInt();
|
||||
this.onlyBreakLogsUpwards = ConfigurationManager.Setting.ONLY_DETECT_LOGS_UPWARDS.getBoolean();
|
||||
@ -224,6 +226,9 @@ public class TreeDetectionManager extends Manager {
|
||||
* @return True if the block is a valid log type, otherwise false
|
||||
*/
|
||||
private boolean isValidLogType(Set<TreeDefinition> treeDefinitions, Block block) {
|
||||
if (this.placedBlockManager.isBlockPlaced(block))
|
||||
return false;
|
||||
|
||||
for (TreeDefinition treeDefinition : treeDefinitions)
|
||||
for (IBlockData logBlockData : treeDefinition.getLogBlockData())
|
||||
if (logBlockData.isSimilar(block))
|
||||
@ -239,6 +244,9 @@ public class TreeDetectionManager extends Manager {
|
||||
* @return True if the block is a valid log type, otherwise false
|
||||
*/
|
||||
private boolean isValidLeafType(Set<TreeDefinition> treeDefinitions, Block block) {
|
||||
if (this.placedBlockManager.isBlockPlaced(block))
|
||||
return false;
|
||||
|
||||
for (TreeDefinition treeDefinition : treeDefinitions)
|
||||
for (IBlockData leafBlockData : treeDefinition.getLeafBlockData())
|
||||
if (leafBlockData.isSimilar(block))
|
||||
|
@ -71,8 +71,10 @@ public class TreeFallManager extends Manager implements Listener {
|
||||
if (!choppingManager.isChopping(player))
|
||||
isValid = false;
|
||||
|
||||
if (treeAnimationManager.isBlockInAnimation(block))
|
||||
if (treeAnimationManager.isBlockInAnimation(block)) {
|
||||
isValid = false;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
if (!treeDefinitionManager.isToolValidForAnyTreeDefinition(tool))
|
||||
isValid = false;
|
||||
|
@ -116,6 +116,17 @@ use-custom-particles: true
|
||||
# Default: 2
|
||||
bonus-loot-multiplier: 2
|
||||
|
||||
# If placed blocks should be ignored for toppling trees
|
||||
# Note: This only keeps track of blocks placed during the current server load
|
||||
# If your server restarts, the placed tree blocks could be toppled again
|
||||
# Default: true
|
||||
ignore-placed-blocks: true
|
||||
|
||||
# The maximum number of blocks to keep track of in memory at once
|
||||
# Use a lower number if this starts to take up too much memory
|
||||
# Default: 10000
|
||||
ignore-placed-blocks-memory-size: 10000
|
||||
|
||||
# Applies experience when using Jobs/mcMMO
|
||||
# Only does something if Jobs or mcMMO is installed
|
||||
# Default: true
|
||||
@ -140,12 +151,6 @@ tree-animation-type: FANCY
|
||||
# Default: false
|
||||
scatter-tree-blocks-on-ground: false
|
||||
|
||||
# Mix all the tree types below and consider all of them as a single tree type
|
||||
# Useful for EpicWorldGenerator and similar plugins that make custom trees
|
||||
# Warning: Custom loot can get messy with this enabled
|
||||
# Default: false
|
||||
mix-all-tree-types: false
|
||||
|
||||
# Tree configuration
|
||||
# Allows for extreme fine-tuning of tree detection and what are considered trees
|
||||
# Multiple log and leaf types are allowed, only one sapling type is allowed
|
||||
|
@ -117,6 +117,17 @@ use-custom-particles: true
|
||||
# Default: 2
|
||||
bonus-loot-multiplier: 2
|
||||
|
||||
# If placed blocks should be ignored for toppling trees
|
||||
# Note: This only keeps track of blocks placed during the current server load
|
||||
# If your server restarts, the placed tree blocks could be toppled again
|
||||
# Default: true
|
||||
ignore-placed-blocks: true
|
||||
|
||||
# The maximum number of blocks to keep track of in memory at once
|
||||
# Use a lower number if this starts to take up too much memory
|
||||
# Default: 10000
|
||||
ignore-placed-blocks-memory-size: 10000
|
||||
|
||||
# Applies experience when using Jobs/mcMMO
|
||||
# Only does something if Jobs or mcMMO is installed
|
||||
# Default: true
|
||||
@ -141,12 +152,6 @@ tree-animation-type: FANCY
|
||||
# Default: false
|
||||
scatter-tree-blocks-on-ground: false
|
||||
|
||||
# Mix all the tree types below and consider all of them as a single tree type
|
||||
# Useful for EpicWorldGenerator and similar plugins that make custom trees
|
||||
# Warning: Custom loot can get messy with this enabled
|
||||
# Default: false
|
||||
mix-all-tree-types: false
|
||||
|
||||
# Tree configuration
|
||||
# Allows for extreme fine-tuning of tree detection and what are considered trees
|
||||
# Multiple log and leaf types are allowed, only one sapling type is allowed
|
||||
|
Loading…
Reference in New Issue
Block a user