Merge pull request #22 from RedstonerServer/F_signalstrength
Signalstrength fix
This commit is contained in:
@@ -27,7 +27,7 @@ import com.redstoner.utils.CommandMap;
|
|||||||
|
|
||||||
@Commands(CommandHolderType.None)
|
@Commands(CommandHolderType.None)
|
||||||
@AutoRegisterListener
|
@AutoRegisterListener
|
||||||
@Version(major = 4, minor = 0, revision = 0, compatible = 4)
|
@Version(major = 4, minor = 1, revision = 1, compatible = 4)
|
||||||
public final class BlockPlaceMods implements Module, Listener
|
public final class BlockPlaceMods implements Module, Listener
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@@ -89,7 +89,7 @@ public final class BlockPlaceMods implements Module, Listener
|
|||||||
String pluginName = Main.plugin.getName().toLowerCase();
|
String pluginName = Main.plugin.getName().toLowerCase();
|
||||||
// @noformat
|
// @noformat
|
||||||
return new String[]{"mod", pluginName + ":mod",
|
return new String[]{"mod", pluginName + ":mod",
|
||||||
"set", pluginName + ":mod",
|
"set", pluginName + ":set",
|
||||||
"toggle", pluginName + ":toggle"
|
"toggle", pluginName + ":toggle"
|
||||||
};
|
};
|
||||||
// @format
|
// @format
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public abstract class ModAbstract implements Mod, Listener
|
|||||||
ModAbstract.logger = logger;
|
ModAbstract.logger = logger;
|
||||||
registerMod(new ModToggledCauldron());
|
registerMod(new ModToggledCauldron());
|
||||||
registerMod(new ModToggledPiston());
|
registerMod(new ModToggledPiston());
|
||||||
|
registerMod(new ModToggledObserver());
|
||||||
registerMod(new ModToggledStep());
|
registerMod(new ModToggledStep());
|
||||||
registerMod(new ModToggledTorch());
|
registerMod(new ModToggledTorch());
|
||||||
registerMod(new ModInventory("dropper", InventoryType.DROPPER));
|
registerMod(new ModInventory("dropper", InventoryType.DROPPER));
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.redstoner.modules.blockplacemods.mods;
|
||||||
|
|
||||||
|
import org.bukkit.GameMode;
|
||||||
|
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.block.BlockPlaceEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mod that makes placement of directional blocks act the way placement of logs does normally.
|
||||||
|
* Quartz pillar placement works like this too.
|
||||||
|
*
|
||||||
|
* Placed blocks face the block you clicked to place them.
|
||||||
|
*/
|
||||||
|
public abstract class ModToggledLogPlaceAbstract extends ModToggledAbstract {
|
||||||
|
|
||||||
|
protected ModToggledLogPlaceAbstract(String name, boolean enabledByDefault) {
|
||||||
|
super(name, enabledByDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onBlockPlace(BlockPlaceEvent event)
|
||||||
|
{
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
Block block;
|
||||||
|
if (hasEnabled(player) && !player.isSneaking() && player.getGameMode() == GameMode.CREATIVE
|
||||||
|
&& isApplicableToPlacedBlock(block = event.getBlock()))
|
||||||
|
{
|
||||||
|
block.setData((byte) getBlockDataForFacing(block.getFace(event.getBlockAgainst())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract int getBlockDataForFacing(BlockFace direction);
|
||||||
|
|
||||||
|
protected abstract boolean isApplicableToPlacedBlock(Block block);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.redstoner.modules.blockplacemods.mods;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
|
||||||
|
public class ModToggledObserver extends ModToggledLogPlaceAbstract {
|
||||||
|
|
||||||
|
protected ModToggledObserver() {
|
||||||
|
super("observer", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "If active, observers face the block you place them against";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isApplicableToPlacedBlock(Block block) {
|
||||||
|
return block.getType() == Material.OBSERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getBlockDataForFacing(BlockFace direction) {
|
||||||
|
switch (direction) {
|
||||||
|
case UP:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
case DOWN:
|
||||||
|
return 1;
|
||||||
|
case SOUTH:
|
||||||
|
return 2;
|
||||||
|
case NORTH:
|
||||||
|
return 3;
|
||||||
|
case EAST:
|
||||||
|
return 4;
|
||||||
|
case WEST:
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,15 +1,10 @@
|
|||||||
package com.redstoner.modules.blockplacemods.mods;
|
package com.redstoner.modules.blockplacemods.mods;
|
||||||
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
|
|
||||||
public class ModToggledPiston extends ModToggledAbstract
|
public class ModToggledPiston extends ModToggledLogPlaceAbstract
|
||||||
{
|
{
|
||||||
public ModToggledPiston()
|
public ModToggledPiston()
|
||||||
{
|
{
|
||||||
@@ -22,28 +17,17 @@ public class ModToggledPiston extends ModToggledAbstract
|
|||||||
return "If active, pistons face the block you place them against";
|
return "If active, pistons face the block you place them against";
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@Override
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
protected boolean isApplicableToPlacedBlock(Block block) {
|
||||||
public void onBlockPlace(BlockPlaceEvent event)
|
Material type = block.getType();
|
||||||
{
|
return type == Material.PISTON_BASE || type == Material.PISTON_STICKY_BASE;
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (hasEnabled(player) && !player.isSneaking() && player.getGameMode() == GameMode.CREATIVE
|
|
||||||
&& isPiston(event.getBlock().getType()))
|
|
||||||
{
|
|
||||||
Block block = event.getBlock();
|
|
||||||
block.setData((byte) pistonDataForFace(block.getFace(event.getBlockAgainst())));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPiston(Material block)
|
@Override
|
||||||
{
|
protected int getBlockDataForFacing(BlockFace direction) {
|
||||||
return block == Material.PISTON_BASE || block == Material.PISTON_STICKY_BASE;
|
switch (direction)
|
||||||
}
|
|
||||||
|
|
||||||
private int pistonDataForFace(BlockFace face)
|
|
||||||
{
|
|
||||||
switch (face)
|
|
||||||
{
|
{
|
||||||
|
default:
|
||||||
case DOWN:
|
case DOWN:
|
||||||
return 0;
|
return 0;
|
||||||
case UP:
|
case UP:
|
||||||
@@ -56,8 +40,7 @@ public class ModToggledPiston extends ModToggledAbstract
|
|||||||
return 4;
|
return 4;
|
||||||
case EAST:
|
case EAST:
|
||||||
return 5;
|
return 5;
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,130 +1,180 @@
|
|||||||
package com.redstoner.modules.signalstrength;
|
package com.redstoner.modules.signalstrength;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
import org.bukkit.block.BlockState;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import com.nemez.cmdmgr.Command;
|
import com.nemez.cmdmgr.Command;
|
||||||
import com.redstoner.annotations.Commands;
|
import com.redstoner.annotations.Commands;
|
||||||
import com.redstoner.annotations.Version;
|
import com.redstoner.annotations.Version;
|
||||||
import com.redstoner.misc.CommandHolderType;
|
import com.redstoner.misc.CommandHolderType;
|
||||||
import com.redstoner.modules.Module;
|
import com.redstoner.modules.Module;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Nameable;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.BlockState;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Commands(CommandHolderType.File)
|
@Commands(CommandHolderType.File)
|
||||||
@Version(major = 4, minor = 0, revision = 0, compatible = 4)
|
@Version(major = 4, minor = 0, revision = 0, compatible = 4)
|
||||||
public class SignalStrength implements Module
|
public class SignalStrength implements Module
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static final String namePrefix = ChatColor.GREEN.toString() + ChatColor.RESET + ChatColor.DARK_PURPLE + "Signal Strength: " + ChatColor.RED + ChatColor.BOLD;
|
||||||
|
|
||||||
|
private static String nameForSignalStrength(int strength)
|
||||||
|
{
|
||||||
|
return namePrefix + strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSignalStrengthNameOrEmpty(String name)
|
||||||
|
{
|
||||||
|
return name == null || name.isEmpty() || name.startsWith(namePrefix);
|
||||||
|
}
|
||||||
|
|
||||||
@Command(hook = "ss")
|
@Command(hook = "ss")
|
||||||
public boolean ss(CommandSender sender, int strength)
|
public boolean ss(CommandSender sender, int strength)
|
||||||
{
|
{
|
||||||
return ssm(sender, strength, Material.REDSTONE_WIRE.toString());
|
return ssm(sender, strength, Material.REDSTONE.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(hook = "ssm")
|
@Command(hook = "ssm")
|
||||||
public boolean ssm(CommandSender sender, int strength, String material)
|
public boolean ssm(CommandSender sender, int strength, String material)
|
||||||
{
|
{
|
||||||
Material item_type = Material.getMaterial(material);
|
Material itemType = Material.matchMaterial(material);
|
||||||
|
if (itemType == null)
|
||||||
|
{
|
||||||
|
getLogger().message(sender, true, "The material " + material + " could not be recognized");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Player player = (Player) sender;
|
Player player = (Player) sender;
|
||||||
Block target_block = player.getTargetBlock(new HashSet<Material>(), 5);
|
|
||||||
if (target_block == null)
|
// Empty set in the first argument would make it always return the first block, because no block types are
|
||||||
|
// considered to be transparent. Only a value of null is treated as "air only".
|
||||||
|
Block targetBlock = player.getTargetBlock((Set<Material>) null, 5);
|
||||||
|
if (targetBlock == null)
|
||||||
{
|
{
|
||||||
getLogger().message(sender, true, "That command can only be used if a container is targeted!");
|
getLogger().message(sender, true, "That command can only be used if a container is targeted!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Inventory inventory = getInventory(target_block);
|
Inventory inventory = getInventory(targetBlock);
|
||||||
if (inventory == null)
|
if (inventory == null)
|
||||||
{
|
{
|
||||||
getLogger().message(sender, true, "That command can only be used if a container is targeted!");
|
getLogger().message(sender, true, "That command can only be used if a container is targeted!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------Get the stack size and required amount of items to achieve the desired signal strength---------
|
// --------Get the stack size and required amount of items to achieve the desired signal strength---------
|
||||||
int stack_size = item_type.getMaxStackSize();
|
int stackSize = itemType.getMaxStackSize();
|
||||||
int slot_count = inventory.getSize();
|
int slotCount = inventory.getSize();
|
||||||
int item_count = required_item_count(strength, stack_size, slot_count);
|
int itemCount = computeRequiredItemCount(strength, stackSize, slotCount);
|
||||||
if (item_count == -1)
|
if (itemCount == -1)
|
||||||
{
|
{
|
||||||
getLogger().message(sender, true,
|
getLogger().message(sender, true,
|
||||||
"The desired signal strength could not be achieved with the requested item type");
|
"The desired signal strength could not be achieved with the requested item type");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// #--------Add the other side of the chest if target is a double chest and check if player can build---------
|
// #--------Add the other side of the chest if target is a double chest and check if player can build---------
|
||||||
ArrayList<Block> container_blocks = getAllContainers(target_block);
|
ArrayList<Block> containerBlocks = new ArrayList<>();
|
||||||
for (Block b : container_blocks)
|
containerBlocks.add(targetBlock);
|
||||||
|
|
||||||
|
Material blockType = targetBlock.getType();
|
||||||
|
if (inventory.getType() == InventoryType.CHEST)
|
||||||
{
|
{
|
||||||
if (!canBuild(player, b))
|
Arrays.stream(new BlockFace[]{BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH})
|
||||||
|
.map(targetBlock::getRelative)
|
||||||
|
.filter(b -> b.getType() == blockType)
|
||||||
|
.forEach(containerBlocks::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Block containerBlock : containerBlocks)
|
||||||
|
{
|
||||||
|
if (!canBuild(player, containerBlock))
|
||||||
{
|
{
|
||||||
getLogger().message(sender, true, "You can not build here!");
|
getLogger().message(sender, true, "You can not build here!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #----------------Insert items-------------
|
// #----------------Insert items-------------
|
||||||
int full_stack_count = item_count / stack_size;
|
int fullStackCount = itemCount / stackSize;
|
||||||
int remaining = item_count % stack_size;
|
int remaining = itemCount % stackSize;
|
||||||
for (Block b : container_blocks)
|
for (Block containerBlock : containerBlocks)
|
||||||
{
|
{
|
||||||
Inventory inv = getInventory(b);
|
// Below checks should evaluate to false, but let's be safe.
|
||||||
|
BlockState blockState = containerBlock.getState();
|
||||||
|
if (!(blockState instanceof InventoryHolder)) continue;
|
||||||
|
|
||||||
|
if (blockState instanceof Nameable && isSignalStrengthNameOrEmpty(((Nameable) blockState).getCustomName()))
|
||||||
|
{
|
||||||
|
((Nameable) blockState).setCustomName(nameForSignalStrength(strength));
|
||||||
|
blockState.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
Inventory inv = ((InventoryHolder) blockState).getInventory();
|
||||||
|
if (inv == null) continue;
|
||||||
|
|
||||||
inv.clear();
|
inv.clear();
|
||||||
for (int i = 0; i < full_stack_count; i++)
|
for (int i = 0; i < fullStackCount; i++)
|
||||||
inv.setItem(i, new ItemStack(item_type, stack_size));
|
inv.setItem(i, new ItemStack(itemType, stackSize));
|
||||||
if (remaining > 0)
|
if (remaining > 0)
|
||||||
inv.setItem(full_stack_count, new ItemStack(item_type, remaining));
|
inv.setItem(fullStackCount, new ItemStack(itemType, remaining));
|
||||||
|
|
||||||
}
|
}
|
||||||
getLogger().message(sender,
|
getLogger().message(sender, "Comparators attached to this " + enumNameToHumanName(blockType.name())
|
||||||
"Comparators attached to this Inventory will now put out a signal strength of" + strength);
|
+ " will now put out a signal strength of " + strength);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int required_item_count(int strength, int stack_size, int slot_count)
|
private static Inventory getInventory(Block b)
|
||||||
{
|
|
||||||
int item_count = -1;
|
|
||||||
if (strength == 0)
|
|
||||||
item_count = 0;
|
|
||||||
else if (strength == 1)
|
|
||||||
item_count = 1;
|
|
||||||
else
|
|
||||||
item_count = (int) Math.ceil(slot_count * stack_size / 14.0 * (strength - 1));
|
|
||||||
int resulting_strength = item_count == 0 ? 0 : (int) Math.ceil(1 + 14.0 * item_count / stack_size / slot_count);
|
|
||||||
// Clarification on these formulas at https://minecraft.gamepedia.com/Redstone_Comparator#Containers
|
|
||||||
return resulting_strength == strength ? item_count : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Inventory getInventory(Block b)
|
|
||||||
{
|
{
|
||||||
BlockState state = b.getState();
|
BlockState state = b.getState();
|
||||||
if (state instanceof InventoryHolder)
|
if (state instanceof InventoryHolder)
|
||||||
return ((InventoryHolder) state).getInventory();
|
return ((InventoryHolder) state).getInventory();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canBuild(Player p, Block b)
|
private static int computeRequiredItemCount(int strength, int stackSize, int slotCount)
|
||||||
{
|
{
|
||||||
BlockPlaceEvent e = new BlockPlaceEvent(b, b.getState(), b.getRelative(BlockFace.DOWN),
|
int itemCount = -1;
|
||||||
p.getInventory().getItemInMainHand(), p, true, EquipmentSlot.HAND);
|
if (strength == 0)
|
||||||
return e.isCancelled();
|
itemCount = 0;
|
||||||
}
|
else if (strength == 1)
|
||||||
|
itemCount = 1;
|
||||||
private ArrayList<Block> getAllContainers(Block b)
|
else
|
||||||
{
|
itemCount = (int) Math.ceil(slotCount * stackSize / 14.0 * (strength - 1));
|
||||||
ArrayList<Block> result = new ArrayList<Block>();
|
|
||||||
result.add(b);
|
// Reverse engineer the calculation to verify
|
||||||
for (BlockFace face : BlockFace.values())
|
int resultingStrength = itemCount == 0 ? 0 : (int) Math.floor(1 + 14.0 * itemCount / stackSize / slotCount);
|
||||||
|
if (resultingStrength != strength)
|
||||||
{
|
{
|
||||||
Block b2 = b.getRelative(face);
|
return -1;
|
||||||
if (getInventory(b2) != null)
|
|
||||||
result.add(b2);
|
|
||||||
}
|
}
|
||||||
return result;
|
// Clarification on these formulas at https://minecraft.gamepedia.com/Redstone_Comparator#Containers
|
||||||
|
return itemCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean canBuild(Player p, Block b)
|
||||||
|
{
|
||||||
|
BlockPlaceEvent event = new BlockPlaceEvent(b, b.getState(), b.getRelative(BlockFace.DOWN),
|
||||||
|
p.getInventory().getItemInMainHand(), p, true, EquipmentSlot.HAND);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
return !event.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String enumNameToHumanName(String enumName)
|
||||||
|
{
|
||||||
|
return enumName.toLowerCase().replace('_', ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user