UltimateTimber/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java

202 lines
9.2 KiB
Java
Raw Normal View History

2019-03-26 21:35:17 +01:00
package com.songoda.ultimatetimber.manager;
import com.songoda.ultimatetimber.UltimateTimber;
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;
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;
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
private final Random random;
2019-03-26 21:35:17 +01:00
private Set<TreeDefinition> treeDefinitions;
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);
this.random = new Random();
2019-03-26 21:35:17 +01:00
this.treeDefinitions = new HashSet<>();
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();
this.globalLogLoot.clear();
this.globalLeafLoot.clear();
this.globalRequiredTools.clear();
2019-03-26 21:35:17 +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
}
/**
* 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
}