Writing on Signs/ Setting floating blocks/ Saving configs

Discussion in 'Plugin Development' started by Templar3lf, Aug 22, 2014.

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

    Templar3lf

    Ok, so I have multiple problems and people just don't seem to be answering them, but I'll ask again anyway.

    First problem: If a sign is destroyed by an explosion, it waits a bit, then fixes it. Before explosion it gets the sign text, after fixing it, it sets the sign text. I know it's getting the sign text fine as I printed it to console, but it just ain't setting the sign text fine.

    [Whole] EntityExplodeEvent Handler:
    Code:java
    1. @EventHandler
    2. public void onEntityExplode(final EntityExplodeEvent event){
    3. currentlyFixing = true;
    4. lastExplosion = event.getLocation();
    5. List<Block> effectedBlocks = event.blockList();
    6. Collections.shuffle(effectedBlocks);
    7. boolean doMore = true;
    8. while (doMore) {
    9. doMore = false;
    10. for (int i = 0; i < effectedBlocks.size() - 1; i++) {
    11. Block firstBlock = effectedBlocks.get(i);
    12. Block secondBlock = effectedBlocks.get(i + 1);
    13. if(firstBlock.getY() > secondBlock.getY()){
    14. effectedBlocks.set(i + 1, firstBlock);
    15. effectedBlocks.set(i, secondBlock);
    16. doMore = true;
    17. }
    18. }
    19. }
    20. event.getLocation().getWorld().setGameRuleValue("doTileDrops", "false");
    21. this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    22. public void run() {
    23. event.getLocation().getWorld().setGameRuleValue("doTileDrops", "true");
    24. lastExplosion = null;
    25. currentlyFixing = false;
    26. }
    27. }, 20L);
    28. for(int i = 0; i < effectedBlocks.size(); i++){
    29. final Block thisBlock = effectedBlocks.get(i);
    30. final Material blockMaterial = thisBlock.getType();
    31. thisBlock.getDrops().clear();
    32. final BlockState blockState = thisBlock.getState();
    33. this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    34. public void run() {
    35. thisBlock.setType(blockMaterial);
    36. blockState.update(true);
    37. }
    38. }, (long) i * 4 + 60);
    39. if(blockMaterial == Material.CHEST || blockMaterial == Material.TRAPPED_CHEST){
    40. final ItemStack[] chestInv = ((Chest) thisBlock.getState()).getInventory().getContents();
    41. ((Chest) thisBlock.getState()).getInventory().clear();
    42. this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    43. public void run() {
    44. ((Chest) thisBlock.getState()).getInventory().setContents(chestInv);
    45. }
    46. }, (long) i * 4 + 61);
    47. }
    48. else if(blockMaterial == Material.SIGN || blockMaterial == Material.SIGN_POST){
    49. final Sign sign = (Sign) thisBlock.getState();
    50. final String[] lines = sign.getLines();
    51. pluginLogger.info(lines[0] + "." + lines[1] + "." + lines[2] + "." + lines[3]);
    52. this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    53. public void run() {
    54. sign.setLine(0, "TEST");
    55. sign.setLine(1, lines[1]);
    56. sign.setLine(2, lines[2]);
    57. sign.setLine(3, lines[3]);
    58. sign.update();
    59. thisBlock.getState().update();
    60. }
    61. }, (long) i * 4 + 62);
    62. }
    63. else if(blockMaterial == Material.TNT){
    64. this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    65. public void run() {
    66. thisBlock.setType(Material.AIR);
    67. }
    68. }, (long) i * 4 + 63);
    69. }
    70. }
    71. }


    Second problem:

    How would one use the Block.setType(Material.SAND) to set a floating/ non-falling block. Every time I try to set a block in mid air to sand, it falls. I have tried the physics event, and have even used that to stop any blocks already near the explosion radius from falling, but it just doesn't seem to register properly on blocks that I place using the setType() method.

    Third problem:

    I have another plugin which saves inventories when the player switches worlds. In this plugin I know it manages to get the inventory correctly, and the save should work as I have used it in almost exactly the same manner but with a different file further up the code.

    [Whole] SaveInventory Method:
    Code:java
    1. private void savePlayerInv(Player thePlayer){
    2. File Inventory = new File("plugins/MultiWorld/Inventories/" + thePlayer.getName() + ".yml");
    3. YamlConfiguration pInv = YamlConfiguration.loadConfiguration(Inventory);
    4. PlayerInventory slots = thePlayer.getInventory();
    5. int slotCounter = 0, armCounter = 0;
    6. String start = thePlayer.getWorld().getName() + ".inv";
    7. for (ItemStack slot : slots.getContents()) {
    8. String saveloc = start + "." + Integer.toString(slotCounter);
    9. pInv.set(saveloc, null);
    10. slotCounter++;
    11. if (slot == null) continue;
    12. pInv.set(saveloc + ".amt", slot.getAmount());
    13. pInv.set(saveloc + ".dur", Short.toString(slot.getDurability()));
    14. pInv.set(saveloc + ".typ", slot.getType().toString());
    15. int enchCounter = 0;
    16. for (Entry<Enchantment, Integer> enchs : slot.getEnchantments().entrySet()) {
    17. pInv.set(saveloc + ".enh." + enchCounter + ".nme", enchs.getKey().getName());
    18. pInv.set(saveloc + ".enh." + enchCounter + ".lvl", enchs.getValue());
    19. enchCounter++;
    20. }
    21. pluginLogger.info("Inv:" + slot.getType().toString());
    22. }
    23. for (ItemStack armslot : slots.getArmorContents()) {
    24. String armsave = start + ".arm." + Integer.toString(armCounter);
    25. pInv.set(armsave, null);
    26. armCounter++;
    27. if(armslot.getType().toString() == null) continue;
    28. pInv.set(armsave + ".amt", armslot.getAmount());
    29. pInv.set(armsave + ".dur", Short.toString(armslot.getDurability()));
    30. pInv.set(armsave + ".typ", armslot.getType().toString());
    31. int enchCounter = 0;
    32. for (Entry<Enchantment, Integer> enchs : armslot.getEnchantments().entrySet()) {
    33. pInv.set(armsave + ".enh." + enchCounter + ".nme", enchs.getKey().getName());
    34. pInv.set(armsave + ".enh." + enchCounter + ".lvl", enchs.getValue());
    35. enchCounter++;
    36. }
    37. pluginLogger.info("Inv:" + armslot.getType().toString());
    38. }
    39. if (thePlayer.getExp() != 0){ pInv.set(thePlayer.getWorld().getName() + ".exp", thePlayer.getExp());}
    40. try {
    41. pInv.save(Inventory);
    42. } catch (IOException e) {
    43. pluginLogger.info("[MultiWorld] Something went wrong when saving Player file.");
    44. e.printStackTrace();
    45. }
    46. }


    Thank you for any answers to these questions you may have.

    How often can one Bump a post?

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

    MasterDoctor

    Every 24 hours.

    Second problem:

    How would one use the Block.setType(Material.SAND) to set a floating/ non-falling block. Every time I try to set a block in mid air to sand, it falls. I have tried the physics event, and have even used that to stop any blocks already near the explosion radius from falling, but it just doesn't seem to register properly on blocks that I place using the setType() method.

    Are there any block updates occurring next to the sand block?

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

    Templar3lf

    MasterDoctor
    I have made some headway in that problem. It seems the BlockPhysicsEvent does activate when the block is set but I am searching a list of effected blocks for a block I got in a different EventHandler, at a later point, when I assume the block data has changed in some way. This means that if you search a list of blocks for that block, even if it was in that list of blocks when you got the list of blocks, it wont find it, as it's no longer got the same data.

    Correct me if this theory is wrong, but I'm trying again using the block location instead. Setting a list of locations to the locations of the list of blocks and seeing if the new location matches any of the locations in the list, then I can continue to cancel the event.

    Edit: Just found this quote: "When you spawn sand or gravel Blocks (not FallingBlocks) they turn into an instance of FallingBlocks and start to fall, if spawned in air. "

    Edit Two: Ok, I mostly fixed the second problem by setting the block below the block I am placing to Bedrock, quarter of a second before I set it, if the block is Sand or Gravel. I then set it back to its original block if it's not air, quarter of a second after the block has been placed.

    Without setting it back to its original block it just set it to air and I ended up with a hole, but covered up by a layer of hovering sand, because of how I had used the BlockPhysicsEvent.

    The other two problems are still very much just that. Problems. If anyone knows how to fix these, please tell me.

    Ok, so:

    Second problem fixed [Mostly]: I have to check the block below to sandstone or dirt, depending on the material, and then convert it back to it's original material when the regeneration is complete. Kinda hacky, but it works about 95% of the time. The 5% of the time it doesn't work, it just misses a few sand or gravel blocks, which you can replace yourself if you actually care for them.

    Third problem fixed: Event though you have saved it, you can't open a file using another file manager in the same event or command. Just separate those two sets of data into different files if you're trying to use the same file twice.
    Or find other ways of storing it. Or open the file at the start or somewhere else.

    But if anyone has a fix for the first problem, the signs not saving, that would be nice.

    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