Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
**ForceBattle** is a multiplayer gamemode where players compete to complete randomized objectives and earn points.
The player with the most points after the timer ends wins the battle!

Current supported Minecraft version: 1.21.8
Currently supports Minecraft version: 1.21.8

**Objective types include:**
- 🔹 Collect an item
- 🔹 Kill a mob
- 🔹 Discover a biome
- 🔹 Complete an advancement
- 🔹 Reach a certain height
- 🔹 Reach a certain coordinate
- 🔹 Discover a certain structure
- Collect an item
- Kill a mob
- Discover a biome
- Complete an advancement
- Reach a certain height
- Reach a certain coordinate
- Discover a certain structure


Objective types can be enabled or disabled individually via the plugin's settings menu.
Expand All @@ -39,23 +39,23 @@ Objective types can be enabled or disabled individually via the plugin's setting

### 📋 Commands

| Command | Description |
|:----------------------------|:-----------------------------------------------------------|
| `/backpack <player>` | Opens the personal or teammates backpack (can be disabled) |
| `/displayresults` | Show the final leaderboard (player, team) |
| `/exclude <player>` | Exclude a player from the battle |
| `/help` | Display a list of available commands |
| `/joker <player> <amount>` | Adjust jokers for a player |
| `/language` | Open the language selection menu |
| `/points <player> <amount>` | Modify a player's points |
| `/randomteams <teamsize>` | Creates random teams with a specific size |
| `/recipe <item>` | Displays the recipe of an item |
| `/reset [player]` | Reset the battle or a specific player |
| `/result <player>` | Show detailed results for a player |
| `/settings` | Open the plugin's settings menu |
| `/skip <player>` | Skip a player's current objective (for admins) |
| `/team` | Manage teams |
| `/timer` | Control the timer (start, stop, set duration) |
| Command | Description |
|:----------------------------|:------------------------------------------------------|
| `/backpack` | Opens the personal or team backpack (can be disabled) |
| `/displayresults` | Show the final leaderboard (player, team) |
| `/exclude <player>` | Exclude a player from the battle |
| `/help` | Display a list of available commands |
| `/joker <player> <amount>` | Adjust jokers for a player |
| `/language` | Open the language selection menu |
| `/points <player> <amount>` | Modify a player's points |
| `/randomteams <teamsize>` | Creates random teams with a specific size |
| `/recipe <item>` | Displays the recipe of an item |
| `/reset [player]` | Reset the battle or a specific player |
| `/result <player>` | Show detailed results for a player |
| `/settings` | Open the plugin's settings menu |
| `/skip <player>` | Skip a player's current objective (for admins) |
| `/team` | Manage teams |
| `/timer` | Control the timer (start, stop, set duration) |

---

Expand Down
6 changes: 2 additions & 4 deletions src/main/java/net/fameless/forcebattle/ForceBattle.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
import net.fameless.forcebattle.command.framework.PermissionManager;
import net.fameless.forcebattle.configuration.PluginUpdater;
import net.fameless.forcebattle.configuration.SettingsFile;
import net.fameless.forcebattle.game.GameListener;
import net.fameless.forcebattle.game.NametagManager;
import net.fameless.forcebattle.game.ObjectiveManager;
import net.fameless.forcebattle.game.Timer;
import net.fameless.forcebattle.gui.GUIListener;
import net.fameless.forcebattle.scoreboard.ScoreboardManager;
import net.fameless.forcebattle.util.BukkitUtil;
import net.fameless.forcebattle.util.EventRegistrar;
import net.fameless.forcebattle.util.ResourceUtil;
import net.kyori.adventure.text.Component;
import org.bstats.bukkit.Metrics;
Expand Down Expand Up @@ -55,8 +54,7 @@ public void onEnable() {

NametagManager.runTask();

Bukkit.getPluginManager().registerEvents(new GameListener(), this);
Bukkit.getPluginManager().registerEvents(new GUIListener(), this);
EventRegistrar.registerAll(this, "net.fameless.forcebattle");

CommandHandler.registerAll(Command.COMMANDS);
PermissionManager.registerPermissions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
import net.fameless.forcebattle.command.framework.Command;
import net.fameless.forcebattle.command.framework.CommandCaller;
import net.fameless.forcebattle.configuration.SettingsManager;
import net.fameless.forcebattle.game.GameListener;
import net.fameless.forcebattle.player.BattlePlayer;
import net.fameless.forcebattle.util.StringUtility;
import net.fameless.forcebattle.util.TabCompletions;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

Expand All @@ -21,7 +19,7 @@ public BackpackCommand() {
"backpack",
List.of("bp"),
CallerType.PLAYER,
"/backpack <player>",
"/backpack",
"forcebattle.backpack",
"Command to open the backpack"
);
Expand All @@ -33,29 +31,15 @@ public void executeCommand(CommandCaller caller, String[] args) {
caller.sendMessage(Caption.of("error.backpacks_disabled"));
return;
}
if (GameListener.startPhase) return;

Optional<BattlePlayer> senderOpt = BattlePlayer.adapt(caller.getName());

if (args.length > 0 && !args[0].isEmpty()) {
Optional<BattlePlayer> targetOpt = BattlePlayer.adapt(args[0]);

if (senderOpt.isPresent() && targetOpt.isPresent() && senderOpt.get().isInTeam() && targetOpt.get().isInTeam() &&
senderOpt.get().getTeam() == targetOpt.get().getTeam()) {
targetOpt.get().openBackpack(senderOpt.get());
return;
}

caller.sendMessage(Caption.of("error.not_same_team"));
} else {
senderOpt.ifPresent(BattlePlayer::openBackpack);
}
senderOpt.ifPresent(BattlePlayer::openBackpack);
}

