Solved Block Regeneration

Discussion in 'Plugin Development' started by Telmovieira, Jul 3, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Telmovieira

    Hi there everyone!
    So, i need to make a system that regenerates resources is a place that they are limited, something similar to annihilation where you break, for example a log and the log is replaced by air, goes to your inventory, gives you exp and then run a timer that in a time of 3 or 4 seconds the block magicaly appears again! My code seams prety logic to me, thats why i can't solve this problem beacause what happens is that every thing goes right until the part when the runnable comes into play and the log just does not apear any more
    Here is some of my code...
    Code:java
    1. @EventHandler
    2. public void OnBlockBreak(BlockBreakEvent event){
    3. Player player = event.getPlayer();
    4. final Block block = event.getBlock();
    5.  
    6. if(block.getType().equals(Material.LOG)){
    7. block.getDrops().clear();
    8. ItemStack Log = new ItemStack (Material.LOG);
    9. player.getInventory().addItem(Log);
    10. block.setType(Material.AIR);
    11. player.giveExp(2);
    12. new BukkitRunnable(){
    13. public void run(){
    14. block.setType(Material.LOG);
    15. }
    16. }.runTaskLater(plugin, 600L);
    17. }
    18. }


    Please anwser i realy need help with this...
    Telmovieira

    PS: This is in a different class other than the main one of the plugin.
    And another thing... Events are registered and Listener is implemented...(I am not an idiot...).
     
  2. Offline

    HungerCraftNL

    Don't you need to cancel the event?
     
  3. Offline

    CynutsBR

    Telmovieira You putted 600l it means 30 seconds, nothing appears after this time?
    And cancel the event at first ;)
     
  4. Offline

    mythbusterma

    Your problem is likely in the fact that you can't store an instance of a Block, it just doesn't work. Read the JavaDocs on Block for why it isn't possible and what the proper alternative is (BlockState).
     
  5. Offline

    Telmovieira

    HungerCraftNL, CynutsBR and mythbusterma
    Thank you very much for your sugestions i will try them i will give some feedback if it worked or not!

    @mythbusterma
    Could you write some pseudo code for me to have an ideia of what i should, like, should i use Hash maps and those sorts of things....

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
  6. Offline

    mythbusterma

    Just use BlockState instead of Block in your code, Block has a getState() method for this, and you can call BlockState#update(boolean) Medford for changing the block to the BlockState's state.
     
  7. Offline

    Telmovieira

    mythbusterma
    I was able to make it so the block appeared again using the block state, showing that the problem resides in the bukkit runnable.... Could you give me some assistance with that?
    Here is the updated code:
    Code:java
    1. @EventHandler
    2. public void OnBlockBreak(BlockBreakEvent event){
    3. Player player = event.getPlayer();
    4. final BlockState block = event.getBlock().getState();
    5. if(block.getType().equals(Material.LOG)){
    6. event.setCancelled(true);
    7. block.getBlock().getDrops().clear();
    8. ItemStack Log = new ItemStack (Material.LOG);
    9. player.getInventory().addItem(Log);
    10. block.setType(Material.AIR);
    11. player.giveExp(2);
    12. new BukkitRunnable(){
    13. public void run(){
    14. block.setType(Material.LOG);
    15. }
    16. }.runTaskLater(plugin, 600L);
    17. }
    18. }

    Thank you in advance!
     
  8. Offline

    mythbusterma

    Doing BlockState#setType(Material) does nothing, it only changes the BlockState, not the actual Block in the world. You need to use update(boolean) like I said before....
     
  9. Offline

    endoml

    In the run method, use block.update(true); instead of block.setType(Material.LOG);
     
  10. Offline

    Telmovieira

    mythbusterma endoml
    Good news! I found out what the problem was... Bad news, I don't know how to solve it
    The bukkt runnable does not work because of a IllegalArgumentException: Plugin cannot be null
    I researched about it and the solutions i found said to use this.plugin = this in the onEnable() and other stuff in the Listener class like putting a constructor in there, etc.... In summary i did EVERYTHING in my reach and keeps throwing the goddam exception over and over again!
    I am starting to panic here and i realy need some help!
    There is all the code you need to do so... If you need more I will provide it to you

    Part of the BlockListener class including the event and the constructor:
    Code:java
    1. public class BlockListener implements Listener {
    2.  
    3. public Main plugin;
    4.  
    5. public BlockListener(Main instance){
    6. instance = plugin;
    7. }
    8.  
    9.  
    10. @EventHandler
    11. public void OnBlockBreak(BlockBreakEvent event) {
    12. Player player = event.getPlayer();
    13. final BlockState block = event.getBlock().getState();
    14. if (block.getType().equals(Material.LOG)) {
    15. event.setCancelled(true);
    16. block.getBlock().getDrops().clear();
    17. ItemStack Log = new ItemStack(Material.LOG);
    18. player.getInventory().addItem(Log);
    19. block.setType(Material.AIR);
    20. block.update(true);
    21. player.giveExp(2);
    22. new BukkitRunnable() {
    23. public void run() {
    24. block.update(true);
    25. }
    26. }.runTaskLaterAsynchronously(plugin, 100L);//Error is thrown here...
    27.  
    28. }
    29. }


    OnEnable and listener constructors:
    Code:java
    1. public class Main extends JavaPlugin implements Listener {
    2. public final Logger logger = Logger.getLogger("Minecraft");
    3. public Main plugin;
    4. public boolean freeze = false;
    5. public final PlayerListener pl = new PlayerListener();
    6. public final BlockListener bl = new BlockListener(this);
    7. public final SoulboundListeners sl = new SoulboundListeners();
    8. public final Domination dom = new Domination();
    9. public int onlinePlayers = Bukkit.getOnlinePlayers().length;//Don't mind this
    10. public int number = 10;//Don't mind this
    11. public Scoreboard timerBoard = null;//Don't mind this
    12. public Objective timerObj = null;//Don't mind this
    13.  
    14. @Override
    15. public void onEnable() {
    16. PluginDescriptionFile pdfFile = this.getDescription();
    17. this.logger.info(pdfFile.getName() + " Version " + pdfFile.getVersion()
    18. + "Has been enabled");
    19. this.plugin = this;
    20. PluginManager pm = getServer().getPluginManager();
    21. pm.registerEvents(this.pl, this);
    22. pm.registerEvents(this.bl, this);
    23. pm.registerEvents(this.sl, this);
    24. pm.registerEvents(this.dom, this);
    25. pm.registerEvents(this, this);
    26. this.getServer().getPluginManager().registerEvents(this, this);
    27. me.Telmovieira.Liberatum.Team.clearTeams();
    28. ScoreboardManager sbManager = Bukkit.getScoreboardManager();
    29. for (Player p : Bukkit.getOnlinePlayers()) {
    30. p.setScoreboard(sbManager.getNewScoreboard());
    31. p.setDisplayName(ChatColor.RESET + p.getName());
    32. p.setPlayerListName(ChatColor.RESET + p.getName());
    33. }
    34. GameState.setState(GameState.IN_LOBBY);
    35. Runtime.getRuntime().traceInstructions(false);//Don't mind this
    36. Runtime.getRuntime().traceMethodCalls(false);//Don't mind this
    37. //Desableing stack traces reduces lag... of course they are enabled when i am developing the plugin...
    38.  
    39.  
    40. }


    I am hopping you give me an answer soon

    Thank you once again!
     
  11. Offline

    Zer0DZN

    Try To Use This Code

    Code:java
    1. //The BlockBreak Event
    2. @EventHandler
    3. public void breakingBlock(BlockBreakEvent event) {
    4. Block b = event.getBlock();
    5. //Material
    6. if(b.getType() == Material.LOG) {
    7. // Block Regeneration
    8. final BlockState restorePoint = event.getBlock().getState();
    9. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, new Runnable() {
    10. public void run() {
    11. restorePoint.update(true, false);
    12. }
    13. }, 320L);
    14. //320L = 15 Seconds
    15. }
    16. }
    17. }
    18.  
     
  12. Offline

    endoml

    I think the problem is that you are not initializing the plugin variable, but I'm not sure.
     
  13. Offline

    mythbusterma

    Telmovieira

    DON'T EVER DO THIS ASYNCHRONOUSLY, IT IS NOT SAFE. Use synchronous methods instead.

    Second, you're trying to update it to air again, which isn't going to do anything, you need to update it to a log.

    Third, all of your instance variables should be private, not public.

    Fourth, the assignment in the constructor is going the wrong way, so you're setting a temporary value to null, and not the other way around.
     
  14. Offline

    Telmovieira

    mythbusterma
    Thx for the help but what do you mean by the assignment in the constructor is going the wrong way?

    Sorry for the inconvinence... :(
     
  15. Offline

    mythbusterma

    Should be "plugin = instance" not the other way around.
     
  16. Offline

    Telmovieira

    Ok thx

    It worked.... Finaly!
    Thank you so much for your help!!!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
Thread Status:
Not open for further replies.

Share This Page