1.8.8 How can I allow placing blocks but not breaking the map?

Discussion in 'Spigot Plugin Development' started by Kognise, Jan 18, 2020.

  1. I'm teaching myself Java and Kotlin by making a Hypixel-like bedwars plugin. I'm struggling with creating a good build permissions system - maybe you guys can help me?

    I want players to be able to place blocks, and break blocks they and other players have placed. But they shouldn't be able to break blocks that are part of the preexisting map. I'm using WorldGuard for managing mechanics like this in the lobby, but looking through the API there's nothing that would explicitly aid me in the functionality I'm looking for.

    Could one of you kindly point me in the direction of the simplest option to accomplish this? I'm totally fine with writing custom code, but I'm a little lost here.

    • Games are in temporary worlds that are created automatically by my plugin
    • There are NPCs in the map that players should be able to interact with
    • Each island has a chest that only members of the team can access, but this is something I can figure out on my own
    • The map also shouldn't be able to be blown up with TNT, but this is again something I can figure out myself

  2. This is what I would do:
    • Store the location of placed blocks inside some array.
    • Only allow these block locations to be destroyed again.
    • Agree Agree x 1
  3. Instead of an array, he can store them in a List.
    (It's not the same thing, I think you most likely meant List)

    And break event and if the List contains your Block, you just allow the event, otherwise, cancel it.
  4. Thanks! That's the obvious solution I was thinking of, but I was wondering if there's a better way I could do this. After a lot of gameplay storage files might get very large and I'm worried about performance issues. What do you think?
  5. I would likely store these in a custom config file because I want games to be preserved across restarts. Still not sure if it's the best solution though - especially if there are going to be a lot of games with a lot of blocks being placed at the same time.
  6. I don't think this is the best solution.
    If you have a database, you should better store it there, or in an SQLite database.
    • Agree Agree x 1
  7. Here‘s two other thoughts:
    1) define an arbitrary shaped region (cuboid is probably the best) where you can‘t break blocks
    2) only allow that certain blocks may be placed and then check for the type

    probably the best approach is a combination of all three in some ways...
  8. Neither of these are viable. To be terse, the maps are complex structures and it would be mindnumbingly tedious to mark everything in regions, and players are able to place blocks that are also in maps - for example obsidian.

    I wonder if I could store NBT data on map blocks and check for this when players break blocks. Would this be bad practice?

    Thanks for all the suggestions, guys!
  9. Well I think it is not bad practice.

    Oops, I misunderstood you, no that is a BAD practice for sure.
    Better would be if you place NBT on the blocks that players placed.
  10. Interesting! Why?
  11. How big is your map?
    You probably should have to add NBT to about 100k blocks, and how are you gonna add them.
    It would take a lot of time adding NBT tags to all of the non-breakable blocks in first place for the map.
    After that, it doesn't really actually matter.

    But if you just add nbt to play-placed blocks
    on block place event, and just allow them to be broken you save up some work.
  12. What I meant to say is that you certainly have a number of regions, Islands maybe, that define effectively maybe 20% or so of your map (if we look at standard bedwars maps). You could define a Box around these to notify that there is "special care" to be taken when breaking or placing a block inside those regions. Outside, you can be certain, that placement and breaking can be done without interfering with the map.

    Because custom NBT-Tags are not persistently saved. There exist methods, however (you could save them yourself or use Bukkits persistent data interface)
  13. Actually.. Can blocks even store NBT data? Isn't it only items?
  14. Nbt is used for virtually everything, just take a look at Chests or Furnaces.
  15. blocks cant store data, only entities/items can (interactable blocks are tile entities).

    store a set of blocks or setlocations and check if the set contains the block. dont use a list or array.
    • Agree Agree x 1
    • Informative Informative x 1