Customize GameModes! [Create a spectator mode]

Discussion in 'Resources' started by ccrama, Feb 10, 2014.

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

    ccrama

    Hello Bukkit,

    I have been thinking of good ways to let players become spectators in my minigame without utilizing lists or tons of code just to do some simple functions like invisibility or fly. I came up with the idea of editing the ADVENTURE gamemode to better suit my needs, as it is easy to set, edit, and it is easy to check if a player is a "spectator".

    I will be hooking into the PlayerGameModeChangeEvent for this tutorial, as it will let me intercept if a player is being changed to ADVENTURE mode.

    First we start with the GameMode Change event. Make sure your onEnable is registering events or it won't work.

    Code:java
    1. @EventHandler
    2. public void onGameModeChange(PlayerGameModeChangeEvent e){
    3. }


    This will fire every time someone changes gamemodes. Let's add some functionality

    Code:java
    1. @EventHandler
    2. public void onGameModeChange(PlayerGameModeChangeEvent e){
    3. if(e.getNewGameMode() == GameMode.ADVENTURE){
    4.  
    5. } else {
    6. }
    7. }


    This will make sure we are only doing this to the ADVENTURE gamemode. For my uses, I want players to teleport 5 blocks up when they are spectating, and I want them to be able to fly. I also want them to be invisible to all online players.

    Code:java
    1. @EventHandler
    2. public void gamemode(PlayerGameModeChangeEvent e){
    3. final Player p = e.getPlayer();
    4. if(e.getNewGameMode() == GameMode.ADVENTURE){
    5.  
    6. final Plugin yourPlugin= Bukkit.getPluginManager().getPlugin(your plugin here!); //make sure to replace with YOUR plugin
    7. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(yourPlugin, new Runnable()//start a delay so flight will work
    8. {
    9. public void run()
    10. {
    11. p.setAllowFlight(true); //lets players fly
    12. p.setFlying(true); //sets player to flying
    13. p.teleport(p.getLocation().add(0,5,0)); //teleports player 5 blocks up
    14.  
    15. }
    16. }, 2L);
    17. for(Player pla: Bukkit.getOnlinePlayers()){
    18. pla.hidePlayer(e.getPlayer()); //hides players to all online players
    19. }
    20.  
    21. e.getPlayer().sendMessage(ChatColor.RED + "You are now a spectator!"); //tells player he is a spectator
    22.  
    23.  
    24. } else {
    25. }
    26. }


    The delay is crucial, as the player won't fly without it. This will also send a message to the player saying he is now a spectator. If you plan on restarting a game once it's done, you will want to reset the player back into survival mode. We need to set an else statement to remove fly and invisibility.

    Code:java
    1. @EventHandler
    2. public void gamemode(PlayerGameModeChangeEvent e){
    3. final Player p = e.getPlayer();
    4. if(e.getNewGameMode() == GameMode.ADVENTURE){
    5.  
    6. final Plugin yourPlugin= Bukkit.getPluginManager().getPlugin(your plugin here!);
    7. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(yourPlugin, new Runnable()
    8. {
    9. public void run()
    10. {
    11. p.setAllowFlight(true);
    12. p.setFlying(true);
    13. p.teleport(p.getLocation().add(0,5,0));
    14.  
    15. }
    16. }, 2L);
    17. for(Player pla: Bukkit.getOnlinePlayers()){
    18. pla.hidePlayer(e.getPlayer());
    19. }
    20.  
    21. e.getPlayer().sendMessage(ChatColor.RED + "You are now a spectator!");
    22.  
    23.  
    24. } else { //will fire when player is changed to SURVIVAL or CREATIVE gamemodes
    25. for(Player pla:Bukkit.getOnlinePlayers()){ //reshows a player to all online players
    26. pla.showPlayer(e.getPlayer());
    27.  
    28. }
    29. e.getPlayer().setAllowFlight(false); //disallows flight
    30. e.getPlayer().setFlying(false); //makes them stop flying if they are in flight
    31. e.getPlayer().teleport(your location here); //teleport them to spawn if they are no longer spectator
    32. }
    33. }


    You're done with that part! To make the player change to adventure mode, use
    Code:java
    1. e.getPlayer().setGameMode(GameMode.ADVENTURE);
    2.  


    and

    Code:java
    1. e.getPlayer().setGameMode(GameMode.SURVIVAL);
    2.  


    to reset them.

    EXTRA:
    To hook into events to check if a player is in this gamemode or not, you can use

    Code:java
    1. if(player.getGameMode() == GameMode.ADVENTURE){


    For my needs, I want the player to teleport to another living player on interact event.

    Code:java
    1. @EventHandler
    2. public void teleport(PlayerInteractEvent e){
    3. if(e.getPlayer().getGameMode() == GameMode.ADVENTURE){
    4. int rand = new Random().nextInt(Bukkit.getOnlinePlayers().size()); //get a random player
    5. Player player = Bukkit.getOnlinePlayers()[rand]; //choose a player based on our random player
    6. if(player == e.getPlayer()){
    7. e.setCancelled(true);
    8. } else {
    9. if(p.getGameMode() == GameMode.ADVENTURE){
    10. e.setCancelled(true);
    11. } else {
    12. p.setPassenger(e.getPlayer()); //sets the player in ADVENTURE mode to ride the living player
    13. }
    14. }
    15.  
    16. }
    17. }




    You can also edit the event to cancel chat or breaking blocks to suit your needs. I hope someone gets some use out of this method!

    Cheers,
    ccrama
     
    MrAwellstein likes this.
  2. Offline

    DarkBladee12

    ccrama Well but you're kind of limited with this, because you can only use the Adventure game mode. I you'd have more possibilities if you modify the game mode enum with Jogy34 's EnumModifier. However the "spectator" mode is going to implemented in 1.8 so you don't even have to create one then ;)
     
  3. Offline

    Jogy34

    Wow, I got really confused as to where I was tagged in this post at first.

    Anyways, if you do want to do that you can find my post that has that stuff here under the modifiers section. Be careful with it though and let me know if how it turns out if you end up trying it.
     
  4. Offline

    ccrama

    DarkBladee12, Yeah, just learned about that... Apart from this, I think I'll check out Jogy34 's enum modifier, looks pretty cool :)
     
  5. Offline

    Jogy34

    I looked into it a little bit. It doesn't seem like it would be as easy as just adding to the bukkit enum. You'll also have to mess with the NMS EnumGamemode.
     
  6. Offline

    Ultimate_n00b

    I was about to say this as I was reading down the post.
     
    ccrama likes this.
  7. Offline

    ccrama

    Ultimate_n00b Yeah, wish I knew this. At least this will work to tide you over for a few more months (and possibly a few more after MC is released before Bukkit updates)!
     
  8. Offline

    Ultimate_n00b

    I just coded it actually.
     
  9. Offline

    HeavyMine13

    You need to make him invincible and invisible
     
  10. Offline

    ccrama

    HeavyMine13 He is invisible, and as I stated below it you can check if the user is in adventure mode, and cancel damage events :)
     
Thread Status:
Not open for further replies.

Share This Page