@Override
public List<String> tabComplete(CommandCaller caller, String @NotNull [] args) {
if (args.length == 1) {
return StringUtility.copyPartialMatches(args[0], TabCompletions.getPlayerNamesTabCompletions(), new ArrayList<>());
}
return List.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,6 @@ protected void executeCommand(final CommandCaller caller, final String[] args) {

caller.sendMessage(Caption.of("notification.randomteams_successfully_created",
TagResolver.resolver("amount", Tag.inserting(Component.text(String.valueOf(amountOfTeams))))));

for (Team team : Team.teams) {
List<String> names = new ArrayList<>();
for (BattlePlayer player : team.getPlayers()) {
names.add(player.getName() + ", ");
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public enum Setting {
EXCLUDE_ARMOR_TEMPLATES,
EXCLUDE_POTTERY_SHERDS,
EXCLUDE_ORES,
EXCLUDE_END_ITEMS,
EXCLUDE_END,
EXCLUDE_TRIAL_ITEMS,
}

Expand Down
11 changes: 7 additions & 4 deletions src/main/java/net/fameless/forcebattle/game/GameListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
private final List<BattlePlayer> teamSkipCooldown = new ArrayList<>();
private final List<BattlePlayer> swapCooldown = new ArrayList<>();
private boolean sentUpdateMessage = false;
private boolean startPhase = true;
public static boolean startPhase = true;
public static boolean spawnCreated = false;
public static Location spawn = new Location(Bukkit.getWorld("world"), 0.5, 201, 0.5);

Expand All @@ -75,9 +75,8 @@
TaskManager.startAll();
}

//TODO better tablist
//TODO evtl /item => zeigt rezept an => wenn gui system done is
//TODO commands von cords ausführen (for spawn)
//TODO does chain mode work with team objective?

Check warning on line 78 in src/main/java/net/fameless/forcebattle/game/GameListener.java

View check run for this annotation

codefactor.io / CodeFactor

src/main/java/net/fameless/forcebattle/game/GameListener.java#L78

Resolve unexpected comment. (com.puppycrawl.tools.checkstyle.checks.TodoCommentCheck)
//TODO support only team objective if not already possible

Check warning on line 79 in src/main/java/net/fameless/forcebattle/game/GameListener.java

View check run for this annotation

codefactor.io / CodeFactor

src/main/java/net/fameless/forcebattle/game/GameListener.java#L79

Resolve unexpected comment. (com.puppycrawl.tools.checkstyle.checks.TodoCommentCheck)

@EventHandler
public void onPlayerLogin(AsyncPlayerPreLoginEvent event) {
Expand Down Expand Up @@ -193,6 +192,10 @@

player.getPlayer().teleport(world.getSpawnLocation());
}

for (Team team : Team.teams) {
team.createBackpackGUIs();
}
}

@EventHandler
Expand Down
92 changes: 61 additions & 31 deletions src/main/java/net/fameless/forcebattle/game/ObjectiveManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.bukkit.entity.Player;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -117,25 +116,25 @@ private Objective generateObjective(BattleType battleType, BattlePlayer battlePl
private List<String> getAllPossibleObjectives(BattleType battleType, BattlePlayer battlePlayer) {
List<String> list = new ArrayList<>();
switch (battleType) {
case FORCE_ITEM -> getAvailableItems().forEach(i -> list.add(i.name()));
case FORCE_MOB -> getAvailableMobs().forEach(m -> list.add(m.name()));
case FORCE_ITEM -> getAvailableItems().forEach(material -> list.add(material.name()));
case FORCE_MOB -> getAvailableMobs().forEach(entityType -> list.add(entityType.name()));
case FORCE_BIOME -> {
if (SettingsManager.isEnabled(SettingsManager.Setting.SIMPLIFIED_OBJECTIVES))
getAvailableBiomesSimplified().forEach(b -> list.add(b.getName()));
getAvailableBiomesSimplified().forEach(biomeSimplified -> list.add(biomeSimplified.getName()));
else
getAvailableBiomes().forEach(b -> list.add(b.name()));
getAvailableBiomes().forEach(biome -> list.add(biome.name()));
}
case FORCE_ADVANCEMENT -> getAvailableAdvancements().forEach(a -> list.add(a.toString()));
case FORCE_HEIGHT -> getAvailableHeights().forEach(h -> list.add(String.valueOf(h)));
case FORCE_ADVANCEMENT -> getAvailableAdvancements().forEach(advancement -> list.add(advancement.toString()));
case FORCE_HEIGHT -> getAvailableHeights().forEach(height -> list.add(String.valueOf(height)));
case FORCE_COORDS -> {
Location coords = getRandomLocation(battlePlayer);
list.add(coords.getX() + "," + coords.getZ());
}
case FORCE_STRUCTURE -> {
if (SettingsManager.isEnabled(SettingsManager.Setting.SIMPLIFIED_OBJECTIVES))
getAvailableStructuresSimplified().forEach(s -> list.add(s.getName()));
getAvailableStructuresSimplified().forEach(structureSimplified -> list.add(structureSimplified.getName()));
else
getAvailableStructures().forEach(s -> list.add(s.toString()));
getAvailableStructures().forEach(structure -> list.add(structure.toString()));
}
}
return list;
Expand All @@ -150,7 +149,7 @@ public List<Material> getAvailableItems() {
boolean excludeArmorTemplates = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_ARMOR_TEMPLATES);
boolean excludePotteryShreds = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_POTTERY_SHERDS);
boolean excludeOres = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_ORES);
boolean excludeEndItems = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_END_ITEMS);
boolean excludeEndItems = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_END);

