mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2024-11-28 00:55:29 +01:00
fixed #252 double drops
This commit is contained in:
parent
e9b417f191
commit
c1a98bc5a5
@ -1,33 +1,33 @@
|
|||||||
package net.Indyuce.mmocore.api.droptable.dropitem;
|
package net.Indyuce.mmocore.api.droptable.dropitem;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.droptable.DropTable;
|
import net.Indyuce.mmocore.api.droptable.DropTable;
|
||||||
import net.Indyuce.mmocore.api.droptable.condition.ConditionInstance;
|
import net.Indyuce.mmocore.api.droptable.condition.ConditionInstance;
|
||||||
import net.Indyuce.mmocore.api.loot.LootBuilder;
|
import net.Indyuce.mmocore.api.loot.LootBuilder;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import org.apache.commons.lang.Validate;
|
||||||
|
|
||||||
public class DropTableDropItem extends DropItem {
|
public class DropTableDropItem extends DropItem {
|
||||||
private final DropTable dropTable;
|
private final DropTable dropTable;
|
||||||
|
|
||||||
public DropTableDropItem(MMOLineConfig config) {
|
public DropTableDropItem(MMOLineConfig config) {
|
||||||
super(config);
|
super(config);
|
||||||
|
|
||||||
config.validate("id");
|
config.validate("id");
|
||||||
String id = config.getString("id");
|
String id = config.getString("id");
|
||||||
|
|
||||||
Validate.isTrue(MMOCore.plugin.dropTableManager.has(id), "Could not find drop table " + id);
|
Validate.isTrue(MMOCore.plugin.dropTableManager.has(id), "Could not find drop table " + id);
|
||||||
this.dropTable = MMOCore.plugin.dropTableManager.get(id);
|
this.dropTable = MMOCore.plugin.dropTableManager.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collect(LootBuilder builder) {
|
public void collect(LootBuilder builder) {
|
||||||
PlayerData data = builder.getEntity();
|
PlayerData data = builder.getEntity();
|
||||||
if(!data.isOnline()) return;
|
if (!data.isOnline()) return;
|
||||||
if (dropTable.areConditionsMet(new ConditionInstance(data.getPlayer())))
|
|
||||||
for (int j = 0; j < rollAmount(); j++)
|
if (dropTable.areConditionsMet(new ConditionInstance(data.getPlayer())))
|
||||||
builder.addLoot(dropTable.collect(builder));
|
for (int j = 0; j < rollAmount(); j++)
|
||||||
}
|
dropTable.collect(builder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,5 @@
|
|||||||
package net.Indyuce.mmocore.listener;
|
package net.Indyuce.mmocore.listener;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Statistic;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
|
||||||
import org.bukkit.event.block.BlockFormEvent;
|
|
||||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
|
||||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.metadata.FixedMetadataValue;
|
|
||||||
|
|
||||||
import io.lumine.mythic.lib.UtilityMethods;
|
import io.lumine.mythic.lib.UtilityMethods;
|
||||||
import io.lumine.mythic.utils.Schedulers;
|
import io.lumine.mythic.utils.Schedulers;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
@ -28,200 +8,212 @@ import net.Indyuce.mmocore.api.block.BlockInfo.BlockInfoOption;
|
|||||||
import net.Indyuce.mmocore.api.block.VanillaBlockType;
|
import net.Indyuce.mmocore.api.block.VanillaBlockType;
|
||||||
import net.Indyuce.mmocore.api.droptable.condition.ConditionInstance;
|
import net.Indyuce.mmocore.api.droptable.condition.ConditionInstance;
|
||||||
import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
|
import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
|
||||||
|
import net.Indyuce.mmocore.api.loot.LootBuilder;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.*;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BlockListener implements Listener {
|
public class BlockListener implements Listener {
|
||||||
private static final BlockFace[] order = { BlockFace.UP, BlockFace.DOWN, BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH };
|
private static final BlockFace[] order = {BlockFace.UP, BlockFace.DOWN, BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH};
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
public void onCustomBreak(BlockBreakEvent event) {
|
public void onCustomBreak(BlockBreakEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
if (player.getGameMode() == GameMode.CREATIVE)
|
if (player.getGameMode() == GameMode.CREATIVE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
String savedData = event.getBlock().getBlockData().getAsString();
|
String savedData = event.getBlock().getBlockData().getAsString();
|
||||||
Block block = event.getBlock();
|
Block block = event.getBlock();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for custom mining in the current region first.
|
* Check for custom mining in the current region first.
|
||||||
*/
|
*/
|
||||||
boolean customMine = MMOCore.plugin.mineManager.isEnabled(player, block.getLocation());
|
boolean customMine = MMOCore.plugin.mineManager.isEnabled(player, block.getLocation());
|
||||||
if (!customMine)
|
if (!customMine)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the block is a temporary block placed by block regen, immediately
|
* If the block is a temporary block placed by block regen, immediately
|
||||||
* cancel the break event; also check for extra config provided block
|
* cancel the break event; also check for extra config provided block
|
||||||
* conditions
|
* conditions
|
||||||
*/
|
*/
|
||||||
BlockInfo info = MMOCore.plugin.mineManager.getInfo(block);
|
BlockInfo info = MMOCore.plugin.mineManager.getInfo(block);
|
||||||
boolean temporaryBlock = MMOCore.plugin.mineManager.isTemporaryBlock(block);
|
boolean temporaryBlock = MMOCore.plugin.mineManager.isTemporaryBlock(block);
|
||||||
if ((temporaryBlock && info == null) || (info != null && !info.checkConditions(block))) {
|
if ((temporaryBlock && info == null) || (info != null && !info.checkConditions(block))) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If players are prevented from breaking blocks in custom mining
|
* If players are prevented from breaking blocks in custom mining
|
||||||
* regions
|
* regions
|
||||||
*/
|
*/
|
||||||
if (MMOCore.plugin.mineManager.shouldProtect())
|
if (MMOCore.plugin.mineManager.shouldProtect())
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extra breaking conditions.
|
* Extra breaking conditions.
|
||||||
*/
|
*/
|
||||||
if (!info.getBlock().breakRestrictions(block)) {
|
if (!info.getBlock().breakRestrictions(block)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean canBreak = true;
|
boolean canBreak = true;
|
||||||
ItemStack item = player.getInventory().getItemInMainHand();
|
ItemStack item = player.getInventory().getItemInMainHand();
|
||||||
if (!MMOCore.plugin.restrictionManager.checkPermissions(item, info.getBlock())) {
|
if (!MMOCore.plugin.restrictionManager.checkPermissions(item, info.getBlock())) {
|
||||||
MMOCore.plugin.configManager.getSimpleMessage("cannot-break").send(player);
|
MMOCore.plugin.configManager.getSimpleMessage("cannot-break").send(player);
|
||||||
canBreak = false;
|
canBreak = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calls the event and listen for cancel & for drops changes... also
|
* Find the block drops
|
||||||
* allows to apply tool durability & enchants to drops, etc.
|
*/
|
||||||
*/
|
boolean conditionsMet = !info.hasDropTable() || info.getDropTable().areConditionsMet(new ConditionInstance(player));
|
||||||
CustomBlockMineEvent called = new CustomBlockMineEvent(PlayerData.get(player), block, info, canBreak);
|
List<ItemStack> drops = conditionsMet ? info.getDropTable().collect(new LootBuilder(PlayerData.get(player), 0)) : new ArrayList<>();
|
||||||
Bukkit.getPluginManager().callEvent(called);
|
|
||||||
|
|
||||||
if (called.isCancelled() || !called.canBreak()) {
|
/*
|
||||||
event.setCancelled(true);
|
* Calls the event and listen for cancel & for drops changes... also
|
||||||
return;
|
* allows to apply tool durability & enchants to drops, etc.
|
||||||
}
|
*/
|
||||||
|
CustomBlockMineEvent called = new CustomBlockMineEvent(PlayerData.get(player), block, info, drops, !canBreak);
|
||||||
|
Bukkit.getPluginManager().callEvent(called);
|
||||||
|
if (called.isCancelled()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove vanilla drops if needed and
|
* Remove vanilla drops if needed and
|
||||||
* decreases the durability of the item
|
* decreases the durability of the item
|
||||||
* used to mine the block.
|
* used to mine the block.
|
||||||
*/
|
*/
|
||||||
if (!info.getOption(BlockInfoOption.VANILLA_DROPS)) {
|
if (!info.getOption(BlockInfoOption.VANILLA_DROPS)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
event.getBlock().setType(Material.AIR);
|
event.getBlock().setType(Material.AIR);
|
||||||
MMOCoreUtils.decreaseDurability(player, EquipmentSlot.HAND, 1);
|
MMOCoreUtils.decreaseDurability(player, EquipmentSlot.HAND, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply triggers, add experience info to the event so the other events
|
* Apply triggers, add experience info to the event so the other events
|
||||||
* can give exp to other TOOLS and display HOLOGRAMS
|
* can give exp to other TOOLS and display HOLOGRAMS
|
||||||
*/
|
*/
|
||||||
if (info.hasTriggers() && !block.hasMetadata("player_placed")) {
|
if (conditionsMet && info.hasTriggers() && !block.hasMetadata("player_placed")) {
|
||||||
if (!info.hasDropTable() || info.hasDropTable() && info.getDropTable().areConditionsMet(new ConditionInstance(player))) {
|
PlayerData playerData = PlayerData.get(player);
|
||||||
PlayerData playerData = PlayerData.get(player);
|
info.getTriggers().forEach(trigger -> trigger.apply(playerData));
|
||||||
info.getTriggers().forEach(trigger -> trigger.apply(playerData));
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply drop tables
|
* Apply drop tables
|
||||||
*/
|
*
|
||||||
if (info.hasDropTable()) {
|
* You can apply the drop tables even if the block was placed by a player.
|
||||||
Location dropLocation = getSafeDropLocation(block,
|
*/
|
||||||
!block.getType().isSolid() || !(info.regenerates() && info.getRegenerationInfo().hasTemporaryBlock()));
|
if (conditionsMet && info.hasDropTable()) {
|
||||||
for (ItemStack drop : called.getDrops())
|
Location dropLocation = getSafeDropLocation(block, !block.getType().isSolid() || !(info.regenerates() && info.getRegenerationInfo().hasTemporaryBlock()));
|
||||||
if (drop.getType() != Material.AIR && drop.getAmount() > 0)
|
for (ItemStack drop : drops)
|
||||||
UtilityMethods.dropItemNaturally(dropLocation, drop);
|
if (drop.getType() != Material.AIR && drop.getAmount() > 0)
|
||||||
}
|
UtilityMethods.dropItemNaturally(dropLocation, drop);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally enable block regen.
|
* Finally enable block regen.
|
||||||
*/
|
*/
|
||||||
if (info.hasRegen()) {
|
if (info.hasRegen())
|
||||||
Schedulers.sync().runLater(()-> {
|
Schedulers.sync().runLater(() -> MMOCore.plugin.mineManager.initialize(info.startRegeneration(Bukkit.createBlockData(savedData), block.getLocation()), !temporaryBlock), 1);
|
||||||
MMOCore.plugin.mineManager.initialize(info.startRegeneration(Bukkit.createBlockData(savedData), block.getLocation()), !temporaryBlock);
|
}
|
||||||
}, 1);
|
|
||||||
|
|
||||||
}
|
/*
|
||||||
}
|
* This is handled in a separate event because it
|
||||||
|
* needs to happen AFTER it's already checked the tag
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void unregisterPlayerPlacedBlocksTag(BlockBreakEvent event) {
|
||||||
|
if (event.getBlock().hasMetadata("player_placed"))
|
||||||
|
event.getBlock().removeMetadata("player_placed", MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
* This is handled in a separate event because it
|
public void registerPlayerPlacedBlocksTag(BlockPlaceEvent event) {
|
||||||
* needs to happen AFTER it's already checked the tag
|
event.getBlock().setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
||||||
*/
|
}
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void unregisterPlayerPlacedBlocksTag(BlockBreakEvent event) {
|
|
||||||
if(event.getBlock().hasMetadata("player_placed"))
|
|
||||||
event.getBlock().removeMetadata("player_placed", MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void registerPlayerPlacedBlocksTag(BlockPlaceEvent event) {
|
public void blockPistonExtend(BlockPistonExtendEvent event) {
|
||||||
event.getBlock().setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
Block movedBlock = event.getBlock();
|
||||||
}
|
if (!movedBlock.hasMetadata("player_placed"))
|
||||||
|
return;
|
||||||
|
BlockFace direction = event.getDirection();
|
||||||
|
// movedBlock = movedBlock.getRelative(direction, 2);
|
||||||
|
|
||||||
|
for (Block b : event.getBlocks())
|
||||||
|
if (b.hasMetadata("player_placed")) {
|
||||||
|
movedBlock = b.getRelative(direction);
|
||||||
|
movedBlock.setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void blockPistonRetract(BlockPistonRetractEvent event) {
|
||||||
|
BlockFace direction = event.getDirection();
|
||||||
|
Block movedBlock = event.getBlock().getRelative(direction);
|
||||||
|
movedBlock.setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
for (Block block : event.getBlocks()) {
|
||||||
public void blockPistonExtend(BlockPistonExtendEvent event) {
|
movedBlock = block.getRelative(direction);
|
||||||
Block movedBlock = event.getBlock();
|
movedBlock.setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
||||||
if (!movedBlock.hasMetadata("player_placed"))
|
}
|
||||||
return;
|
}
|
||||||
BlockFace direction = event.getDirection();
|
|
||||||
// movedBlock = movedBlock.getRelative(direction, 2);
|
|
||||||
|
|
||||||
for (Block b : event.getBlocks())
|
/*
|
||||||
if (b.hasMetadata("player_placed")) {
|
* Allows to mark cobblestone generated by cobblestone generators so that
|
||||||
movedBlock = b.getRelative(direction);
|
* exp is not gained by these blocks
|
||||||
movedBlock.setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
*/
|
||||||
}
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
}
|
public void cobblestoneGeneratorHandling(BlockFormEvent event) {
|
||||||
|
if (event.getBlock().hasMetadata("player_placed"))
|
||||||
|
event.getBlock().removeMetadata("player_placed", MMOCore.plugin);
|
||||||
|
if (MMOCore.plugin.configManager.cobbleGeneratorXP) return;
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
if (event.getBlock().getType() == Material.WATER || event.getBlock().getType() == Material.LAVA)
|
||||||
public void blockPistonRetract(BlockPistonRetractEvent event) {
|
if (event.getNewState().getType() == Material.COBBLESTONE || event.getNewState().getType() == Material.OBSIDIAN)
|
||||||
BlockFace direction = event.getDirection();
|
event.getNewState().setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
||||||
Block movedBlock = event.getBlock().getRelative(direction);
|
}
|
||||||
movedBlock.setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
|
||||||
|
|
||||||
for (Block block : event.getBlocks()) {
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
movedBlock = block.getRelative(direction);
|
public void handlePlayerStatistics(CustomBlockMineEvent event) {
|
||||||
movedBlock.setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
if (event.getBlockInfo().getBlock() instanceof VanillaBlockType)
|
||||||
}
|
event.getPlayer().incrementStatistic(Statistic.MINE_BLOCK, ((VanillaBlockType) event.getBlockInfo().getBlock()).getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private Location getSafeDropLocation(Block block, boolean self) {
|
||||||
* Allows to mark cobblestone generated by cobblestone generators so that
|
if (block.getType() == Material.AIR && self)
|
||||||
* exp is not gained by these blocks
|
return block.getLocation();
|
||||||
*/
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
for (BlockFace face : order) {
|
||||||
public void cobblestoneGeneratorHandling(BlockFormEvent event) {
|
Block relative = block.getRelative(face);
|
||||||
if(event.getBlock().hasMetadata("player_placed"))
|
if (!relative.getType().isSolid())
|
||||||
event.getBlock().removeMetadata("player_placed", MMOCore.plugin);
|
return relative.getLocation().add(block.getLocation().subtract(relative.getLocation()).multiply(.6));
|
||||||
if(MMOCore.plugin.configManager.cobbleGeneratorXP) return;
|
}
|
||||||
|
|
||||||
if (event.getBlock().getType() == Material.WATER || event.getBlock().getType() == Material.LAVA)
|
return block.getLocation();
|
||||||
if (event.getNewState().getType() == Material.COBBLESTONE || event.getNewState().getType() == Material.OBSIDIAN)
|
}
|
||||||
event.getNewState().setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void handlePlayerStatistics(CustomBlockMineEvent event) {
|
|
||||||
if (event.getBlockInfo().getBlock() instanceof VanillaBlockType)
|
|
||||||
event.getPlayer().incrementStatistic(Statistic.MINE_BLOCK, ((VanillaBlockType) event.getBlockInfo().getBlock()).getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Location getSafeDropLocation(Block block, boolean self) {
|
|
||||||
if (block.getType() == Material.AIR && self)
|
|
||||||
return block.getLocation();
|
|
||||||
|
|
||||||
for (BlockFace face : order) {
|
|
||||||
Block relative = block.getRelative(face);
|
|
||||||
if (!relative.getType().isSolid())
|
|
||||||
return relative.getLocation().add(block.getLocation().subtract(relative.getLocation()).multiply(.6));
|
|
||||||
}
|
|
||||||
|
|
||||||
return block.getLocation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user