diff options
| author | Myles <mylesandmore9@gmail.com> | 2022-12-10 01:23:40 -0600 | 
|---|---|---|
| committer | Myles <mylesandmore9@gmail.com> | 2022-12-10 01:23:40 -0600 | 
| commit | a56513d85180c699b566783d7e1ce1f12d641aa4 (patch) | |
| tree | 406d942b7b40f91de92224f18b49fe295c9e341d | |
| parent | 074bd245939ae6cd29d5e2a55840fdecc512716e (diff) | |
| download | Tumble-a56513d85180c699b566783d7e1ce1f12d641aa4.tar.gz Tumble-a56513d85180c699b566783d7e1ce1f12d641aa4.tar.bz2 Tumble-a56513d85180c699b566783d7e1ce1f12d641aa4.zip | |
1AM COMMIT LETS GOOOO
- fixed about 20 bugs, glitches, exploits, you name it--Jacob can break anything (not even joking, did my first *real* playtest; it was...valuable...we'll leave it at that)
- added some sort of block balancing (want to improve on it later maybe?)
- change the prefix back to lowercase because we're emo or something (COMMONALITY SHUT UP)
- game env is now more controlled (thanks Jacob)
- can I go to bed now
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | src/main/java/com/MylesAndMore/tumble/EventListener.java | 120 | ||||
| -rw-r--r-- | src/main/java/com/MylesAndMore/tumble/Game.java | 40 | ||||
| -rw-r--r-- | src/main/java/com/MylesAndMore/tumble/Main.java | 10 | ||||
| -rw-r--r-- | src/main/java/com/MylesAndMore/tumble/commands/SetWorldConfig.java | 1 | ||||
| -rw-r--r-- | src/main/resources/config.yml | 2 | 
6 files changed, 142 insertions, 33 deletions
| @@ -16,7 +16,7 @@ once this list is complete and all bugs are fixed, we *should* be ready for rele  - [x] make the shovel in shovels mode not lose any durabilty  - [x] make it so that you can't move until the game begins -- [ ] make the game blocks breakable very fast, but **not instantly--very important for balancing!!** +- [x] make the game blocks breakable very fast, but **not instantly--very important for balancing!!**    - Basically, just set a "cooldown" on both snowballs and shovels--not a long one--but one at that  - [ ] add infinite snowballs in the gamemanager for tumble mode    - [x] make it so that you can't remove any of the game items from your inventory diff --git a/src/main/java/com/MylesAndMore/tumble/EventListener.java b/src/main/java/com/MylesAndMore/tumble/EventListener.java index dd42ea2..a18a9d3 100644 --- a/src/main/java/com/MylesAndMore/tumble/EventListener.java +++ b/src/main/java/com/MylesAndMore/tumble/EventListener.java @@ -4,14 +4,15 @@ import java.util.Objects;  import org.bukkit.Bukkit;  import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment;  import org.bukkit.entity.Player;  import org.bukkit.entity.Snowball;  import org.bukkit.event.EventHandler;  import org.bukkit.event.Listener; -import org.bukkit.event.entity.FoodLevelChangeEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.entity.ProjectileHitEvent; -import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDropItemEvent; +import org.bukkit.event.entity.*;  import org.bukkit.event.player.*;  import org.bukkit.inventory.ItemStack;  import org.bukkit.util.Vector; @@ -105,20 +106,18 @@ public class EventListener implements Listener {      }      @EventHandler -    public void ItemDamageEvent(PlayerItemDamageEvent event) { +    public void PlayerItemDamageEvent(PlayerItemDamageEvent event) {          if (TumbleManager.getGameWorld() == null) {              return;          } -        // On a BlockBreakEvent, -        // check to see if the block was broken in the gameWorld, +        // On an ItemDamageEvent +        // check to see if the item was damaged in the gameWorld,          if (event.getPlayer().getWorld() == Bukkit.getWorld(TumbleManager.getGameWorld())) { -            // If it was in the gameWorld, check if the roundType was shovels -            if (Objects.equals(Game.getGame().getRoundType(), "shovels")) { -                event.setCancelled(true); -            } +            event.setCancelled(true);          }      } +    private long lastTimeP;      @EventHandler      public void ProjectileLaunchEvent(ProjectileLaunchEvent event) {          if (TumbleManager.getGameWorld() == null) { @@ -129,7 +128,22 @@ public class EventListener implements Listener {          if (event.getEntity().getWorld() == Bukkit.getWorld(TumbleManager.getGameWorld())) {              if (event.getEntity() instanceof Snowball) {                  if (event.getEntity().getShooter() instanceof Player player) { -                    player.getInventory().addItem(new ItemStack(Material.SNOWBALL, 1)); +                    // Check to see if the last snowball was thrown less than 200ms ago, if so, don't allow another +                    if ((System.currentTimeMillis() - lastTimeP) < 200) { event.setCancelled(true); } +                    else { +                        // Otherwise, continue with logic +                        lastTimeP = System.currentTimeMillis(); +                        // This prevents players from shooting snowballs before the game actually begins +                        if (Objects.equals(Game.getGame().getGameState(), "starting")) { +                            event.setCancelled(true); +                        } +                        else { +                            // This gives players a snowball when they've used one +                            Bukkit.getServer().getScheduler().runTask(TumbleManager.getPlugin(), () -> { +                                player.getInventory().addItem(new ItemStack(Material.SNOWBALL, 1)); +                            }); +                        } +                    }                  }              }          } @@ -140,6 +154,10 @@ public class EventListener implements Listener {          if (TumbleManager.getGameWorld() == null) {              return;          } +        // Weird stacktrace thing +        else if (event.getHitBlock() == null) { +            return; +        }          // When a projectile hits          // check to see if the projectile hit in the gameWorld,          if (event.getHitBlock().getWorld() == Bukkit.getWorld(TumbleManager.getGameWorld())) { @@ -151,8 +169,8 @@ public class EventListener implements Listener {                      if (event.getHitBlock() != null) {                          // if it was a block, check if that block is within the game area,                          if (event.getHitBlock().getLocation().distanceSquared(Bukkit.getWorld(TumbleManager.getGameWorld()).getSpawnLocation()) < 402) { -                        // then remove that block. -                        event.getHitBlock().setType(Material.AIR); +                            // then remove that block. +                            event.getHitBlock().setType(Material.AIR);                          }                      }                      else if (event.getHitEntity() != null) { @@ -161,15 +179,11 @@ public class EventListener implements Listener {                              // then cancel the knockback (has to be delayed by a tick for some reason)                              Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(TumbleManager.getPlugin(), () -> {                                  hitPlayer.setVelocity(new Vector()); -                            }, 1); +                            });                          }                      }                  }              } -            // Weird stacktrace thing -            else if (event.getHitBlock().getWorld() == null) { -                event.setCancelled(true); -            }          }      } @@ -187,10 +201,58 @@ public class EventListener implements Listener {      @EventHandler      public void PlayerMoveEvent(PlayerMoveEvent event) { +        if (TumbleManager.getGameWorld() == null) { +            return; +        }          // On a PlayerMoveEvent, check if the game is starting          if (Objects.equals(Game.getGame().getGameState(), "starting")) { -            // Cancel the event if the game is starting (so players can't move before the -            // game starts) +            // Cancel the event if the game is starting (so players can't move before the game starts) +            event.setCancelled(true); +        } +    } + +    @EventHandler +    public void BlockDropItemEvent(BlockDropItemEvent event) { +        if (TumbleManager.getGameWorld() == null) { +            return; +        } +        // If a block was going to drop an item (ex. snow dropping snowballs) in the GameWorld, cancel it +        if (event.getBlock().getWorld() == Bukkit.getWorld(TumbleManager.getGameWorld())) { +            event.setCancelled(true); +        } +    } + +    private long lastTimeI; +    @EventHandler +    public void PlayerInteractEvent(PlayerInteractEvent event) { +        if (TumbleManager.getGameWorld() == null) { +            return; +        } +        // Check if a player was left clicking a block in the gameWorld +        if (event.getAction() == Action.LEFT_CLICK_BLOCK) { +            if (event.getClickedBlock().getWorld() == Bukkit.getWorld(TumbleManager.getGameWorld())) { +                // Then check if it was with an item enchanted w/ silk touch +                if (event.getPlayer().getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH)) { +                    // Then check to see if the player interacted less than 150ms ago +                    if ((System.currentTimeMillis() - lastTimeI) < 150) return; +                    // If not, set that block to air (break it) +                    else { +                        lastTimeI = System.currentTimeMillis(); +                        event.getClickedBlock().setType(Material.AIR); +                    } +                } +            } +        } +    } + +    @EventHandler +    public void BlockBreakEvent(BlockBreakEvent event) { +        if (TumbleManager.getGameWorld() == null) { +            return; +        } +        // This just doesn't allow blocks to break in the gameWorld; the PlayerInteractEvent will take care of everything +        // It just keeps client commonality w/ animations and stuff +        if (event.getBlock().getWorld() == Bukkit.getWorld(TumbleManager.getGameWorld())) {              event.setCancelled(true);          }      } @@ -200,10 +262,22 @@ public class EventListener implements Listener {          if (TumbleManager.getGameWorld() == null) {              return;          } -        // When someone's food level changes -        // check if that happened in the gameWorld +        // When someone's food level changes, check if that happened in the gameWorld, then cancel it          if (event.getEntity().getWorld() == Bukkit.getWorld(TumbleManager.getGameWorld())) {              event.setCancelled(true);          }      } + +    @EventHandler +    public void EntityDamageEvent(EntityDamageEvent event) { +        if (TumbleManager.getGameWorld() == null) { +            return; +        } +        // Check to see if a player got damaged in the gameWorld, if so, cancel it +        if (event.getEntity().getWorld() == Bukkit.getWorld(TumbleManager.getGameWorld())) { +            if (event.getEntity() instanceof Player) { +                event.setCancelled(true); +            } +        } +    }  } diff --git a/src/main/java/com/MylesAndMore/tumble/Game.java b/src/main/java/com/MylesAndMore/tumble/Game.java index 6d085df..7de988a 100644 --- a/src/main/java/com/MylesAndMore/tumble/Game.java +++ b/src/main/java/com/MylesAndMore/tumble/Game.java @@ -6,6 +6,7 @@ import net.md_5.bungee.api.ChatMessageType;  import net.md_5.bungee.api.chat.TextComponent;  import org.bukkit.*; +import org.bukkit.enchantments.Enchantment;  import org.bukkit.entity.Player;  import org.bukkit.inventory.ItemStack;  import org.jetbrains.annotations.NotNull; @@ -78,6 +79,8 @@ public class Game {                  gameState = "starting";                  // Set the roundType to gameType since it won't change for this mode                  roundType = type; +                // Clear the players' inventories so they can't bring any items into the game +                clearInventories(TumbleManager.getPlayersInLobby());                  // Generate the correct layers for a Shovels game                  // The else statement is just in case the generator fails; this command will fail                  if (generateLayers(type)) { @@ -92,6 +95,7 @@ public class Game {              else if (Objects.equals(type, "snowballs")) {                  gameState = "starting";                  roundType = type; +                clearInventories(TumbleManager.getPlayersInLobby());                  if (generateLayers(type)) {                      scatterPlayers(TumbleManager.getPlayersInLobby());                  } @@ -102,6 +106,7 @@ public class Game {              else if (Objects.equals(type, "mixed")) {                  gameState = "starting";                  roundType = type; +                clearInventories(TumbleManager.getPlayersInLobby());                  if (generateLayers(type)) {                      scatterPlayers(TumbleManager.getPlayersInLobby());                  } @@ -187,7 +192,7 @@ public class Game {          // Otherwise, the game must have two people left (and one just died), meaning it is over          // This logic is so that it will not remove the last player standing from the list, so we know who the winner is.          else { -            // roundPlayers.remove(player); +            roundPlayers.remove(player);              // End the game, passing the winner to the gameEnd method              roundEnd(roundPlayers.get(0));          } @@ -229,11 +234,19 @@ public class Game {              Generator.generateLayer(layer, 13, 1, Material.AIR);              layer.setY(layer.getY() - 1);              Generator.generateLayer(layer, 13, 1, Material.GRASS_BLOCK); +            Generator.generateLayer(layer, 4, 1, Material.AIR);              layer.setY(layer.getY() - 1);              Generator.generateLayer(layer, 4, 1, Material.PODZOL);              layer.setY(layer.getY() + 2);              Generator.generateLayer(layer, 4, 2, Material.TALL_GRASS); -            giveItems(TumbleManager.getPlayersInLobby(), new ItemStack(Material.IRON_SHOVEL)); +            ItemStack shovel = new ItemStack(Material.IRON_SHOVEL); +            shovel.addEnchantment(Enchantment.SILK_TOUCH, 1); +            if (Objects.equals(gameState, "running")) { +                giveItems(TumbleManager.getPlayersInGame(), shovel); +            } +            else if (Objects.equals(gameState, "starting")) { +                giveItems(TumbleManager.getPlayersInLobby(), shovel); +            }          }          else if (Objects.equals(type, "snowballs")) {              layer.setY(layer.getY() - 1); @@ -244,7 +257,12 @@ public class Game {              Generator.generateLayer(layer, 4, 1, Material.AIR);              layer.setY(layer.getY() - 1);              Generator.generateLayer(layer, 4, 1, Material.LIME_GLAZED_TERRACOTTA); -            giveItems(TumbleManager.getPlayersInLobby(), new ItemStack(Material.SNOWBALL)); +            if (Objects.equals(gameState, "running")) { +                giveItems(TumbleManager.getPlayersInGame(), new ItemStack(Material.SNOWBALL)); +            } +            else if (Objects.equals(gameState, "starting")) { +                giveItems(TumbleManager.getPlayersInLobby(), new ItemStack(Material.SNOWBALL)); +            }          }          else if (Objects.equals(type, "mixed")) {              // Randomly select either shovels or snowballs and re-run the method @@ -274,6 +292,16 @@ public class Game {      }      /** +     * Clears the inventories of a provided player list +     * @param players The player list for which to clear the inventories of +     */ +    private void clearInventories(List<Player> players) { +        for (Player aPlayer : players) { +            aPlayer.getInventory().clear(); +        } +    } + +    /**       * Sets the gamemodes of a provided list of players       * @param players The player list for which to set the gamemodes of       * @param gameMode The GameMode to set @@ -370,6 +398,10 @@ public class Game {          }          // If that player doesn't have three wins, nobody else does, so we need another round          else { +            roundPlayers.get(0).setGameMode(GameMode.SPECTATOR); +            roundPlayers.remove(0); +            roundPlayers.addAll(gamePlayers); +            clearInventories(gamePlayers);              displayTitles(gamePlayers, ChatColor.RED + "Round over!", ChatColor.GOLD + winner.getName() + " has won the round!", 5, 60, 5);              // Re-generate layers              generateLayers(roundType); @@ -399,6 +431,8 @@ public class Game {      }      private void gameEnd(Player winner) { +        winner.setGameMode(GameMode.SPECTATOR); +        clearInventories(gamePlayers);          // Announce win          displayTitles(gamePlayers, ChatColor.RED + "Game over!", ChatColor.GOLD + winner.getName() + " has won the game!", 5, 60, 5);          displayActionbar(gamePlayers, ChatColor.BLUE + "Returning to lobby in ten seconds..."); diff --git a/src/main/java/com/MylesAndMore/tumble/Main.java b/src/main/java/com/MylesAndMore/tumble/Main.java index a35a519..16f32c4 100644 --- a/src/main/java/com/MylesAndMore/tumble/Main.java +++ b/src/main/java/com/MylesAndMore/tumble/Main.java @@ -25,15 +25,15 @@ public class Main extends JavaPlugin{          // Check if worlds are null in config          if (TumbleManager.getGameWorld() == null) { -            Bukkit.getServer().getLogger().warning("[Tumble] It appears you have not configured a game world for Tumble."); -            Bukkit.getServer().getLogger().info("[Tumble] If this is your first time running the plugin, you may disregard this message."); +            Bukkit.getServer().getLogger().warning("[tumble] It appears you have not configured a game world for Tumble."); +            Bukkit.getServer().getLogger().info("[tumble] If this is your first time running the plugin, you may disregard this message.");          }          if (TumbleManager.getLobbyWorld() == null) { -            Bukkit.getServer().getLogger().warning("[Tumble] It appears you have not configured a lobby world for Tumble."); -            Bukkit.getServer().getLogger().info("[Tumble] If this is your first time running the plugin, you may disregard this message."); +            Bukkit.getServer().getLogger().warning("[tumble] It appears you have not configured a lobby world for Tumble."); +            Bukkit.getServer().getLogger().info("[tumble] If this is your first time running the plugin, you may disregard this message.");          }          // Init message -        Bukkit.getServer().getLogger().info("[Tumble] Tumble initialization complete!"); +        Bukkit.getServer().getLogger().info("[tumble] Tumble initialization complete!");      }  }
\ No newline at end of file diff --git a/src/main/java/com/MylesAndMore/tumble/commands/SetWorldConfig.java b/src/main/java/com/MylesAndMore/tumble/commands/SetWorldConfig.java index 74eaf0d..695c248 100644 --- a/src/main/java/com/MylesAndMore/tumble/commands/SetWorldConfig.java +++ b/src/main/java/com/MylesAndMore/tumble/commands/SetWorldConfig.java @@ -52,6 +52,7 @@ public class SetWorldConfig implements CommandExecutor {                              TumbleManager.getPlugin().saveConfig();                              // Set the gamerule of doImmediateRespawn in the gameWorld for later                              Bukkit.getWorld(world).setGameRule(GameRule.DO_IMMEDIATE_RESPAWN, true); +                            Bukkit.getWorld(world).setGameRule(GameRule.KEEP_INVENTORY, true);                              sender.sendMessage(ChatColor.GREEN + "Game world successfully linked: " + ChatColor.GRAY + world);                              sender.sendMessage(ChatColor.GREEN + "Please restart your server for the changes to take effect; " + ChatColor.RED + "reloading the plugin is insufficient!");                          } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 6a9f62d..bc68c35 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,5 @@  # Hides join/leave messages in public chat -# Default is true +# Default is false  hideJoinLeaveMessages: false  # Customize the message that displays when the player does not have permission to execute a command from this plugin | 
