Merge branch 'development'

This commit is contained in:
Brianna 2020-10-30 15:01:03 -05:00
commit a6926de3a2
34 changed files with 302 additions and 1394 deletions

View File

@ -1,35 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0">
<parent>
<groupId>com.songoda</groupId>
<artifactId>UltimateTimber</artifactId>
<version>2.0.9b</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>CurrentAdapter</artifactId>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.15</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>Core</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore</artifactId>
<version>LATEST</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,169 +0,0 @@
package com.songoda.ultimatetimber.adapter.current;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.ultimatetimber.adapter.IBlockData;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.adapter.VersionAdapterType;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockType;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import com.songoda.ultimatetimber.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.event.player.PlayerItemBreakEvent;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class CurrentAdapter implements VersionAdapter {
@Override
public VersionAdapterType getVersionAdapterType() {
return VersionAdapterType.CURRENT;
}
@Override
public IBlockData parseBlockDataFromString(String blockDataString) {
Material material = Material.matchMaterial(blockDataString);
if (material == null) return null;
return new CurrentBlockData(material);
}
@Override
public ItemStack parseItemStackFromString(String itemStackString) {
CompatibleMaterial compatibleMaterial = CompatibleMaterial.getMaterial(itemStackString);
if (compatibleMaterial == null) return null;
return compatibleMaterial.getItem();
}
@Override
public Collection<ItemStack> getBlockDrops(TreeDefinition treeDefinition, ITreeBlock treeBlock) {
Set<ItemStack> drops = new HashSet<>();
if (treeBlock.getBlock() instanceof Block) {
Block block = (Block)treeBlock.getBlock();
if (block.getType().equals(Material.AIR))
return drops;
drops.add(new ItemStack(block.getType()));
} else if (treeBlock.getBlock() instanceof FallingBlock) {
FallingBlock fallingBlock = (FallingBlock)treeBlock.getBlock();
drops.add(new ItemStack(fallingBlock.getBlockData().getMaterial()));
}
return drops;
}
@Override
public void applyToolDurability(Player player, int damage) {
ItemStack tool = this.getItemInHand(player);
if (tool.getType().getMaxDurability() < 1 || (tool.getItemMeta() != null && tool.getItemMeta().isUnbreakable()))
return;
int unbreakingLevel = tool.getEnchantmentLevel(Enchantment.DURABILITY);
Damageable damageable = (Damageable) tool.getItemMeta();
int actualDamage = 0;
for (int i = 0; i < damage; i++)
if (Methods.checkUnbreakingChance(unbreakingLevel))
actualDamage++;
damageable.setDamage(damageable.getDamage() + actualDamage);
tool.setItemMeta((ItemMeta) damageable);
if (!this.hasEnoughDurability(tool, 1)) {
PlayerItemBreakEvent breakEvent = new PlayerItemBreakEvent(player, tool);
Bukkit.getServer().getPluginManager().callEvent(breakEvent);
this.removeItemInHand(player);
}
}
@Override
public boolean hasEnoughDurability(ItemStack tool, int requiredAmount) {
if (!tool.hasItemMeta() || !(tool.getItemMeta() instanceof Damageable) || tool.getType().getMaxDurability() < 1)
return true;
Damageable damageable = (Damageable) tool.getItemMeta();
int durabilityRemaining = tool.getType().getMaxDurability() - damageable.getDamage();
return durabilityRemaining > requiredAmount;
}
@Override
public ItemStack getItemInHand(Player player) {
return player.getInventory().getItemInMainHand();
}
@Override
public void removeItemInHand(Player player) {
player.getInventory().setItemInMainHand(null);
}
@Override
public FallingBlock spawnFallingBlock(Location location, Block block) {
return location.getWorld().spawnFallingBlock(location, block.getBlockData());
}
@Override
public void configureFallingBlock(FallingBlock fallingBlock) {
this.toggleGravityFallingBlock(fallingBlock, false);
fallingBlock.setDropItem(false);
fallingBlock.setHurtEntities(false);
}
@Override
public void toggleGravityFallingBlock(FallingBlock fallingBlock, boolean applyGravity) {
fallingBlock.setGravity(applyGravity);
}
@Override
public void playFallingParticles(TreeDefinition treeDefinition, ITreeBlock treeBlock) {
BlockData blockData;
if (treeBlock.getBlock() instanceof Block) {
blockData = ((Block)treeBlock.getBlock()).getBlockData();
} else if (treeBlock.getBlock() instanceof FallingBlock) {
blockData = ((FallingBlock)treeBlock.getBlock()).getBlockData();
} else return;
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
location.getWorld().spawnParticle(Particle.BLOCK_DUST, location, 10, blockData);
}
@Override
public void playLandingParticles(TreeDefinition treeDefinition, ITreeBlock treeBlock) {
BlockData blockData;
if (treeBlock.getBlock() instanceof Block) {
blockData = ((Block)treeBlock.getBlock()).getBlockData();
} else if (treeBlock.getBlock() instanceof FallingBlock) {
blockData = ((FallingBlock)treeBlock.getBlock()).getBlockData();
} else return;
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
location.getWorld().spawnParticle(Particle.BLOCK_CRACK, location, 10, blockData);
}
@Override
public void playFallingSound(ITreeBlock treeBlock) {
Location location = treeBlock.getLocation();
location.getWorld().playSound(location, Sound.BLOCK_CHEST_OPEN, 2F, 0.1F);
}
@Override
public void playLandingSound(ITreeBlock treeBlock) {
Location location = treeBlock.getLocation();
if (treeBlock.getTreeBlockType().equals(TreeBlockType.LOG)) {
location.getWorld().playSound(location, Sound.BLOCK_WOOD_FALL, 2F, 0.1F);
} else {
location.getWorld().playSound(location, Sound.BLOCK_GRASS_BREAK, 0.5F, 0.75F);
}
}
}

View File

@ -1,40 +0,0 @@
package com.songoda.ultimatetimber.adapter.current;
import com.songoda.ultimatetimber.adapter.IBlockData;
import org.bukkit.Material;
import org.bukkit.block.Block;
public class CurrentBlockData implements IBlockData {
private final Material material;
public CurrentBlockData(Material material) {
this.material = material;
}
@Override
public Material getMaterial() {
return this.material;
}
@Override
public byte getData() {
return 0;
}
@Override
public boolean isSimilar(IBlockData otherBlockData) {
return this.material.equals(otherBlockData.getMaterial());
}
@Override
public boolean isSimilar(Block block) {
return this.material.equals(block.getType());
}
@Override
public void setBlock(Block block) {
block.setType(this.material);
}
}

View File

