2019-03-26 21:35:17 +01:00
|
|
|
package com.songoda.ultimatetimber.manager;
|
|
|
|
|
|
|
|
import com.songoda.ultimatetimber.UltimateTimber;
|
2019-03-28 09:30:33 +01:00
|
|
|
import com.songoda.ultimatetimber.adapter.VersionAdapter;
|
|
|
|
import com.songoda.ultimatetimber.tree.ITreeBlock;
|
|
|
|
import com.songoda.ultimatetimber.tree.TreeBlockType;
|
2019-03-26 21:35:17 +01:00
|
|
|
import com.songoda.ultimatetimber.tree.TreeDefinition;
|
2019-03-28 09:30:33 +01:00
|
|
|
import com.songoda.ultimatetimber.tree.TreeLoot;
|
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.block.Block;
|
|
|
|
import org.bukkit.block.BlockState;
|
|
|
|
import org.bukkit.configuration.ConfigurationSection;
|
|
|
|
import org.bukkit.configuration.file.YamlConfiguration;
|
|
|
|
import org.bukkit.enchantments.Enchantment;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.inventory.ItemStack;
|
2019-03-26 21:35:17 +01:00
|
|
|
|
|
|
|
import java.util.HashSet;
|
2019-03-28 09:30:33 +01:00
|
|
|
import java.util.Random;
|
2019-03-26 21:35:17 +01:00
|
|
|
import java.util.Set;
|
|
|
|
|
2019-03-28 01:56:39 +01:00
|
|
|
public class TreeDefinitionManager extends Manager {
|
2019-03-26 21:35:17 +01:00
|
|
|
|
2019-03-28 09:30:33 +01:00
|
|
|
private final Random random;
|
2019-03-26 21:35:17 +01:00
|
|
|
private Set<TreeDefinition> treeDefinitions;
|
2019-03-28 09:30:33 +01:00
|
|
|
private Set<TreeLoot> globalLogLoot, globalLeafLoot;
|
|
|
|
private Set<ItemStack> globalRequiredTools;
|
2019-03-26 21:35:17 +01:00
|
|
|
|
|
|
|
public TreeDefinitionManager(UltimateTimber ultimateTimber) {
|
2019-03-28 01:56:39 +01:00
|
|
|
super(ultimateTimber);
|
2019-03-28 09:30:33 +01:00
|
|
|
this.random = new Random();
|
2019-03-26 21:35:17 +01:00
|
|
|
this.treeDefinitions = new HashSet<>();
|
2019-03-28 09:30:33 +01:00
|
|
|
this.globalLogLoot = new HashSet<>();
|
|
|
|
this.globalLeafLoot = new HashSet<>();
|
|
|
|
this.globalRequiredTools = new HashSet<>();
|
2019-03-26 21:35:17 +01:00
|
|
|
}
|
|
|
|
|
2019-03-28 01:56:39 +01:00
|
|
|
@Override
|
|
|
|
public void reload() {
|
|
|
|
this.treeDefinitions.clear();
|
2019-03-28 09:30:33 +01:00
|
|
|
this.globalLogLoot.clear();
|
|
|
|
this.globalLeafLoot.clear();
|
|
|
|
this.globalRequiredTools.clear();
|
2019-03-26 21:35:17 +01:00
|
|
|
|
2019-03-28 09:30:33 +01:00
|
|
|
VersionAdapter versionAdapter = this.ultimateTimber.getVersionAdapter();
|
|
|
|
ConfigurationManager configurationManager = this.ultimateTimber.getConfigurationManager();
|
|
|
|
YamlConfiguration config = configurationManager.getConfig();
|
|
|
|
|
|
|
|
// Load tree settings
|
|
|
|
ConfigurationSection treeSection = config.getConfigurationSection("trees");
|
|
|
|
for (String key : treeSection.getKeys(false)) {
|
|
|
|
ConfigurationSection tree = treeSection.getConfigurationSection(key);
|
|
|
|
|
|
|
|
Set<BlockState> logBlockStates = new HashSet<>();
|
|
|
|
Set<BlockState> leafBlockStates = new HashSet<>();
|
|
|
|
BlockState saplingBlockState;
|
|
|
|
int maxLeafDistanceFromLog;
|
|
|
|
boolean dropOriginalLog;
|
|
|
|
boolean dropOriginalLeaf;
|
|
|
|
Set<TreeLoot> logLoot = new HashSet<>();
|
|
|
|
Set<TreeLoot> leafLoot = new HashSet<>();
|
|
|
|
Set<ItemStack> requiredTools = new HashSet<>();
|
|
|
|
|
|
|
|
for (String blockStateString : tree.getStringList("logs"))
|
|
|
|
logBlockStates.add(versionAdapter.parseBlockStateFromString(blockStateString));
|
|
|
|
|
|
|
|
for (String blockStateString : tree.getStringList("leaves"))
|
|
|
|
leafBlockStates.add(versionAdapter.parseBlockStateFromString(blockStateString));
|
|
|
|
|
|
|
|
saplingBlockState = versionAdapter.parseBlockStateFromString(tree.getString("sapling"));
|
|
|
|
maxLeafDistanceFromLog = tree.getInt("max-leaf-distance-from-log");
|
|
|
|
dropOriginalLog = tree.getBoolean("drop-original-log");
|
|
|
|
dropOriginalLeaf = tree.getBoolean("drop-original-leaf");
|
|
|
|
|
|
|
|
ConfigurationSection logLootSection = tree.getConfigurationSection("log-loot");
|
|
|
|
for (String lootKey : logLootSection.getKeys(false))
|
|
|
|
logLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LOG, logLootSection.getConfigurationSection(lootKey)));
|
|
|
|
|
|
|
|
ConfigurationSection leafLootSection = tree.getConfigurationSection("leaf-loot");
|
|
|
|
for (String lootKey : leafLootSection.getKeys(false))
|
|
|
|
leafLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LEAF, leafLootSection.getConfigurationSection(lootKey)));
|
|
|
|
|
|
|
|
for (String itemStackString : tree.getStringList("required-tools"))
|
|
|
|
requiredTools.add(versionAdapter.parseItemStackFromString(itemStackString));
|
|
|
|
|
|
|
|
this.treeDefinitions.add(new TreeDefinition(key, logBlockStates, leafBlockStates, saplingBlockState, maxLeafDistanceFromLog, dropOriginalLog, dropOriginalLeaf, logLoot, leafLoot, requiredTools));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load global log drops
|
|
|
|
ConfigurationSection logSection = config.getConfigurationSection("global-log-loot");
|
|
|
|
for (String lootKey : logSection.getKeys(false))
|
|
|
|
this.globalLogLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LOG, logSection.getConfigurationSection(lootKey)));
|
|
|
|
|
|
|
|
// Load global leaf drops
|
|
|
|
ConfigurationSection leafSection = config.getConfigurationSection("global-leaf-loot");
|
|
|
|
for (String lootKey : leafSection.getKeys(false))
|
|
|
|
this.globalLeafLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LEAF, leafSection.getConfigurationSection(lootKey)));
|
|
|
|
|
|
|
|
// Load global tools
|
|
|
|
for (String itemStackString : config.getStringList("global-required-tools"))
|
|
|
|
this.globalRequiredTools.add(versionAdapter.parseItemStackFromString(itemStackString));
|
2019-03-28 01:56:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void disable() {
|
|
|
|
this.treeDefinitions.clear();
|
2019-03-26 21:35:17 +01:00
|
|
|
}
|
|
|
|
|
2019-03-28 09:30:33 +01:00
|
|
|
/**
|
|
|
|
* Checks if a given tool is valid for a given tree definition, also takes into account global tools
|
|
|
|
*
|
|
|
|
* @param treeDefinition The TreeDefinition to use
|
|
|
|
* @param tool The tool to check
|
|
|
|
* @return True if the tool is allowed for toppling the given TreeDefinition
|
|
|
|
*/
|
|
|
|
public boolean isToolValidForTreeDefinition(TreeDefinition treeDefinition, ItemStack tool) {
|
|
|
|
for (ItemStack requiredTool : treeDefinition.getRequiredTools())
|
|
|
|
if (requiredTool.isSimilar(tool))
|
|
|
|
return true;
|
|
|
|
for (ItemStack requiredTool : this.globalRequiredTools)
|
|
|
|
if (requiredTool.isSimilar(tool))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tries to spawn loot for a given TreeBlock with the given TreeDefinition for a given player
|
|
|
|
*
|
|
|
|
* @param treeDefinition The TreeDefinition to use
|
|
|
|
* @param treeBlock The TreeBlock to drop for
|
|
|
|
* @param player The Player to drop for
|
|
|
|
*/
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
public void dropTreeLoot(TreeDefinition treeDefinition, ITreeBlock treeBlock, Player player) {
|
|
|
|
boolean addToInventory = ConfigurationManager.Setting.ADD_ITEMS_TO_INVENTORY.getBoolean();
|
|
|
|
ItemStack itemInHand = this.ultimateTimber.getVersionAdapter().getItemInHand(player);
|
|
|
|
boolean hasSilkTouch = itemInHand != null && itemInHand.hasItemMeta() && itemInHand.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH);
|
|
|
|
boolean hasBonusChance = player.hasPermission("ultimatetimber.bonusloot");
|
|
|
|
Set<ItemStack> lootedItems = new HashSet<>();
|
|
|
|
Set<String> lootedCommands = new HashSet<>();
|
|
|
|
|
|
|
|
// Get the loot that we should try to drop
|
|
|
|
Set<TreeLoot> toTry = new HashSet<>();
|
|
|
|
switch (treeBlock.getTreeBlockType()) {
|
|
|
|
case LOG:
|
|
|
|
toTry.addAll(treeDefinition.getLogLoot());
|
|
|
|
toTry.addAll(this.globalLogLoot);
|
|
|
|
if (treeDefinition.shouldDropOriginalLog() || hasSilkTouch)
|
|
|
|
lootedItems.addAll(treeBlock.getDrops());
|
|
|
|
break;
|
|
|
|
case LEAF:
|
|
|
|
toTry.addAll(treeDefinition.getLeafLoot());
|
|
|
|
toTry.addAll(this.globalLeafLoot);
|
|
|
|
if (treeDefinition.shouldDropOriginalLeaf() || hasSilkTouch)
|
|
|
|
lootedItems.addAll(treeBlock.getDrops());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Roll the dice
|
|
|
|
for (TreeLoot treeLoot : toTry) {
|
|
|
|
double chance = hasBonusChance ? treeLoot.getChance() * 2 : treeLoot.getChance();
|
|
|
|
if (this.random.nextDouble() > chance)
|
|
|
|
continue;
|
|
|
|
if (treeLoot.hasItem())
|
|
|
|
lootedItems.add(treeLoot.getItem());
|
|
|
|
if (treeLoot.hasCommand())
|
|
|
|
lootedCommands.add(treeLoot.getCommand());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add to inventory or drop on ground
|
|
|
|
if (addToInventory) {
|
|
|
|
for (ItemStack lootedItem : lootedItems)
|
|
|
|
player.getInventory().addItem(lootedItem);
|
|
|
|
} else {
|
|
|
|
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
|
|
|
|
for (ItemStack lootedItem : lootedItems)
|
|
|
|
location.getWorld().dropItemNaturally(location, lootedItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run looted commands
|
|
|
|
for (String lootedCommand : lootedCommands)
|
|
|
|
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), lootedCommand.replace("%player", player.getName()).replace("%type", treeDefinition.getKey()));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a TreeLoot entry from a ConfigurationSection
|
|
|
|
*
|
|
|
|
* @param versionAdapter The VersionAdapter to use
|
|
|
|
* @param treeBlockType The TreeBlockType to use
|
|
|
|
* @param configurationSection The ConfigurationSection
|
|
|
|
* @return A TreeLoot entry from the section
|
|
|
|
*/
|
|
|
|
private TreeLoot getTreeLootEntry(VersionAdapter versionAdapter, TreeBlockType treeBlockType, ConfigurationSection configurationSection) {
|
|
|
|
ItemStack item = versionAdapter.parseItemStackFromString(configurationSection.getString("material"));
|
|
|
|
String command = configurationSection.getString("command");
|
|
|
|
double chance = configurationSection.getDouble("chance");
|
|
|
|
return new TreeLoot(treeBlockType, item, command, chance);
|
|
|
|
}
|
|
|
|
|
2019-03-26 21:35:17 +01:00
|
|
|
}
|