Reputation: 37
I'm making a Bukkit plugin that will change the block underneath any player to glowstone.
The scheduler isn't working. The ground will change to glowstone but the glowstone block won't revert back to what it originally was.
@EventHandler
public void onStep(PlayerMoveEvent pme) {
Player player = pme.getPlayer();
Location locUnderPlayer = player.getLocation();
locUnderPlayer.setY(locUnderPlayer.getY() - 1);
Location locForScheduler = player.getLocation();
locForScheduler.setY(locForScheduler.getY() + 1);
final Material materialForScheduler = locForScheduler.getBlock().getType();
Block block = locUnderPlayer.getBlock();
Material m = player.getItemInHand().getType();
if (m == Material.GLOWSTONE) {
if (block.getType() != Material.AIR && block.getType() != Material.WATER && block.getType() != Material.STATIONARY_WATER && block.getType() != Material.LAVA && block.getType() != Material.STATIONARY_LAVA && block.getType() != Material.REDSTONE_WIRE && block.getType() != Material.REDSTONE_COMPARATOR && block.getType() != Material.REDSTONE_TORCH_ON && block.getType() != Material.REDSTONE_TORCH_OFF) {
block.setType(Material.GLOWSTONE);
Bukkit.getScheduler().scheduleSyncDelayedTask(Magic.getInstance(), new Runnable() {
public void run() {
block.setType(materialForScheduler);
}
}, 1 * 10);
}
}
}
Upvotes: 2
Views: 8304
Reputation: 5
EDIT: Late huh, my bad well I guess anyone else could use it There's another option:
1) get block under player
Block block = (player.getWorld, player.getLocation().getX(),
,player.getWorld, player.getLocation().getY()-1,
,player.getWorld, player.getLocation().getZ());
2) get the block and save it as a block state
Blockstate bs = block.getState();
3) set the block to glowstone
block.setType(Material.GLOWSTONE);
4) this reverts it back to its last saved state
bs.update(true)
5) (if you want) create a delay
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this new Runnable() {
public void run() {
//put delayed code here
bs.update(true);
}
}, 20 * seconds);
Upvotes: 0
Reputation: 23616
To get the block underneath a player, you could use:
Block block = player.getLocation().subtract(0, 1, 0).getBlock();
Which gets the player's location, subtracts 1 from the Y-axis, and then gets the block (hence getting the block under the player).
Then to get the type, you could use block.getType()
:
Material type = block.getType();
To set the block to glowstone, you could use block.setType(Material)
:
block.setType(Material.GLOWSTONE);
So, if you wanted to set the block under a player to glowstone, then immediately turn it back to the original block, you could use:
Block block = player.getLocation().subtract(0, 1, 0).getBlock(); //get the block
Material type = block.getType(); //get the block's type
block.setType(Material.GLOWSTONE); //set the block's material to glowstone
block.setType(type); //set the block's material back to the original material
But to have a delay between setting the block to glowstone then setting it back to the original block (in your case, the delay is 10 ticks) you could use a Runnable
task:
final Block block = player.getLocation().subtract(0, 1, 0).getBlock(); //get the block
final Material type = block.getType(); //get the block's type
block.setType(Material.GLOWSTONE); //set the block's material to glowstone
Bukkit.getScheduler().runTaskLater(Magic.getInstance(), new Runnable(){
public void run(){
block.setType(type); //set the block back to the original block
}
},10L);
We would want to make sure that the block beneath the player is not already glowstone, to insure that the block change does not become permanent. This could be done using simply:
if(!type.equals(Material.GLOWSTONE))
If we did not check for this, then a player could move with glowstone in their hand, hence setting the block underneath them to glowstone, and then starting a timer to set it back to the original block. But, if the player moves while the timer is in session (for example, 5 ticks after they last moved), the block underneath them would permanently change to glowstone.
So, your code could look something like this:
@EventHandler
public void onStep(PlayerMoveEvent pme) {
Player player = pme.getPlayer(); //get the player in the event
final Block block = player.getLocation().subtract(0, 1, 0).getBlock(); //get the block
final Material type = block.getState().getType(); //get the block's material
if(!type.equals(Material.GLOWSTONE)){//don't change the block if it's already glowstone
if(player.getItemInHand() != null){//make sure the item in the player's hand is not null, to avoid a null pointer
Material m = player.getItemInHand().getType(); //get the item in the player's hand
if(m == Material.GLOWSTONE){ //check if the item in the player's hand is glowstone
if(type != Material.AIR && type != Material.WATER && type != Material.STATIONARY_WATER && type != Material.LAVA && type != Material.STATIONARY_LAVA && type != Material.REDSTONE_WIRE && type != Material.REDSTONE_COMPARATOR && type != Material.REDSTONE_TORCH_ON && type != Material.REDSTONE_TORCH_OFF){
block.setType(Material.GLOWSTONE);//set the block type to glowstone
Bukkit.getScheduler().runTaskLater(Magic.getInstance(), new Runnable() {
public void run(){
block.setType(type); //set the block type back to the original type
}
},10L);
}
}
}
}
}
Also, you could reduce this if
statement:
if(type != Material.AIR && type != Material.WATER && type != Material.STATIONARY_WATER && type != Material.LAVA && type != Material.STATIONARY_LAVA && type != Material.REDSTONE_WIRE && type != Material.REDSTONE_COMPARATOR && type != Material.REDSTONE_TORCH_ON && type != Material.REDSTONE_TORCH_OFF)
into simply type.isSolid()
:
if(type.isSolid())
Upvotes: 8
Reputation: 119
The issue is because you are not checking if the block is already glowstone. So if you are running a temporary glowstone through the code, it will become permanent.
Upvotes: 0
Reputation:
@EventHandler(priority = EventPriority.MONITOR)
public void onMonitor(PlayerMoveEvent event) {
if (!event.isCancelled()) {
Player player = event.getPlayer();
if (player.getItemInHand().getType() == Material.GLOWSTONE) {
Block block = event.getTo().subtract(0D, 1D, 0D).getBlock();
Material type = block.getType();
if (type.isSolid()) {
if (!Restore.locked.contains(block)) {
Restore restore = new Restore(block, type, block.getData());
block.setType(Material.GLOWSTONE);
restore.runTaskLater(Plugin, 10L);
}
}
}
}
}
public class Restore extends BukkitRunnable {
public static Set<Block> locked = new HashSet<Block>();
private Block block;
private Material type;
private byte data;
public Restore(Block block, Material type, byte data) {
this.block = block;
this.type = type;
this.data = data;
locked.add(block);
}
@Override
public void run() {
block.setType(type);
block.setData(data);
locked.remove(block);
}
}
Upvotes: 0