for (Material material : Material.values()) {
if (!material.isItem()) continue;
Expand Down Expand Up @@ -181,37 +180,47 @@ public List<Material> getAvailableItems() {

public List<EntityType> getAvailableMobs() {
List<EntityType> availableMobs = new ArrayList<>();
boolean excludeEndMobs = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_END);

List<String> mobsToExclude = ForceBattle.get().getConfig().getStringList("exclude.mobs");

for (EntityType entity : EntityType.values()) {
if (mobsToExclude.contains(entity.name())) {
continue;
}
if (mobsToExclude.contains(entity.name())) continue;
if (excludeEndMobs && ENDMOBS.contains(entity)) continue;

availableMobs.add(entity);
}
return availableMobs;
}

public List<Biome> getAvailableBiomes() {
List<Biome> availableBiomes = new ArrayList<>();
boolean excludeBiomes = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_END);

List<String> biomesToExclude = ForceBattle.get().getConfig().getStringList("exclude.biomes");

for (Biome biome : Biome.values()) {
if (biomesToExclude.contains(biome.name())) {
continue;
}
if (biomesToExclude.contains(biome.name())) continue;
if (excludeBiomes && ENDBIOMES.contains(biome)) continue;

availableBiomes.add(biome);
}
return availableBiomes;
}

public List<BiomeSimplified> getAvailableBiomesSimplified() {
List<BiomeSimplified> list = new ArrayList<>(Arrays.asList(BiomeSimplified.values()));
List<BiomeSimplified> availableBiomes = new ArrayList<>();
boolean excludeBiomes = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_END);

