[Resource] Dynamic Signwall

Discussion in 'Resources' started by Ivan, Aug 23, 2013.

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

    Ivan

    I made this class to show how easy it is to create one of those fancy dynamic sign-walls that servers like Hypixel, Armadacraft and MineCade (last 2 are basically the same) are having. I added comments to explain what I'm doing in every method. The only thing you have to do is create a GameInstance class that represents an instance of your minigame. Feel free to modify or give me some constructive criticism! :)

    Code:java
    1. import org.bukkit.block.Sign;
    2. import org.bukkit.event.EventHandler;
    3. import org.bukkit.event.Listener;
    4. import org.bukkit.event.block.Action;
    5. import org.bukkit.event.player.PlayerInteractEvent;
    6. import org.bukkit.plugin.java.JavaPlugin;
    7. import org.bukkit.scheduler.BukkitRunnable;
    8.  
    9. import java.util.ArrayList;
    10. import java.util.HashMap;
    11. import java.util.LinkedList;
    12. import java.util.Queue;
    13.  
    14. /**
    15.  * User: Ivan
    16.  * Date: 24/08/13
    17.  * Time: 0:05
    18.  * IDE: IntelliJ IDEA
    19.  * Look me up on bukkit forums!
    20.  * [url]http://forums.bukkit.org/members/ivan.5352/[/url]
    21.  */
    22. public class SignWall extends BukkitRunnable implements Listener {
    23.  
    24. HashMap<Sign,GameInstance> signpool = new HashMap();
    25. Queue<GameInstance> gamequeue = new LinkedList<GameInstance>();
    26. JavaPlugin plugin;
    27.  
    28.  
    29. /*
    30.   The constructor fills our signpool up with sig schedules a
    31.   new bukkit task and registers the associated listener for us.
    32.   */
    33. public SignWall(Sign[] signs,JavaPlugin plugin){
    34. for(Sign sign:signs)
    35. signpool.put(sign,null);
    36.  
    37. this.plugin = plugin;
    38. this.runTaskTimer(plugin, 0, 20L);
    39. plugin.getServer().getPluginManager().registerEvents(this, plugin);
    40. }
    41.  
    42. /*
    43.   Gets an empty sign out of our signpool
    44.   */
    45. public Sign getEmptySign(){
    46. for(Sign sign:signpool.keySet()){
    47. if(signpool.get(sign) == null)
    48. return sign;
    49. }
    50.  
    51. return null;
    52. }
    53.  
    54. /*
    55.   This will be used by the listener that will check
    56.   if there is a game associated with the clicked sign.
    57.   */
    58. public GameInstance getBySign(Sign sign){
    59. return signpool.get(sign);
    60. }
    61.  
    62. /*
    63.   This method will be called by your gameinstance
    64.   or by some kind of handler that decides when
    65.   a game should show up here on the signwall
    66.   */
    67. public void addToQueue(GameInstance instance){
    68. gamequeue.offer(instance);
    69. }
    70.  
    71. /*
    72.   This is the method called by our loop
    73.   that will decide what pops up when
    74.   the sign is empty.
    75.   */
    76. private void formatEmptySign(Sign sign){
    77. sign.setLine(0,"------------");
    78. sign.setLine(1," Waiting ");
    79. sign.setLine(3,"------------");
    80. }
    81.  
    82. /*
    83.   This is our loop. Here is where the magic
    84.   happens :).
    85.   */
    86. @Override
    87. public void run() {
    88.  
    89.  
    90. /* This part removes full games from the signwall,
    91.   since they don't need players anymore*/
    92. for(Sign sign:signpool.keySet()){
    93. GameInstance instance = signpool.get(sign);
    94.  
    95. /* If it no longer needs players,
    96.   remove it from the board*/
    97. if(!instance.needsPlayers()){
    98. signpool.put(sign,null);
    99. formatEmptySign(sign);
    100. sign.update();
    101. }
    102. }
    103.  
    104.  
    105. /* This part checks if more games have to be added to the list
    106.   */
    107. while(!gamequeue.isEmpty()){
    108. Sign emptysign = getEmptySign();
    109.  
    110. /* If no signs are availible, break out of the loop
    111.   */
    112. if(emptysign == null)
    113. break;
    114.  
    115. GameInstance instance = gamequeue.poll();
    116. instance.formatSign(emptysign);
    117. emptysign.update();
    118. signpool.put(emptysign, instance);
    119.  
    120. }
    121.  
    122. }
    123.  
    124. /*
    125.   This is the listener part of our controller.
    126.   It checks if a game is associated with the
    127.   clicked sign.
    128.   */
    129. @EventHandler
    130. public void onJoinAttempt(PlayerInteractEvent event){
    131. if(event.getPlayer().getWorld().getName().equalsIgnoreCase("lobby") &&
    132. event.getAction() == Action.RIGHT_CLICK_BLOCK &&
    133. event.getClickedBlock().getState() instanceof Sign){
    134.  
    135. GameInstance instance = getBySign((Sign) event.getClickedBlock().getState());
    136.  
    137. /* If there is a game associated, tell the gameinstance
    138.   that someone is trying to join. It will return us a
    139.   string with the message that the player will receive.
    140.   If there is still a spot left for him, the instance
    141.   can teleport him using the joinAttempt() method.
    142.   */
    143. if(instance != null)
    144. event.getPlayer().sendMessage(instance.joinAttempt(event.getPlayer()));
    145. }
    146. }
    147. }
    148.  
     
  2. Offline

    user_43347

    Except it lack's Armadacraft's sorting method I put blood, sweat, and tears into :p
     
  3. Offline

    Loogeh

    Awesome tutorial Ivan, I know quite a few people want to learn how to do this.
     
  4. Offline

    Garris0n

    If I remember right it's more efficient to check the type of the block than get its state and check if it's a sign. Not positive, though.
     
Thread Status:
Not open for further replies.

Share This Page