@ -1,29 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0">
<parent>
<groupId>com.songoda</groupId>
<artifactId>UltimateTimber</artifactId>
<version>2.0.9b</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>LegacyAdapter</artifactId>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.12.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>Core</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,216 +0,0 @@
package com.songoda.ultimatetimber.adapter.legacy;
import com.songoda.ultimatetimber.adapter.IBlockData;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.adapter.VersionAdapterType;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockType;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import com.songoda.ultimatetimber.utils.Methods;
import com.songoda.ultimatetimber.utils.NMSUtil;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@SuppressWarnings("deprecation")
public class LegacyAdapter implements VersionAdapter {
@Override
public VersionAdapterType getVersionAdapterType() {
return VersionAdapterType.LEGACY;
}
@Override
public IBlockData parseBlockDataFromString(String blockDataString) {
String[] split = blockDataString.split(":");
Material material = Material.matchMaterial(split[0]);
List<Byte> data = new ArrayList<>();
if (split.length > 1) {
String[] splitData = split[1].split(",");
for (String dataValue : splitData)
data.add(Byte.parseByte(dataValue));
} else {
data.add((byte)0);
}
return new LegacyBlockData(material, data);
}
@Override
public ItemStack parseItemStackFromString(String itemStackString) {
String[] split = itemStackString.split(":");
Material material = Material.matchMaterial(split[0]);
byte data = 0;
if (split.length > 1) {
data = Byte.parseByte(split[1]);
}
return new ItemStack(material, 1, data);
}
@Override
public Collection<ItemStack> getBlockDrops(TreeDefinition treeDefinition, ITreeBlock treeBlock) {
Set<ItemStack> drops = new HashSet<>();
IBlockData treeBlockData;
if (treeBlock.getBlock() instanceof Block) {
Block block = (Block)treeBlock.getBlock();
if (block.getType().equals(Material.AIR))
return drops;
List<Byte> data = new ArrayList<>();
data.add(block.getData());
treeBlockData = new LegacyBlockData(block.getType(), data);
} else if (treeBlock.getBlock() instanceof FallingBlock) {
FallingBlock fallingBlock = (FallingBlock)treeBlock.getBlock();
List<Byte> data = new ArrayList<>();
data.add(fallingBlock.getBlockData());
treeBlockData = new LegacyBlockData(fallingBlock.getMaterial(), data);
} else return drops;
Set<IBlockData> typedBlockData = treeBlock.getTreeBlockType().equals(TreeBlockType.LOG) ? treeDefinition.getLogBlockData() : treeDefinition.getLeafBlockData();
IBlockData definitionBlockData = null;
for (IBlockData blockData : typedBlockData) {
if (blockData.getMaterial().equals(treeBlockData.getMaterial()) && blockData.getData() == treeBlockData.getData()) {
definitionBlockData = blockData;
break;
}
}
if (definitionBlockData == null) {
for (IBlockData blockData : typedBlockData) {
if (blockData.getMaterial().equals(treeBlockData.getMaterial())) {
definitionBlockData = blockData;
break;
}
}
}
if (definitionBlockData != null && definitionBlockData.isSimilar(treeBlockData))
drops.add(new ItemStack(definitionBlockData.getMaterial(), 1, definitionBlockData.getData()));
return drops;
}
@Override
public void applyToolDurability(Player player, int damage) {
ItemStack tool = this.getItemInHand(player);
if (tool.getType().getMaxDurability() < 1 || (tool.getItemMeta() != null && tool.getItemMeta().spigot().isUnbreakable()))
return;
int unbreakingLevel = tool.getEnchantmentLevel(Enchantment.DURABILITY);
int actualDamage = 0;
for (int i = 0; i < damage; i++)
if (Methods.checkUnbreakingChance(unbreakingLevel))
actualDamage++;
tool.setDurability((short)(tool.getDurability() + actualDamage));
if (!this.hasEnoughDurability(tool, 1))
this.removeItemInHand(player);
}
@Override
public boolean hasEnoughDurability(ItemStack tool, int requiredAmount) {
if (tool.getType().getMaxDurability() <= 1)
return true;
return tool.getDurability() + requiredAmount <= tool.getType().getMaxDurability();
}
@Override
public ItemStack getItemInHand(Player player) {
return player.getItemInHand();
}
@Override
public void removeItemInHand(Player player) {
player.setItemInHand(null);
}
@Override
public FallingBlock spawnFallingBlock(Location location, Block block) {
return location.getWorld().spawnFallingBlock(location, block.getType(), block.getData());
}
@Override
public void configureFallingBlock(FallingBlock fallingBlock) {
this.toggleGravityFallingBlock(fallingBlock, false);
fallingBlock.setDropItem(false);
fallingBlock.setHurtEntities(false);
}
@Override
public void toggleGravityFallingBlock(FallingBlock fallingBlock, boolean applyGravity) {
if (NMSUtil.getVersionNumber() > 9)
fallingBlock.setGravity(applyGravity);
}
@Override
public void playFallingParticles(TreeDefinition treeDefinition, ITreeBlock treeBlock) {
Collection<ItemStack> blockDrops = this.getBlockDrops(treeDefinition, treeBlock);
if (!blockDrops.iterator().hasNext())
return;
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
if (NMSUtil.getVersionNumber() > 8) {
location.getWorld().spawnParticle(Particle.BLOCK_CRACK, location, 10, blockDrops.iterator().next().getData());
} else {
location.getWorld().playEffect(location, Effect.SMOKE, 4);
}
}
@Override
public void playLandingParticles(TreeDefinition treeDefinition, ITreeBlock treeBlock) {
Collection<ItemStack> blockDrops = this.getBlockDrops(treeDefinition, treeBlock);
if (!blockDrops.iterator().hasNext())
return;
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
if (NMSUtil.getVersionNumber() > 8) {
location.getWorld().spawnParticle(Particle.BLOCK_DUST, location, 10, blockDrops.iterator().next().getData());
} else {
location.getWorld().playEffect(location, Effect.SMOKE, 4);
}
}
@Override
public void playFallingSound(ITreeBlock treeBlock) {
Location location = treeBlock.getLocation();
if (NMSUtil.getVersionNumber() > 8) {
location.getWorld().playSound(location, Sound.BLOCK_CHEST_OPEN, 2F, 0.1F);
} else {
location.getWorld().playSound(location, Sound.valueOf("CHEST_OPEN"), 2F, 0.1F);
}
}
@Override
public void playLandingSound(ITreeBlock treeBlock) {
Location location = treeBlock.getLocation();
if (treeBlock.getTreeBlockType().equals(TreeBlockType.LOG)) {
if (NMSUtil.getVersionNumber() > 8) {
location.getWorld().playSound(location, Sound.BLOCK_WOOD_FALL, 3F, 0.1F);
} else {
location.getWorld().playSound(location, Sound.valueOf("DIG_WOOD"), 3F, 0.1F);
}
} else {
if (NMSUtil.getVersionNumber() > 8) {
location.getWorld().playSound(location, Sound.BLOCK_GRASS_BREAK, 0.5F, 0.75F);
} else {
location.getWorld().playSound(location, Sound.valueOf("DIG_GRASS"), 0.5F, 0.75F);
}
}
}
}

View File

@ -1,67 +0,0 @@
package com.songoda.ultimatetimber.adapter.legacy;
import com.songoda.ultimatetimber.adapter.IBlockData;
import org.bukkit.Material;
import org.bukkit.block.Block;
import java.util.List;
@SuppressWarnings("deprecation")
public class LegacyBlockData implements IBlockData {
private final Material material;
private final List<Byte> data;
public LegacyBlockData(Material material, List<Byte> data) {
this.material = material;
this.data = data;
}
@Override
public Material getMaterial() {
return this.material;
}
@Override
public byte getData() {
return this.data.get(0);
}
@Override
public boolean isSimilar(IBlockData otherBlockData) {
if (this.data.size() == 1)
return this.material.equals(otherBlockData.getMaterial()) && this.getData() == otherBlockData.getData();
Material blockMaterial = otherBlockData.getMaterial();
byte blockData = otherBlockData.getData();
if (!this.material.equals(blockMaterial))
return false;
for (byte value : this.data)
if (value == blockData)
return true;
return false;
}
@Override
public boolean isSimilar(Block block) {
if (this.data.size() == 1)
return this.material.equals(block.getType()) && this.getData() == block.getData();
Material blockMaterial = block.getType();
byte blockData = block.getData();
if (!this.material.equals(blockMaterial))
return false;
for (byte value : this.data)
if (value == blockData)
return true;
return false;
}
@Override
public void setBlock(Block block) {
block.setType(this.material);
block.setData(this.data.get(0));
}
}

View File

@ -3,7 +3,7 @@
<parent>
<groupId>com.songoda</groupId>
<artifactId>UltimateTimber</artifactId>
<version>2.0.9b</version>
<version>2.1</version>
<relativePath>../../</relativePath>
</parent>
@ -16,8 +16,14 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.15</version>
<version>1.16.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore</artifactId>
<version>LATEST</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,43 +0,0 @@
package com.songoda.ultimatetimber.adapter;
import org.bukkit.Material;
import org.bukkit.block.Block;
public interface IBlockData {
/**
* Gets the Material of the BlockData
*
* @return The Material
*/
Material getMaterial();
/**
* Gets the data of the BlockData
*
* @return The data
*/
byte getData();
/**
* Compares this IBlockData with another one to see if they are similar
*
* @return True if they are similar, otherwise false
*/
boolean isSimilar(IBlockData otherBlockData);
/**
* Compares this IBlockData with a block to see if they are similar
*
* @return True if they are similar, otherwise false
*/
boolean isSimilar(Block block);
/**
* Sets a given Block to use this IBlockData
*
* @param block The Block to set
*/
void setBlock(Block block);
}

View File

@ -1,133 +0,0 @@
package com.songoda.ultimatetimber.adapter;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
public interface VersionAdapter {
/**
* Gets the version adapter type
*
* @return The VersionAdapterType
*/
VersionAdapterType getVersionAdapterType();
/**
* Parses a String into an IBlockData instance
*
* @param blockDataString The String to parse
* @return An IBlockData instance that the given String represents
*/
IBlockData parseBlockDataFromString(String blockDataString);
/**
* Parses a String into an ItemStack
*
* @param itemStackString The String to parse
* @return An ItemStack that the given String represents
*/
ItemStack parseItemStackFromString(String itemStackString);
/**
* Get the items that a tree block should drop when it breaks
*
* @param treeDefinition The tree definition to get the items for
* @param treeBlock The tree block
* @return A Set of ItemStacks that should be dropped
*/
Collection<ItemStack> getBlockDrops(TreeDefinition treeDefinition, ITreeBlock treeBlock);
/**
* Applies damage to a tool
*
* @param player The Player who's tool to apply damage to
* @param damage The amount of damage to apply
*/
void applyToolDurability(Player player, int damage);
/**
* Checks if a given tool has enough durability remaining
*
* @param tool The tool to check
* @param requiredAmount The amount of durability required
* @return True if enough durability is remaining to not break the tool, otherwise false
*/
boolean hasEnoughDurability(ItemStack tool, int requiredAmount);
/**
* Gets the item in the player's main hand
*
* @param player The Player to get the item from
* @return The ItemStack in the Player's main hand
*/
ItemStack getItemInHand(Player player);
/**
* Removes the item in the player's main hand
*
* @param player The Player to remove the item from
*/
void removeItemInHand(Player player);
/**
* Spawns a falling block at the given location with the given block data
*
* @param location The location to spawn at
* @param block The block to use block data
* @return A newly spawned FallingBlock entity
*/
FallingBlock spawnFallingBlock(Location location, Block block);
/**
* Configures a falling block for animating
*
* @param fallingBlock The falling block to configure
*/
void configureFallingBlock(FallingBlock fallingBlock);
/**
* Enables/Disables gravity for a falling block
*
* @param fallingBlock The falling block to apply gravity settings to
* @param applyGravity Whether or not to apply the gravity
*/
void toggleGravityFallingBlock(FallingBlock fallingBlock, boolean applyGravity);
/**
* Plays particles to indicate a tree block has started falling
*
* @param treeDefinition The TreeDefinition of the block
* @param treeBlock The TreeBlock to play the particles for
*/
void playFallingParticles(TreeDefinition treeDefinition, ITreeBlock treeBlock);
/**
* Plays particles to indicate a tree block has hit the ground
*
* @param treeDefinition The TreeDefinition of the block
* @param treeBlock The TreeBlock to play the particles for
*/
void playLandingParticles(TreeDefinition treeDefinition, ITreeBlock treeBlock);
/**
* Plays a sound to indicate a tree block has started falling
*
* @param treeBlock The TreeBlock to play the sound for
*/
void playFallingSound(ITreeBlock treeBlock);
/**
* Plays a sound to indicate a tree block has hit the ground
*
* @param treeBlock The TreeBlock to play the sound for
*/
void playLandingSound(ITreeBlock treeBlock);
}

View File

@ -1,10 +0,0 @@
package com.songoda.ultimatetimber.adapter;
/**
* The version adapter type
* Used to determine what version adapter is being used
*/
public enum VersionAdapterType {
CURRENT,
LEGACY
}