List<String> biomesToExclude = ForceBattle.get().getConfig().getStringList("exclude.biomes");
list.removeIf(b -> biomesToExclude.contains(b.getName().toUpperCase(Locale.ROOT)));
return list;

for (BiomeSimplified simplified : BiomeSimplified.values()) {
if (biomesToExclude.contains(simplified.getName().toUpperCase(Locale.ROOT))) continue;
if (excludeBiomes && ENDBIOMESSIMPLIFIED.contains(simplified)) continue;

availableBiomes.add(simplified);
}
return availableBiomes;
}

public List<FBAdvancement> getAvailableAdvancements() {
Expand All @@ -220,9 +229,8 @@ public List<FBAdvancement> getAvailableAdvancements() {
List<String> advancementsToExclude = ForceBattle.get().getConfig().getStringList("exclude.advancements");

for (FBAdvancement advancement : FBAdvancement.values()) {
if (advancementsToExclude.contains(advancement.name())) {
continue;
}
if (advancementsToExclude.contains(advancement.name())) continue;

availableAdvancements.add(advancement);
}
return availableAdvancements;
Expand All @@ -234,9 +242,8 @@ public List<Integer> getAvailableHeights() {
List<String> heightsToExclude = ForceBattle.get().getConfig().getStringList("exclude.heights");

for (int i = -63; i < 321; i++) {
if (heightsToExclude.contains(String.valueOf(i))) {
continue;
}
if (heightsToExclude.contains(String.valueOf(i))) continue;

availableHeights.add(i);
}
return availableHeights;
Expand All @@ -263,24 +270,32 @@ public Location getRandomLocation(BattlePlayer battlePlayer) {

public List<FBStructure> getAvailableStructures() {
List<FBStructure> availableStructures = new ArrayList<>();
boolean excludeEndStructures = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_END);

List<String> structuresToExclude = ForceBattle.get().getConfig().getStringList("exclude.structures");

for (FBStructure structure : FBStructure.values()) {
if (structuresToExclude.contains(structure.getKey())) {
continue;
}
if (structuresToExclude.contains(structure.getKey())) continue;
if (excludeEndStructures && ENDSTRUCTURES.contains(structure)) continue;

availableStructures.add(structure);
}
return availableStructures;
}

public List<StructureSimplified> getAvailableStructuresSimplified() {
List<StructureSimplified> list = new ArrayList<>(Arrays.asList(StructureSimplified.values()));
List<StructureSimplified> availableStructures = new ArrayList<>();
boolean excludeEndStructures = SettingsManager.isEnabled(SettingsManager.Setting.EXCLUDE_END);

List<String> structuresToExclude = ForceBattle.get().getConfig().getStringList("exclude.structures");
list.removeIf(s -> structuresToExclude.contains(s.name().toUpperCase(Locale.ROOT)));
return list;

for (StructureSimplified simplified : StructureSimplified.values()) {
if (structuresToExclude.contains(simplified.name().toUpperCase(Locale.ROOT))) continue;
if (excludeEndStructures && ENDSTRUCTURESSIMPLIFIED.contains(simplified)) continue;

availableStructures.add(simplified);
}
return availableStructures;
}

public List<String> getChainList() {
Expand Down Expand Up @@ -333,4 +348,19 @@ public void updateChainList() {
Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.WHITE_SHULKER_BOX,
Material.YELLOW_SHULKER_BOX, Material.SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE
);
private final List<EntityType> ENDMOBS = List.of(
EntityType.ENDER_DRAGON, EntityType.SHULKER, EntityType.SHULKER_BULLET, EntityType.DRAGON_FIREBALL
);
private final List<Biome> ENDBIOMES = List.of(
Biome.THE_END, Biome.END_BARRENS, Biome.END_HIGHLANDS, Biome.END_MIDLANDS, Biome.SMALL_END_ISLANDS
);
private final List<BiomeSimplified> ENDBIOMESSIMPLIFIED = List.of(
BiomeSimplified.END
);
private final List<FBStructure> ENDSTRUCTURES = List.of(
FBStructure.END_CITY
);
private final List<StructureSimplified> ENDSTRUCTURESSIMPLIFIED = List.of(
StructureSimplified.END_CITY
);
}
Loading
Loading