View File

@ -1,6 +1,6 @@
package com.songoda.ultimatetimber.tree;
import com.songoda.ultimatetimber.adapter.IBlockData;
import com.songoda.core.compatibility.CompatibleMaterial;
import org.bukkit.inventory.ItemStack;
import java.util.Collections;
@ -9,8 +9,8 @@ import java.util.Set;
public class TreeDefinition {
private final String key;
private final Set<IBlockData> logBlockData, leafBlockData, plantableSoilBlockData;
private final IBlockData saplingBlockData;
private final Set<CompatibleMaterial> logMaterial, leafMaterial, plantableSoilMaterial;
private final CompatibleMaterial saplingMaterial;
private final double maxLogDistanceFromTrunk;
private final int maxLeafDistanceFromLog;
private final boolean detectLeavesDiagonally;
@ -18,15 +18,15 @@ public class TreeDefinition {
private final Set<TreeLoot> logLoot, leafLoot, entireTreeLoot;
private final Set<ItemStack> requiredTools;
public TreeDefinition(String key, Set<IBlockData> logBlockData, Set<IBlockData> leafBlockData, IBlockData saplingBlockData,
Set<IBlockData> plantableSoilBlockData, double maxLogDistanceFromTrunk, int maxLeafDistanceFromLog,
public TreeDefinition(String key, Set<CompatibleMaterial> logMaterial, Set<CompatibleMaterial> leafMaterial, CompatibleMaterial saplingMaterial,
Set<CompatibleMaterial> plantableSoilMaterial, double maxLogDistanceFromTrunk, int maxLeafDistanceFromLog,
boolean detectLeavesDiagonally, boolean dropOriginalLog, boolean dropOriginalLeaf, Set<TreeLoot> logLoot,
Set<TreeLoot> leafLoot, Set<TreeLoot> entireTreeLoot, Set<ItemStack> requiredTools) {
this.key = key;
this.logBlockData = logBlockData;
this.leafBlockData = leafBlockData;
this.saplingBlockData = saplingBlockData;
this.plantableSoilBlockData = plantableSoilBlockData;
this.logMaterial = logMaterial;
this.leafMaterial = leafMaterial;
this.saplingMaterial = saplingMaterial;
this.plantableSoilMaterial = plantableSoilMaterial;
this.maxLogDistanceFromTrunk = maxLogDistanceFromTrunk;
this.maxLeafDistanceFromLog = maxLeafDistanceFromLog;
this.detectLeavesDiagonally = detectLeavesDiagonally;
@ -50,37 +50,37 @@ public class TreeDefinition {
/**
* Gets a set of valid log block data for this TreeDefinition
*
* @return A Set of IBlockData
* @return A Set of CompatibleMaterial
*/
public Set<IBlockData> getLogBlockData() {
return Collections.unmodifiableSet(this.logBlockData);
public Set<CompatibleMaterial> getLogMaterial() {
return Collections.unmodifiableSet(this.logMaterial);
}
/**
* Gets a set of valid leaf block data for this TreeDefinition
*
* @return A Set of IBlockData
* @return A Set of CompatibleMaterial
*/
public Set<IBlockData> getLeafBlockData() {
return Collections.unmodifiableSet(this.leafBlockData);
public Set<CompatibleMaterial> getLeafMaterial() {
return Collections.unmodifiableSet(this.leafMaterial);
}
/**
* Gets the sapling block data of this TreeDefinition
*
* @return An IBlockData instance for the sapling
* @return An CompatibleMaterial instance for the sapling
*/
public IBlockData getSaplingBlockData() {
return this.saplingBlockData;
public CompatibleMaterial getSaplingMaterial() {
return this.saplingMaterial;
}
/**
* Gets a set of plantable soil block data for this TreeDefinition
*
* @return A Set of IBlockData
* @return A Set of CompatibleMaterial
*/
public Set<IBlockData> getPlantableSoilBlockData() {
return Collections.unmodifiableSet(this.plantableSoilBlockData);
public Set<CompatibleMaterial> getPlantableSoilMaterial() {
return Collections.unmodifiableSet(this.plantableSoilMaterial);
}
/**

View File

@ -70,4 +70,13 @@ public class TreeLoot {
return this.chance;
}
@Override
public String toString() {
return "TreeLoot{" +
"treeBlockType=" + treeBlockType +
", item=" + item +
", command='" + command + '\'' +
", chance=" + chance +
'}';
}
}

View File

@ -1,48 +0,0 @@
package com.songoda.ultimatetimber.utils;
import org.bukkit.ChatColor;
import java.util.Random;
public class Methods {
private static Random random = new Random();
/**
* Formats a given string replacing colors
*
* @param text The string
* @return The formatted string
*/
public static String formatText(String text) {
if (text == null || text.equals(""))
return "";
return formatText(text, false);
}
/**
* Formats a given string replacing colors and optionally capitalizing the first word
*
* @param text The string
* @param cap If the first word should be capitalized
* @return The formatted string
*/
private static String formatText(String text, boolean cap) {
if (text == null || text.equals(""))
return "";
if (cap)
text = text.substring(0, 1).toUpperCase() + text.substring(1);
return ChatColor.translateAlternateColorCodes('&', text);
}
/**
* Check if durbility should be applied based on the unbreaking enchantment
*
* @param level The level of the unbreaking enchantment
* @return True if durability should be applied, otherwise false
*/
public static boolean checkUnbreakingChance(int level) {
return (1.0 / (level + 1)) > random.nextDouble();
}
}

View File

@ -1,22 +0,0 @@
package com.songoda.ultimatetimber.utils;
import org.bukkit.Bukkit;
public class NMSUtil {
public static String getVersion() {
String name = Bukkit.getServer().getClass().getPackage().getName();
return name.substring(name.lastIndexOf('.') + 1) + ".";
}
public static int getVersionNumber() {
String name = getVersion().substring(3);
return Integer.valueOf(name.substring(0, name.length() - 4));
}
public static int getVersionReleaseNumber() {
String NMSVersion = getVersion();
return Integer.valueOf(NMSVersion.substring(NMSVersion.length() - 2).replace(".", ""));
}
}

View File

@ -3,7 +3,7 @@
<parent>
<groupId>com.songoda</groupId>
<artifactId>UltimateTimber</artifactId>
<version>2.0.9b</version>
<version>2.1</version>
<relativePath>../../</relativePath>
</parent>
@ -64,8 +64,6 @@
<includes>
<include>com.songoda:SongodaCore</include>
<include>com.songoda:Core</include>
<include>com.songoda:CurrentAdapter</include>
<include>com.songoda:LegacyAdapter</include>
</includes>
</artifactSet>
<filters>
@ -87,7 +85,7 @@
<relocations>
<relocation>
<pattern>com.songoda.core</pattern>
<shadedPattern>${project.groupId}.ultimatestacker.core</shadedPattern>
<shadedPattern>${project.groupId}.ultimatetimber.core</shadedPattern>
</relocation>
</relocations>
</configuration>
@ -101,7 +99,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.16.1</version>
<version>1.16.2</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -116,17 +114,5 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>CurrentAdapter</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>LegacyAdapter</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,399 +0,0 @@
# ____ ___ __ __ __ __ ___________ __ ___
# | | \ |_/ |_|__| _____ _____ _/ |_ ___\__ ___/|__| _____\_ |__ ___________
# | | / |\ __\ |/ \\__ \\ __\/ __ \| | | |/ \| __ \_/ __ \_ __ \
# | | /| |_| | | | Y Y \/ __ \| | \ ___/| | | | Y Y \ \_\ \ ___/| | \/
# |______/ |____/__| |__|__|_| (____ /__| \___ |____| |__|__|_| /___ /\___ >__|
# The type of server you are running in relation to this plugin
# If you ever upgrade from a legacy version of Minecraft to a current version, you will need to reset this config
# Do not change this value
# Default: LEGACY
server-type: LEGACY
# The locale to use in the /locale folder
# Default: en_US
locale: en_US
# A list of worlds that the plugin is disabled in
# Default:
# - disabled_world_name
disabled-worlds:
- disabled_world_name
# The max number of logs that can be broken at one time
# Default: 150
max-logs-per-chop: 150
# The minimum number of leaves required for something to be considered a tree
# Default: 5
leaves-required-for-tree: 5
# If leaves should be destroyed
# Default: true
destroy-leaves: true
# Apply realistic damage to the tools based on the number of logs chopped
# If false, only one durability will be removed from the tool
# Default: true
realistic-tool-damage: true
# Protect the tool used to chop down the tree from breaking
# Prevents the tree from being toppled if the tool would break
# Default: false
protect-tool: false
# Use the silk touch enchantment if the tool has it
# Logs and leaves will drop their original block 100% of the time
# Default: true
apply-silk-touch: true
# Damage the tool extra for each leaf block broken, this is vanilla behavior but can be disabled here
# Does nothing if realistic-tool-damage is false
# Default: true
apply-silk-touch-tool-damage: true
# Require the entire base of the tree to be broken before it topples
# Default: false
break-entire-tree-base: false
# Don't drop a block for the block that initiates the tree fall
# Default: false
destroy-initiated-block: false
# Only detect logs above the initiated block
# Default: true
only-detect-logs-upwards: true
# Only topple trees while the player is doing something
# Valid values: SNEAKING, NOT_SNEAKING, ALWAYS
# Default: ALWAYS
only-topple-while: ALWAYS
# Allow toppling trees in creative mode
# Default: true
allow-creative-mode: true
# Require the player to have the permission 'ultimatetimber.chop' to topple trees
# Default: false
require-chop-permission: false
# If a player should only be allowed to chop one tree per cooldown length
# Default: false
player-tree-topple-cooldown: false
# The amount of seconds a player has to wait before they can chop a tree again
# Does nothing if player-tree-topple-cooldown is false
# The time is in seconds and must be a postive whole number
# Default: 5
player-tree-topple-cooldown-length: 5
# Allow players to topple trees regardless of what they are holding in their hand
# Default: false
ignore-required-tools: false
# Automatically replant saplings when a tree is toppled
# Default: true
replant-saplings: true
# Always replant saplings for base tree blocks, regardless of player permissions
# Default: false
always-replant-sapling: false
# How many seconds to prevent players from breaking replanted saplings
# Set to 0 to disable
# Does nothing if replant-saplings is false
# The time is in seconds and must be a postive whole number
# Default: 3
replant-saplings-cooldown: 3
# Give fallen leaf blocks a chance to replant saplings when they hit the ground
# Default: true
falling-blocks-replant-saplings: true
# The percent chance that fallen leaves have of planting a sapling
# Does nothing if falling-blocks-replant-saplings is false
# The chance is out of 100 and may contain decimals
# Default: 1
falling-blocks-replant-saplings-chance: 1
# Make falling tree blocks deal damage to players if they get hit
# Default: true
falling-blocks-deal-damage: true
# The amount of damage that falling tree blocks do
# This does nothing if falling-blocks-deal-damage is false
# Default: 1
falling-block-damage: 1
# Automatically add tree blocks to the player's inventory instead of dropping them
# Default: false
add-items-to-inventory: false
# Use custom sounds when toppling trees
# Default: true
use-custom-sounds: true
# Use custom particles when toppling trees
# Default: true
use-custom-particles: true
# The bonus loot multiplier when a player has the permission ultimatetimber.bonusloot
# Multiplies the chance of tree drops by this value
# Decimal values are allowed
# 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 or trees start taking too long to detect
# Default: 5000
ignore-placed-blocks-memory-size: 5000
# Applies experience when using Jobs/mcMMO
# Only does something if Jobs or mcMMO is installed
# Default: true
hooks-apply-experience: true
# Applies extra drops passive ability when using mcMMO
# Only does something if mcMMO is installed
# Default: true
hooks-apply-extra-drops: true
# Requires the tree feller ability in mcMMO to be active to use timber
# Only does something if mcMMO is installed
# Default: false
hooks-require-ability-active: false
# The type of animation to use for tree toppling
# Types: FANCY, DISINTEGRATE, CRUMBLE, NONE
tree-animation-type: FANCY
# If the tree-animation-type is FANCY or CRUMBLE, make the blocks stick to the ground
# Does nothing if tree-animation-type is not FANCY or CRUMBLE
# Default: false
scatter-tree-blocks-on-ground: 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
# You can add your own custom tree types here, just add a new section
trees:
oak:
logs:
- LOG:0,4,8,12
leaves:
- LEAVES:0,4,8,12
sapling: SAPLING:0
plantable-soil: []
max-log-distance-from-trunk: 6
max-leaf-distance-from-log: 6
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
leaf-loot:
0:
material: SAPLING:0
chance: 5
1:
material: APPLE
chance: 0.5
entire-tree-loot: []
required-tools: []
spruce:
logs:
- LOG:1,5,9,13
leaves:
- LEAVES:1,5,9,13
sapling: SAPLING:1
plantable-soil: []
max-log-distance-from-trunk: 2
max-leaf-distance-from-log: 6
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
leaf-loot:
0:
material: SAPLING:1
chance: 5
entire-tree-loot: []
required-tools: []
birch:
logs:
- LOG:2,6,10,14
leaves:
- LEAVES:2,6,10,14
sapling: SAPLING:2
plantable-soil: []
max-log-distance-from-trunk: 1
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
leaf-loot:
0:
material: SAPLING:2
chance: 5
entire-tree-loot: []
required-tools: []
jungle:
logs:
- LOG:3,7,11,15
leaves:
- LEAVES:3,7,11,15
sapling: SAPLING:3
plantable-soil: []
max-log-distance-from-trunk: 6
max-leaf-distance-from-log: 6
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
leaf-loot:
0:
material: SAPLING:3
chance: 2.5
entire-tree-loot: []
required-tools: []
acacia:
logs:
- LOG_2:0,4,8,12
leaves:
- LEAVES_2:0,4,8,12
sapling: SAPLING:4
plantable-soil: []
max-log-distance-from-trunk: 4
max-leaf-distance-from-log: 5
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
leaf-loot:
0:
material: SAPLING:4
chance: 5
entire-tree-loot: []
required-tools: []
dark_oak:
logs:
- LOG_2:1,5,9,13
leaves:
- LEAVES_2:1,5,9,13
sapling: SAPLING:5
plantable-soil: []
max-log-distance-from-trunk: 3
max-leaf-distance-from-log: 5
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
leaf-loot:
0:
material: SAPLING:5
chance: 5
1:
material: APPLE
chance: 0.5
entire-tree-loot: []
required-tools: []
brown_mushroom:
logs:
- HUGE_MUSHROOM_1:15,10
leaves:
- HUGE_MUSHROOM_1:14,0,1,2,3,4,5,6,7,8,9
sapling: BROWN_MUSHROOM
plantable-soil:
- MYCEL
max-log-distance-from-trunk: 4
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: false
drop-original-log: false
drop-original-leaf: false
log-loot: []
leaf-loot:
0:
material: BROWN_MUSHROOM
chance: 25
entire-tree-loot: []
required-tools: []
red_mushroom:
logs:
- HUGE_MUSHROOM_2:15,10
leaves:
- HUGE_MUSHROOM_2:14,0,1,2,3,4,5,6,7,8,9
sapling: RED_MUSHROOM
plantable-soil:
- MYCEL
max-log-distance-from-trunk: 4
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: true
drop-original-log: false
drop-original-leaf: false
log-loot: []
leaf-loot:
0:
material: RED_MUSHROOM
chance: 25
entire-tree-loot: []
required-tools: []
# All soil types that the tree type's saplings can be planted on
global-plantable-soil:
- GRASS
- DIRT:0
- DIRT:1
- DIRT:2
# Custom loot that is available for all tree types
# The loot applies to each log broken in the tree
# To add more, increment the number by 1
# The chance is out of 100 and can contain decimals
# The default examples here are to show what you can do with custom loot
# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos%
global-log-loot:
0:
material: DIAMOND
chance: 0
1:
command: 'eco give %player% 5'
chance: 0
2:
material: GOLDEN_APPLE
command: 'broadcast %player% found a golden apple in a %type% tree at %xPos% %yPos% %zPos%!'
chance: 0
# Custom loot that is available for all tree types
# The loot applies to each leaf broken in the tree
# To add more, increment the number by 1
# The chance is out of 100 and can contain decimals
# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos%
global-leaf-loot:
0:
material: GOLDEN_APPLE
chance: 0.1
# Custom entire tree loot that is available for all tree types
# The loot will be dropped only one time for the entire tree
# To add more, increment the number by 1
# The chance is out of 100 and can contain decimals
# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos%
global-entire-tree-loot:
0:
material: DIAMOND
chance: 0
# Tools that must be used to topple over a tree
# Applies to all tree types
global-required-tools:
- WOOD_AXE
- STONE_AXE
- IRON_AXE
- GOLD_AXE
- DIAMOND_AXE

View File

@ -1,6 +1,6 @@
name: UltimateTimber
version: maven-version-number
authors: [Songoda, Esophose]
authors: [Songoda]
main: com.songoda.ultimatetimber.UltimateTimber
api-version: 1.13
softdepend: [mcMMO, Jobs, CoreProtect]

View File

@ -5,28 +5,20 @@ import com.songoda.core.SongodaPlugin;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.configuration.Config;
import com.songoda.core.hooks.LogManager;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.adapter.current.CurrentAdapter;
import com.songoda.ultimatetimber.adapter.legacy.LegacyAdapter;
import com.songoda.ultimatetimber.commands.CommandReload;
import com.songoda.ultimatetimber.commands.CommandToggle;
import com.songoda.ultimatetimber.manager.*;
import com.songoda.ultimatetimber.utils.NMSUtil;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Esophose
*/
public class UltimateTimber extends SongodaPlugin {
private static UltimateTimber INSTANCE;
private Set<Manager> managers;
private VersionAdapter versionAdapter;
private ChoppingManager choppingManager;
private ConfigurationManager configurationManager;
private com.songoda.core.commands.CommandManager commandManager;
@ -73,7 +65,6 @@ public class UltimateTimber extends SongodaPlugin {
this.treeFallManager = this.registerManager(TreeFallManager.class);
// Load version adapter and managers
this.setupVersionAdapter();
this.reloadConfig();
}
@ -106,17 +97,6 @@ public class UltimateTimber extends SongodaPlugin {
this.managers.forEach(Manager::disable);
}
/**
* Sets up the version adapter
*/
private void setupVersionAdapter() {
if (NMSUtil.getVersionNumber() > 12) {
this.versionAdapter = new CurrentAdapter();
} else {
this.versionAdapter = new LegacyAdapter();
}
}
/**
* Registers a manager
*
@ -135,15 +115,6 @@ public class UltimateTimber extends SongodaPlugin {
}
}
/**
* Gets the active version adapter being used
*
* @return The VersionAdapter being used for the plugin
*/
public VersionAdapter getVersionAdapter() {
return this.versionAdapter;
}
/**
* Gets the chopping manager
*

View File

@ -1,12 +1,15 @@
package com.songoda.ultimatetimber.animation;
import com.songoda.core.compatibility.CompatibleHand;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.tree.DetectedTree;
import com.songoda.ultimatetimber.tree.FallingTreeBlock;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockSet;
import com.songoda.ultimatetimber.utils.BlockUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -28,7 +31,7 @@ public abstract class TreeAnimation {
this.detectedTree = detectedTree;
this.player = player;
ItemStack itemInHand = UltimateTimber.getInstance().getVersionAdapter().getItemInHand(player);
ItemStack itemInHand = CompatibleHand.getHand(CompatibleHand.MAIN_HAND).getItem(player);
this.hasSilkTouch = itemInHand != null && itemInHand.hasItemMeta() && itemInHand.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH);
this.fallingTreeBlocks = new TreeBlockSet<>(); // Should be overridden in any subclasses that need to use it
@ -94,17 +97,17 @@ public abstract class TreeAnimation {
* @return A FallingTreeBlock that has been converted from a TreeBlock
*/
protected FallingTreeBlock convertToFallingBlock(TreeBlock treeBlock) {
VersionAdapter versionAdapter = UltimateTimber.getInstance().getVersionAdapter();
Location location = treeBlock.getLocation().clone().add(0.5, 0, 0.5);
Block block = treeBlock.getBlock();
CompatibleMaterial material = CompatibleMaterial.getMaterial(block);
if (block.getType().equals(Material.AIR)) {
if (material.isAir()) {
this.replaceBlock(treeBlock);
return null;
}
FallingBlock fallingBlock = versionAdapter.spawnFallingBlock(location, block);
UltimateTimber.getInstance().getVersionAdapter().configureFallingBlock(fallingBlock);
FallingBlock fallingBlock = BlockUtils.spawnFallingBlock(location, material);
BlockUtils.configureFallingBlock(fallingBlock);
FallingTreeBlock fallingTreeBlock = new FallingTreeBlock(fallingBlock, treeBlock.getTreeBlockType());
this.replaceBlock(treeBlock);

View File

@ -1,7 +1,7 @@
package com.songoda.ultimatetimber.animation;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.manager.ConfigurationManager;
import com.songoda.ultimatetimber.tree.DetectedTree;
import com.songoda.ultimatetimber.tree.FallingTreeBlock;
@ -10,6 +10,9 @@ import com.songoda.ultimatetimber.tree.TreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockSet;
import com.songoda.ultimatetimber.tree.TreeBlockType;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import com.songoda.ultimatetimber.utils.BlockUtils;
import com.songoda.ultimatetimber.utils.ParticleUtils;
import com.songoda.ultimatetimber.utils.SoundUtils;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
@ -29,7 +32,6 @@ public class TreeAnimationCrumble extends TreeAnimation {
@Override
public void playAnimation(Runnable whenFinished) {
UltimateTimber ultimateTimber = UltimateTimber.getInstance();
VersionAdapter versionAdapter = ultimateTimber.getVersionAdapter();
boolean useCustomSound = ConfigurationManager.Setting.USE_CUSTOM_SOUNDS.getBoolean();
boolean useCustomParticles = ConfigurationManager.Setting.USE_CUSTOM_PARTICLES.getBoolean();
@ -63,10 +65,10 @@ public class TreeAnimationCrumble extends TreeAnimation {
for (int i = 0; i < 3 && !partition.isEmpty(); i++) {
ITreeBlock<Block> treeBlock = partition.remove(0);
if (treeBlock.getTreeBlockType().equals(TreeBlockType.LOG)) {
if (td.getLogBlockData().stream().noneMatch(x -> x.isSimilar(treeBlock.getBlock())))
if (td.getLogMaterial().stream().noneMatch(x -> x.equals(CompatibleMaterial.getMaterial(treeBlock.getBlock()))))
continue;
} else if (treeBlock.getTreeBlockType().equals(TreeBlockType.LEAF)) {
if (td.getLeafBlockData().stream().noneMatch(x -> x.isSimilar(treeBlock.getBlock())))
if (td.getLeafMaterial().stream().noneMatch(x -> x.equals(CompatibleMaterial.getMaterial(treeBlock.getBlock()))))
continue;
}
@ -74,7 +76,7 @@ public class TreeAnimationCrumble extends TreeAnimation {
if (fallingTreeBlock == null)
continue;
versionAdapter.toggleGravityFallingBlock(fallingTreeBlock.getBlock(), true);
BlockUtils.toggleGravityFallingBlock(fallingTreeBlock.getBlock(), true);
fallingTreeBlock.getBlock().setVelocity(Vector.getRandom().setY(0).subtract(new Vector(0.5, 0, 0.5)).multiply(0.15));
TreeAnimationCrumble.this.fallingTreeBlocks.add(fallingTreeBlock);
@ -82,9 +84,9 @@ public class TreeAnimationCrumble extends TreeAnimation {
TreeAnimationCrumble.this.fallingTreeBlocks = new TreeBlockSet<>(fallingTreeBlock);
if (useCustomSound)
versionAdapter.playLandingSound(treeBlock);
SoundUtils.playLandingSound(treeBlock);
if (useCustomParticles)
versionAdapter.playFallingParticles(td, treeBlock);
ParticleUtils.playFallingParticles(treeBlock);
}
if (partition.isEmpty()) {

View File

@ -1,7 +1,7 @@
package com.songoda.ultimatetimber.animation;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.manager.ConfigurationManager;
import com.songoda.ultimatetimber.manager.TreeDefinitionManager;
import com.songoda.ultimatetimber.tree.DetectedTree;
@ -9,6 +9,8 @@ import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockType;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import com.songoda.ultimatetimber.utils.ParticleUtils;
import com.songoda.ultimatetimber.utils.SoundUtils;
import org.bukkit.block.Block;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
@ -30,7 +32,6 @@ public class TreeAnimationDisintegrate extends TreeAnimation {
public void playAnimation(Runnable whenFinished) {
UltimateTimber ultimateTimber = UltimateTimber.getInstance();
TreeDefinitionManager treeDefinitionManager = ultimateTimber.getTreeDefinitionManager();
VersionAdapter versionAdapter = ultimateTimber.getVersionAdapter();
boolean useCustomSound = ConfigurationManager.Setting.USE_CUSTOM_SOUNDS.getBoolean();
boolean useCustomParticles = ConfigurationManager.Setting.USE_CUSTOM_PARTICLES.getBoolean();
@ -71,19 +72,19 @@ public class TreeAnimationDisintegrate extends TreeAnimation {
if (!toDestroy.isEmpty()) {
ITreeBlock<Block> first = toDestroy.get(0);
if (useCustomSound)
versionAdapter.playLandingSound(first);
SoundUtils.playLandingSound(first);
for (ITreeBlock<Block> treeBlock : toDestroy) {
if (treeBlock.getTreeBlockType().equals(TreeBlockType.LOG)) {
if (td.getLogBlockData().stream().noneMatch(x -> x.isSimilar(treeBlock.getBlock())))
if (td.getLogMaterial().stream().noneMatch(x -> x.equals(CompatibleMaterial.getMaterial(treeBlock.getBlock()))))
continue;
} else if (treeBlock.getTreeBlockType().equals(TreeBlockType.LEAF)) {
if (td.getLeafBlockData().stream().noneMatch(x -> x.isSimilar(treeBlock.getBlock())))
if (td.getLeafMaterial().stream().noneMatch(x -> x.equals(CompatibleMaterial.getMaterial(treeBlock.getBlock()))))
continue;
}
if (useCustomParticles)
versionAdapter.playFallingParticles(td, treeBlock);
ParticleUtils.playFallingParticles(treeBlock);
treeDefinitionManager.dropTreeLoot(td, treeBlock, p, hst, false);
TreeAnimationDisintegrate.this.replaceBlock((TreeBlock) treeBlock);
}

View File

@ -1,7 +1,6 @@
package com.songoda.ultimatetimber.animation;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.manager.ConfigurationManager;
import com.songoda.ultimatetimber.manager.TreeAnimationManager;
import com.songoda.ultimatetimber.tree.DetectedTree;
@ -9,6 +8,9 @@ import com.songoda.ultimatetimber.tree.FallingTreeBlock;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockSet;
import com.songoda.ultimatetimber.utils.BlockUtils;
import com.songoda.ultimatetimber.utils.ParticleUtils;
import com.songoda.ultimatetimber.utils.SoundUtils;
import org.bukkit.block.Block;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
@ -24,7 +26,6 @@ public class TreeAnimationFancy extends TreeAnimation {
@Override
public void playAnimation(Runnable whenFinished) {
UltimateTimber ultimateTimber = UltimateTimber.getInstance();
VersionAdapter versionAdapter = ultimateTimber.getVersionAdapter();
boolean useCustomSound = ConfigurationManager.Setting.USE_CUSTOM_SOUNDS.getBoolean();
boolean useCustomParticles = ConfigurationManager.Setting.USE_CUSTOM_PARTICLES.getBoolean();
@ -33,7 +34,7 @@ public class TreeAnimationFancy extends TreeAnimation {
FallingTreeBlock initialFallingBlock = this.convertToFallingBlock((TreeBlock)this.detectedTree.getDetectedTreeBlocks().getInitialLogBlock());
if (useCustomSound)
versionAdapter.playFallingSound(initialTreeBlock);
SoundUtils.playFallingSound(initialTreeBlock);
Vector velocityVector = initialTreeBlock.getLocation().clone().subtract(this.player.getLocation().clone()).toVector().normalize().setY(0);
@ -47,7 +48,7 @@ public class TreeAnimationFancy extends TreeAnimation {
this.fallingTreeBlocks.add(fallingTreeBlock);
if (useCustomParticles)
versionAdapter.playFallingParticles(this.detectedTree.getTreeDefinition(), treeBlock);
ParticleUtils.playFallingParticles(treeBlock);
double multiplier = (treeBlock.getLocation().getY() - this.player.getLocation().getY()) * 0.05;
fallingBlock.setVelocity(velocityVector.clone().multiply(multiplier));
@ -62,7 +63,7 @@ public class TreeAnimationFancy extends TreeAnimation {
if (this.timer == 0) {
for (ITreeBlock<FallingBlock> fallingTreeBlock : TreeAnimationFancy.this.fallingTreeBlocks.getAllTreeBlocks()) {
FallingBlock fallingBlock = fallingTreeBlock.getBlock();
versionAdapter.toggleGravityFallingBlock(fallingBlock, true);
BlockUtils.toggleGravityFallingBlock(fallingBlock, true);
fallingBlock.setVelocity(fallingBlock.getVelocity().multiply(1.5));
}
}

View File

@ -1,12 +1,13 @@
package com.songoda.ultimatetimber.animation;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.manager.ConfigurationManager;
import com.songoda.ultimatetimber.manager.TreeDefinitionManager;
import com.songoda.ultimatetimber.tree.DetectedTree;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlock;
import com.songoda.ultimatetimber.utils.ParticleUtils;
import com.songoda.ultimatetimber.utils.SoundUtils;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
@ -19,14 +20,13 @@ public class TreeAnimationNone extends TreeAnimation {
@Override
public void playAnimation(Runnable whenFinished) {
TreeDefinitionManager treeDefinitionManager = UltimateTimber.getInstance().getTreeDefinitionManager();
VersionAdapter versionAdapter = UltimateTimber.getInstance().getVersionAdapter();
if (ConfigurationManager.Setting.USE_CUSTOM_SOUNDS.getBoolean())
versionAdapter.playFallingSound(this.detectedTree.getDetectedTreeBlocks().getInitialLogBlock());
SoundUtils.playFallingSound(this.detectedTree.getDetectedTreeBlocks().getInitialLogBlock());
if (ConfigurationManager.Setting.USE_CUSTOM_PARTICLES.getBoolean())
for (ITreeBlock<Block> treeBlock : this.detectedTree.getDetectedTreeBlocks().getAllTreeBlocks())
versionAdapter.playFallingParticles(this.detectedTree.getTreeDefinition(), treeBlock);
ParticleUtils.playFallingParticles(treeBlock);
for (ITreeBlock<Block> treeBlock : this.detectedTree.getDetectedTreeBlocks().getAllTreeBlocks()) {
treeDefinitionManager.dropTreeLoot(this.detectedTree.getTreeDefinition(), treeBlock, this.player, this.hasSilkTouch, false);

View File

@ -1,10 +1,8 @@
package com.songoda.ultimatetimber.manager;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapterType;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.List;
@ -181,8 +179,7 @@ public class ConfigurationManager extends Manager {
// Create the new config if it doesn't exist
if (!configFile.exists()) {
boolean isCurrentConfig = this.plugin.getVersionAdapter().getVersionAdapterType() == VersionAdapterType.CURRENT;
String newConfigName = "config-" + (isCurrentConfig ? "current" : "legacy") + ".yml";
String newConfigName = "config.yml";
File newConfigFile = new File(this.plugin.getDataFolder() + "/" + newConfigName);
this.plugin.saveResource(newConfigName, false);
newConfigFile.renameTo(configFile);

View File

@ -1,7 +1,7 @@
package com.songoda.ultimatetimber.manager;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.IBlockData;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockType;
import com.songoda.ultimatetimber.tree.TreeDefinition;
@ -84,8 +84,8 @@ public class SaplingManager extends Manager {
Block block = treeBlock.getLocation().getBlock();
Block blockBelow = block.getRelative(BlockFace.DOWN);
boolean isValidSoil = false;
for (IBlockData soilBlockData : treeDefinitionManager.getPlantableSoilBlockData(treeDefinition)) {
if (soilBlockData.isSimilar(blockBelow)) {
for (CompatibleMaterial soilMaterial : treeDefinitionManager.getPlantableSoilMaterial(treeDefinition)) {
if (soilMaterial.equals(CompatibleMaterial.getMaterial(blockBelow))) {
isValidSoil = true;
break;
}
@ -94,8 +94,8 @@ public class SaplingManager extends Manager {
if (!isValidSoil)
return;
IBlockData saplingBlockData = treeDefinition.getSaplingBlockData();
saplingBlockData.setBlock(block);
CompatibleMaterial material = treeDefinition.getSaplingMaterial();
material.applyToBlock(block);
int cooldown = ConfigurationManager.Setting.REPLANT_SAPLINGS_COOLDOWN.getInt();
if (cooldown != 0) {

View File

@ -1,7 +1,6 @@
package com.songoda.ultimatetimber.manager;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.animation.TreeAnimation;
import com.songoda.ultimatetimber.animation.TreeAnimationCrumble;
import com.songoda.ultimatetimber.animation.TreeAnimationDisintegrate;
@ -11,6 +10,8 @@ import com.songoda.ultimatetimber.animation.TreeAnimationType;
import com.songoda.ultimatetimber.tree.DetectedTree;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import com.songoda.ultimatetimber.utils.ParticleUtils;
import com.songoda.ultimatetimber.utils.SoundUtils;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
@ -71,7 +72,7 @@ public class TreeAnimationManager extends Manager implements Listener, Runnable
* Plays an animation for toppling a tree
*
* @param detectedTree The DetectedTree
* @param player The Player who toppled the tree
* @param player The Player who toppled the tree
*/
public void runAnimation(DetectedTree detectedTree, Player player) {
switch (TreeAnimationType.fromString(ConfigurationManager.Setting.TREE_ANIMATION_TYPE.getString())) {
@ -141,19 +142,18 @@ public class TreeAnimationManager extends Manager implements Listener, Runnable
* Reacts to a falling block hitting the ground
*
* @param treeAnimation The tree animation for the falling block
* @param treeBlock The tree block to impact
* @param treeBlock The tree block to impact
*/
public void runFallingBlockImpact(TreeAnimation treeAnimation, ITreeBlock<FallingBlock> treeBlock) {
TreeDefinitionManager treeDefinitionManager = this.plugin.getTreeDefinitionManager();
VersionAdapter versionAdapter = this.plugin.getVersionAdapter();
boolean useCustomSound = ConfigurationManager.Setting.USE_CUSTOM_SOUNDS.getBoolean();
boolean useCustomParticles = ConfigurationManager.Setting.USE_CUSTOM_PARTICLES.getBoolean();
TreeDefinition treeDefinition = treeAnimation.getDetectedTree().getTreeDefinition();
if (useCustomParticles)
versionAdapter.playLandingParticles(treeDefinition, treeBlock);
ParticleUtils.playLandingParticles(treeBlock);
if (useCustomSound)
versionAdapter.playLandingSound(treeBlock);
SoundUtils.playLandingSound(treeBlock);
treeDefinitionManager.dropTreeLoot(treeDefinition, treeBlock, treeAnimation.getPlayer(), treeAnimation.hasSilkTouch(), false);
this.plugin.getSaplingManager().replantSaplingWithChance(treeDefinition, treeBlock);
@ -173,7 +173,7 @@ public class TreeAnimationManager extends Manager implements Listener, Runnable
int damage = ConfigurationManager.Setting.FALLING_BLOCK_DAMAGE.getInt();
for (Entity entity : fallingBlock.getNearbyEntities(0.5, 0.5, 0.5)) {
if (!(entity instanceof LivingEntity)) continue;
((LivingEntity)entity).damage(damage, fallingBlock);
((LivingEntity) entity).damage(damage, fallingBlock);
}
}
@ -187,5 +187,4 @@ public class TreeAnimationManager extends Manager implements Listener, Runnable
event.setCancelled(true);
}
}

View File

@ -1,13 +1,13 @@
package com.songoda.ultimatetimber.manager;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.hooks.McMMOHook;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.IBlockData;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockType;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import com.songoda.ultimatetimber.tree.TreeLoot;
import com.songoda.ultimatetimber.utils.BlockUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
@ -21,10 +21,10 @@ import java.util.*;
public class TreeDefinitionManager extends Manager {
private final Random random;
private Set<TreeDefinition> treeDefinitions;
private Set<IBlockData> globalPlantableSoil;
private Set<TreeLoot> globalLogLoot, globalLeafLoot, globalEntireTreeLoot;
private Set<ItemStack> globalRequiredTools;
private final Set<TreeDefinition> treeDefinitions;
private final Set<CompatibleMaterial> globalPlantableSoil;
private final Set<TreeLoot> globalLogLoot, globalLeafLoot, globalEntireTreeLoot;
private final Set<ItemStack> globalRequiredTools;
public TreeDefinitionManager(UltimateTimber ultimateTimber) {
super(ultimateTimber);
@ -46,7 +46,6 @@ public class TreeDefinitionManager extends Manager {
this.globalEntireTreeLoot.clear();
this.globalRequiredTools.clear();
VersionAdapter versionAdapter = this.plugin.getVersionAdapter();
ConfigurationManager configurationManager = this.plugin.getConfigurationManager();
YamlConfiguration config = configurationManager.getConfig();
@ -56,10 +55,10 @@ public class TreeDefinitionManager extends Manager {
for (String key : treeSection.getKeys(false)) {
ConfigurationSection tree = treeSection.getConfigurationSection(key);
Set<IBlockData> logBlockData = new HashSet<>();
Set<IBlockData> leafBlockData = new HashSet<>();
IBlockData saplingBlockData;
Set<IBlockData> plantableSoilBlockData = new HashSet<>();
Set<CompatibleMaterial> logMaterials = new HashSet<>();
Set<CompatibleMaterial> leafMaterials = new HashSet<>();
CompatibleMaterial saplingMaterial;
Set<CompatibleMaterial> plantableSoilMaterial = new HashSet<>();
double maxLogDistanceFromTrunk;
int maxLeafDistanceFromLog;
boolean detectLeavesDiagonally;
@ -70,22 +69,25 @@ public class TreeDefinitionManager extends Manager {
Set<TreeLoot> entireTreeLoot = new HashSet<>();
Set<ItemStack> requiredTools = new HashSet<>();
for (String blockDataString : tree.getStringList("logs")) {
IBlockData blockData = versionAdapter.parseBlockDataFromString(blockDataString);
if (blockData == null || blockData.getMaterial() == null) continue top;
logBlockData.add(blockData);
for (String materialString : tree.getStringList("logs")) {
CompatibleMaterial material = CompatibleMaterial.getMaterial(materialString);
if (material == null || material.getMaterial() == null) continue top;
logMaterials.add(material);
}
for (String blockDataString : tree.getStringList("leaves")) {
IBlockData blockData = versionAdapter.parseBlockDataFromString(blockDataString);
if (blockData == null || blockData.getMaterial() == null) continue top;
leafBlockData.add(blockData);
for (String materialString : tree.getStringList("leaves")) {
CompatibleMaterial material = CompatibleMaterial.getMaterial(materialString);
if (material == null || material.getMaterial() == null) continue top;
leafMaterials.add(material);
}
saplingBlockData = versionAdapter.parseBlockDataFromString(tree.getString("sapling"));
saplingMaterial = CompatibleMaterial.getMaterial(tree.getString("sapling"));
for (String blockDataString : tree.getStringList("plantable-soil"))
plantableSoilBlockData.add(versionAdapter.parseBlockDataFromString(blockDataString));
for (String materialString : tree.getStringList("plantable-soil")) {
CompatibleMaterial material = CompatibleMaterial.getMaterial(materialString);
if (material == null || material.getMaterial() == null) continue top;
plantableSoilMaterial.add(material);
}
maxLogDistanceFromTrunk = tree.getDouble("max-log-distance-from-trunk");
maxLeafDistanceFromLog = tree.getInt("max-leaf-distance-from-log");
@ -96,53 +98,53 @@ public class TreeDefinitionManager extends Manager {
ConfigurationSection logLootSection = tree.getConfigurationSection("log-loot");
if (logLootSection != null)
for (String lootKey : logLootSection.getKeys(false))
logLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LOG, logLootSection.getConfigurationSection(lootKey)));
logLoot.add(this.getTreeLootEntry(TreeBlockType.LOG, logLootSection.getConfigurationSection(lootKey)));
ConfigurationSection leafLootSection = tree.getConfigurationSection("leaf-loot");
if (leafLootSection != null)
for (String lootKey : leafLootSection.getKeys(false))
leafLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LEAF, leafLootSection.getConfigurationSection(lootKey)));
leafLoot.add(this.getTreeLootEntry(TreeBlockType.LEAF, leafLootSection.getConfigurationSection(lootKey)));
ConfigurationSection entireTreeLootSection = tree.getConfigurationSection("entire-tree-loot");
if (entireTreeLootSection != null)
for (String lootKey : entireTreeLootSection.getKeys(false))
entireTreeLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LEAF, entireTreeLootSection.getConfigurationSection(lootKey)));
entireTreeLoot.add(this.getTreeLootEntry(TreeBlockType.LEAF, entireTreeLootSection.getConfigurationSection(lootKey)));
for (String itemStackString : tree.getStringList("required-tools")) {
ItemStack tool = versionAdapter.parseItemStackFromString(itemStackString);
if (tool == null) continue top;
requiredTools.add(tool);
CompatibleMaterial material = CompatibleMaterial.getMaterial(itemStackString);
if (material == null) continue top;
requiredTools.add(material.getItem());
}
this.treeDefinitions.add(new TreeDefinition(key, logBlockData, leafBlockData, saplingBlockData, plantableSoilBlockData, maxLogDistanceFromTrunk,
this.treeDefinitions.add(new TreeDefinition(key, logMaterials, leafMaterials, saplingMaterial, plantableSoilMaterial, maxLogDistanceFromTrunk,
maxLeafDistanceFromLog, detectLeavesDiagonally, dropOriginalLog, dropOriginalLeaf, logLoot, leafLoot, entireTreeLoot, requiredTools));
}
// Load global plantable soil
for (String blockDataString : config.getStringList("global-plantable-soil"))
this.globalPlantableSoil.add(versionAdapter.parseBlockDataFromString(blockDataString));
for (String material : config.getStringList("global-plantable-soil"))
this.globalPlantableSoil.add(CompatibleMaterial.getMaterial(material));
// Load global log drops
ConfigurationSection logSection = config.getConfigurationSection("global-log-loot");
if (logSection != null)
for (String lootKey : logSection.getKeys(false))
this.globalLogLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LOG, logSection.getConfigurationSection(lootKey)));
this.globalLogLoot.add(this.getTreeLootEntry(TreeBlockType.LOG, logSection.getConfigurationSection(lootKey)));
// Load global leaf drops
ConfigurationSection leafSection = config.getConfigurationSection("global-leaf-loot");
if (leafSection != null)
for (String lootKey : leafSection.getKeys(false))
this.globalLeafLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LEAF, leafSection.getConfigurationSection(lootKey)));
this.globalLeafLoot.add(this.getTreeLootEntry(TreeBlockType.LEAF, leafSection.getConfigurationSection(lootKey)));
// Load global entire tree drops
ConfigurationSection entireTreeSection = config.getConfigurationSection("global-entire-tree-loot");
if (entireTreeSection != null)
for (String lootKey : entireTreeSection.getKeys(false))
this.globalEntireTreeLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LOG, entireTreeSection.getConfigurationSection(lootKey)));
this.globalEntireTreeLoot.add(this.getTreeLootEntry(TreeBlockType.LOG, entireTreeSection.getConfigurationSection(lootKey)));
// Load global tools
for (String itemStackString : config.getStringList("global-required-tools")) {
ItemStack tool = versionAdapter.parseItemStackFromString(itemStackString);
ItemStack tool = CompatibleMaterial.getMaterial(itemStackString).getItem();
if (tool == null) continue;
this.globalRequiredTools.add(tool);
}
@ -176,8 +178,8 @@ public class TreeDefinitionManager extends Manager {
switch (treeBlockType) {
case LOG:
for (TreeDefinition treeDefinition : possibleTreeDefinitions) {
for (IBlockData logBlockData : treeDefinition.getLogBlockData()) {
if (logBlockData.isSimilar(block)) {
for (CompatibleMaterial material : treeDefinition.getLogMaterial()) {
if (material.equals(CompatibleMaterial.getMaterial(block))) {
matchingTreeDefinitions.add(treeDefinition);
break;
}
@ -186,8 +188,8 @@ public class TreeDefinitionManager extends Manager {
break;
case LEAF:
for (TreeDefinition treeDefinition : possibleTreeDefinitions) {
for (IBlockData leafBlockData : treeDefinition.getLeafBlockData()) {
if (leafBlockData.isSimilar(block)) {
for (CompatibleMaterial material : treeDefinition.getLeafMaterial()) {
if (material.equals(CompatibleMaterial.getMaterial(block))) {
matchingTreeDefinitions.add(treeDefinition);
break;
}
@ -246,8 +248,6 @@ public class TreeDefinitionManager extends Manager {
* @param isForEntireTree If the loot is for the entire tree
*/
public void dropTreeLoot(TreeDefinition treeDefinition, ITreeBlock treeBlock, Player player, boolean hasSilkTouch, boolean isForEntireTree) {
VersionAdapter versionAdapter = this.plugin.getVersionAdapter();
boolean addToInventory = ConfigurationManager.Setting.ADD_ITEMS_TO_INVENTORY.getBoolean();
boolean hasBonusChance = player.hasPermission("ultimatetimber.bonusloot");
List<ItemStack> lootedItems = new ArrayList<>();
@ -261,8 +261,8 @@ public class TreeDefinitionManager extends Manager {
} else {
if (ConfigurationManager.Setting.APPLY_SILK_TOUCH.getBoolean() && hasSilkTouch) {
if (McMMOHook.hasWoodcuttingDoubleDrops(player))
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
lootedItems.addAll(BlockUtils.getBlockDrops(treeBlock));
lootedItems.addAll(BlockUtils.getBlockDrops(treeBlock));
} else {
switch (treeBlock.getTreeBlockType()) {
case LOG:
@ -270,8 +270,8 @@ public class TreeDefinitionManager extends Manager {
toTry.addAll(this.globalLogLoot);
if (treeDefinition.shouldDropOriginalLog()) {
if (McMMOHook.hasWoodcuttingDoubleDrops(player))
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
lootedItems.addAll(BlockUtils.getBlockDrops(treeBlock));
lootedItems.addAll(BlockUtils.getBlockDrops(treeBlock));
}
break;
case LEAF:
@ -279,8 +279,8 @@ public class TreeDefinitionManager extends Manager {
toTry.addAll(this.globalLeafLoot);
if (treeDefinition.shouldDropOriginalLeaf()) {
if (McMMOHook.hasWoodcuttingDoubleDrops(player))
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock));
lootedItems.addAll(BlockUtils.getBlockDrops(treeBlock));
lootedItems.addAll(BlockUtils.getBlockDrops(treeBlock));
}
break;
}
@ -290,6 +290,7 @@ public class TreeDefinitionManager extends Manager {
// Roll the dice
double bonusLootMultiplier = ConfigurationManager.Setting.BONUS_LOOT_MULTIPLIER.getDouble();
for (TreeLoot treeLoot : toTry) {
if (treeLoot == null) continue;
double chance = hasBonusChance ? treeLoot.getChance() * bonusLootMultiplier : treeLoot.getChance();
if (this.random.nextDouble() > chance / 100)
continue;
@ -337,9 +338,9 @@ public class TreeDefinitionManager extends Manager {
* @param treeDefinition The TreeDefinition
* @return A Set of IBlockData of plantable soil
*/
public Set<IBlockData> getPlantableSoilBlockData(TreeDefinition treeDefinition) {
Set<IBlockData> plantableSoilBlockData = new HashSet<>();
plantableSoilBlockData.addAll(treeDefinition.getPlantableSoilBlockData());
public Set<CompatibleMaterial> getPlantableSoilMaterial(TreeDefinition treeDefinition) {
Set<CompatibleMaterial> plantableSoilBlockData = new HashSet<>();
plantableSoilBlockData.addAll(treeDefinition.getPlantableSoilMaterial());
plantableSoilBlockData.addAll(this.globalPlantableSoil);
return plantableSoilBlockData;
}
@ -347,14 +348,15 @@ public class TreeDefinitionManager extends Manager {
/**
* 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) {
private TreeLoot getTreeLootEntry(TreeBlockType treeBlockType, ConfigurationSection configurationSection) {
String material = configurationSection.getString("material");
ItemStack item = material != null ? versionAdapter.parseItemStackFromString(material) : null;
CompatibleMaterial compatibleMaterial = material == null ? null : CompatibleMaterial.getMaterial(material);
ItemStack item = compatibleMaterial == null ? null : compatibleMaterial.getItem();
String command = configurationSection.getString("command");
double chance = configurationSection.getDouble("chance");
return new TreeLoot(treeBlockType, item, command, chance);

View File

@ -1,7 +1,7 @@
package com.songoda.ultimatetimber.manager;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.IBlockData;
import com.songoda.ultimatetimber.tree.*;
import org.bukkit.Location;
import org.bukkit.block.Block;
@ -129,8 +129,8 @@ public class TreeDetectionManager extends Manager {
Block blockBelow = block.getRelative(BlockFace.DOWN);
boolean blockBelowIsLog = this.isValidLogType(possibleTreeDefinitions, null, blockBelow);
boolean blockBelowIsSoil = false;
for (IBlockData blockData : treeDefinitionManager.getPlantableSoilBlockData(actualTreeDefinition)) {
if (blockData.isSimilar(blockBelow)) {
for (CompatibleMaterial material : treeDefinitionManager.getPlantableSoilMaterial(actualTreeDefinition)) {
if (material.equals(CompatibleMaterial.getMaterial(blockBelow))) {
blockBelowIsSoil = true;
break;
}
@ -227,8 +227,8 @@ public class TreeDetectionManager extends Manager {
// Check if it matches the tree definition
boolean isCorrectType = false;
for (TreeDefinition treeDefinition : treeDefinitions) {
for (IBlockData logBlockData : treeDefinition.getLogBlockData()) {
if (logBlockData.isSimilar(block)) {
for (CompatibleMaterial material : treeDefinition.getLogMaterial()) {
if (material.equals(CompatibleMaterial.getMaterial(block))) {
isCorrectType = true;
break;
}
@ -271,8 +271,8 @@ public class TreeDetectionManager extends Manager {
// Check if it matches the tree definition
boolean isCorrectType = false;
for (TreeDefinition treeDefinition : treeDefinitions) {
for (IBlockData leafBlockData : treeDefinition.getLeafBlockData()) {
if (leafBlockData.isSimilar(block)) {
for (CompatibleMaterial material : treeDefinition.getLeafMaterial()) {
if (material.equals(CompatibleMaterial.getMaterial(block))) {
isCorrectType = true;
break;
}

View File

@ -1,10 +1,11 @@
package com.songoda.ultimatetimber.manager;
import com.songoda.core.compatibility.CompatibleHand;
import com.songoda.core.hooks.JobsHook;
import com.songoda.core.hooks.LogManager;
import com.songoda.core.hooks.McMMOHook;
import com.songoda.core.utils.ItemUtils;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.events.TreeFallEvent;
import com.songoda.ultimatetimber.events.TreeFellEvent;
import com.songoda.ultimatetimber.misc.OnlyToppleWhile;
@ -50,11 +51,10 @@ public class TreeFallManager extends Manager implements Listener {
TreeAnimationManager treeAnimationManager = this.plugin.getTreeAnimationManager();
ChoppingManager choppingManager = this.plugin.getChoppingManager();
SaplingManager saplingManager = this.plugin.getSaplingManager();
VersionAdapter versionAdapter = this.plugin.getVersionAdapter();
Player player = event.getPlayer();
Block block = event.getBlock();
ItemStack tool = versionAdapter.getItemInHand(player);
ItemStack tool = CompatibleHand.getHand(event).getItem(player);
// Protect saplings
if (saplingManager.isSaplingProtected(block)) {
@ -115,7 +115,7 @@ public class TreeFallManager extends Manager implements Listener {
return;
int toolDamage = this.getToolDamage(detectedTree.getDetectedTreeBlocks(), tool.containsEnchantment(Enchantment.SILK_TOUCH));
if (ConfigurationManager.Setting.PROTECT_TOOL.getBoolean() && !versionAdapter.hasEnoughDurability(tool, toolDamage))
if (ConfigurationManager.Setting.PROTECT_TOOL.getBoolean() && !ItemUtils.hasEnoughDurability(tool, toolDamage))
return;
// Trigger fall event
@ -136,7 +136,7 @@ public class TreeFallManager extends Manager implements Listener {
}
if (!player.getGameMode().equals(GameMode.CREATIVE))
versionAdapter.applyToolDurability(player, toolDamage);
ItemUtils.addDamage(tool, toolDamage);
McMMOHook.addWoodcutting(player, detectedTree.getDetectedTreeBlocks().getAllTreeBlocks().stream()
.map(ITreeBlock::getBlock).collect(Collectors.toList()));

View File

@ -0,0 +1,49 @@
package com.songoda.ultimatetimber.utils;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.FallingBlock;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class BlockUtils {
public static Collection<ItemStack> getBlockDrops(ITreeBlock treeBlock) {
Set<ItemStack> drops = new HashSet<>();
if (treeBlock.getBlock() instanceof Block) {
Block block = (Block)treeBlock.getBlock();
CompatibleMaterial material = CompatibleMaterial.getMaterial(block);
if (material.isAir())
return drops;
drops.add(CompatibleMaterial.getMaterial(block).getItem());
} else if (treeBlock.getBlock() instanceof FallingBlock) {
CompatibleMaterial material = CompatibleMaterial.getMaterial((FallingBlock)treeBlock.getBlock());
if (material == null)
return drops;
drops.add(material.getItem());
}
return drops;
}
public static void toggleGravityFallingBlock(FallingBlock fallingBlock, boolean applyGravity) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9))
fallingBlock.setGravity(applyGravity);
}
public static FallingBlock spawnFallingBlock(Location location, CompatibleMaterial material) {
return location.getWorld().spawnFallingBlock(location, material.getMaterial(), material.getData());
}
public static void configureFallingBlock(FallingBlock fallingBlock) {
toggleGravityFallingBlock(fallingBlock, false);
fallingBlock.setDropItem(false);
fallingBlock.setHurtEntities(false);
}
}

View File

@ -0,0 +1,68 @@
package com.songoda.ultimatetimber.utils;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.FallingBlock;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
public class ParticleUtils {
public static void playFallingParticles(ITreeBlock treeBlock) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
BlockData blockData;
if (treeBlock.getBlock() instanceof Block) {
blockData = ((Block) treeBlock.getBlock()).getBlockData();
} else if (treeBlock.getBlock() instanceof FallingBlock) {
blockData = ((FallingBlock) treeBlock.getBlock()).getBlockData();
} else return;
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
location.getWorld().spawnParticle(Particle.BLOCK_DUST, location, 10, blockData);
} else {
Collection<ItemStack> blockDrops = BlockUtils.getBlockDrops(treeBlock);
if (!blockDrops.iterator().hasNext())
return;
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
if (ServerVersion.isServerVersion(ServerVersion.V1_8)) {
location.getWorld().playEffect(location, Effect.SMOKE, 4);
} else {
location.getWorld().spawnParticle(Particle.BLOCK_DUST, location, 10, blockDrops.iterator().next().getData());
}
}
}
public static void playLandingParticles(ITreeBlock treeBlock) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
BlockData blockData;
if (treeBlock.getBlock() instanceof Block) {
blockData = ((Block) treeBlock.getBlock()).getBlockData();
} else if (treeBlock.getBlock() instanceof FallingBlock) {
blockData = ((FallingBlock) treeBlock.getBlock()).getBlockData();
} else return;
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
location.getWorld().spawnParticle(Particle.BLOCK_CRACK, location, 10, blockData);
} else {
Collection<ItemStack> blockDrops = BlockUtils.getBlockDrops(treeBlock);
if (!blockDrops.iterator().hasNext())
return;
Location location = treeBlock.getLocation().clone().add(0.5, 0.5, 0.5);
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) {
location.getWorld().spawnParticle(Particle.BLOCK_CRACK, location, 10, blockDrops.iterator().next().getData());
} else {
location.getWorld().playEffect(location, Effect.SMOKE, 4);
}
}
}
}

View File

@ -0,0 +1,27 @@
package com.songoda.ultimatetimber.utils;
import com.songoda.core.compatibility.CompatibleSound;
import com.songoda.ultimatetimber.tree.ITreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockType;
import org.bukkit.Location;
public class SoundUtils {
public static void playFallingSound(ITreeBlock block) {
Location location = block.getLocation();
if (location.getWorld() == null) return;
CompatibleSound.BLOCK_CHEST_OPEN.play(location.getWorld(), location, 2F, 0.1F);
}
public static void playLandingSound(ITreeBlock block) {
Location location = block.getLocation();
if (location.getWorld() == null) return;
if (block.getTreeBlockType().equals(TreeBlockType.LOG)) {
CompatibleSound.BLOCK_WOOD_FALL.play(location.getWorld(), location, 2F, 0.1F);
} else {
CompatibleSound.BLOCK_GRASS_BREAK.play(location.getWorld(), location, 0.5F, 0.75F);
}
}
}

View File

@ -2,15 +2,13 @@
<groupId>com.songoda</groupId>
<artifactId>UltimateTimber</artifactId>
<version>2.0.9b</version>
<version>2.1</version>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>UltimateTimber/Core</module>
<module>UltimateTimber/Plugin</module>
<module>UltimateTimber-Adapter/Current</module>
<module>UltimateTimber-Adapter/Legacy</module>
</modules>
<repositories>