Compare commits

..

No commits in common. "fa8d320da9a52998277f4bd4008ee174ec1280d1" and "a10607092b98625805780fee582add851d8c8af8" have entirely different histories.

20 changed files with 72 additions and 39 deletions

View File

@ -38,6 +38,7 @@ import java.util.stream.Collectors;
public class Main extends JavaPlugin {
private GameManager gameManager = null;
private Flag flag;
@Override
public void onEnable() {
@ -52,7 +53,7 @@ public class Main extends JavaPlugin {
this.gameManager = new GameManager(worldBorderApi);
registerTeams(); //Skipped in reloadConfig if gameManager is not created yet
loadPlayerStats(); //Skipped in reloadConfig if gameManager is not created yet
Flag flag = new Flag(this, gameManager);
flag = new Flag(this, gameManager);
new CommandManager(this, gameManager, flag, worldBorderApi);
//Ensuring immediate respawn is on in all worlds
enableImmediateRespawn();
@ -162,4 +163,4 @@ public class Main extends JavaPlugin {
scheduledExecutorService.scheduleAtFixedRate(runnable, 0, 1, java.util.concurrent.TimeUnit.MINUTES);
}
}
}

View File

@ -3,10 +3,16 @@ package com.alttd.ctf.commands.subcommands;
import com.alttd.ctf.commands.SubCommand;
import com.alttd.ctf.config.Messages;
import com.alttd.ctf.game.GameManager;
import com.alttd.ctf.team.Team;
import lombok.AllArgsConstructor;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.Optional;
@AllArgsConstructor
public class SkipPhase extends SubCommand {

View File

@ -4,6 +4,7 @@ import com.alttd.ctf.Main;
import com.alttd.ctf.game.GamePhase;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;

View File

@ -195,7 +195,7 @@ public class Flag implements Runnable {
});
}
private final LinkedList<Location> particleTrail = new LinkedList<>();
LinkedList<Location> particleTrail = new LinkedList<>();
private void spawnTrail() {
TeamColor color = winningTeam.getColor();
@ -324,13 +324,12 @@ public class Flag implements Runnable {
}
Team winningTeam = teamLongEntry.getKey();
teamFlagPointCount.putIfAbsent(winningTeam.getId(), 0);
teamFlagPointCount.entrySet().forEach(entry -> {
if (entry.getKey().equals(winningTeam.getId())) {
entry.setValue(entry.getValue() + 1);
} else {
entry.setValue(Math.max(0, entry.getValue() - 1));
}
teamCounts.forEach((team, count) -> {
teamFlagPointCount.merge(team.getId(), team.equals(winningTeam) ? 1 : -1, (oldValue, delta) -> {
int updatedValue = oldValue + delta;
log.debug("Set count to {} for team {}", updatedValue, team.getId());
return Math.max(updatedValue, 0);
});
});
nearbyPlayers.forEach(teamPlayer -> teamPlayer.increaseStat(Stat.TIME_SPEND_CAPTURING_FLAG));
return true;

View File

@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import java.util.Optional;

View File

@ -15,6 +15,7 @@ import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
@Slf4j
@ -75,6 +76,7 @@ public class RunningGame implements Runnable {
private void broadcastNextPhaseStartTime(GamePhase currentPhase, GamePhase nextPhase) {
//Remaining time for this phase
Duration duration = phaseDurations.get(currentPhase).minus(Duration.between(phaseStartTime, Instant.now()));
log.debug(duration.toString());//TODO remove debug
if ((duration.toMinutes() > 1 && (duration.toMinutes() % 15 == 0 || duration.toMinutes() <= 5)) && duration.toSecondsPart() < 2) {
if (lastMinuteBroadcast == duration.toMinutes()) {
return;

View File

@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@Slf4j

View File

@ -71,17 +71,18 @@ public class EndedPhase implements GamePhaseExecutor {
return messages;
} else if (topTeams.size() > 1) { // Draw scenario, multiple teams have the same top score
messages.add(miniMessage.deserialize("<yellow>It's a draw! Top teams:</yellow>"));
topTeams.forEach(team -> messages.add(
miniMessage.deserialize("<team> had <score> captures.",
Placeholder.component("team", team.getName()),
Placeholder.parsed("score", String.valueOf(highestScore)))));
topTeams.forEach(team -> {
messages.add(miniMessage.deserialize("<team> had <score> captures.",
Placeholder.component("team", team.getName()),
Placeholder.parsed("score", String.valueOf(highestScore))));
});
addOtherTeamsScore(wins, highestScore, messages);
return messages;
} else { // Single winner
Team winner = topTeams.getFirst();
messages.add(miniMessage.deserialize("<green><team> has won with <score> captures!</green>",
Placeholder.component("team", winner.getName()),
Placeholder.parsed("score", String.valueOf(highestScore))));
Placeholder.component("team", winner.getName()),
Placeholder.parsed("score", String.valueOf(highestScore))));
if (wins.size() <= 1) {
return messages;
}
@ -96,8 +97,8 @@ public class EndedPhase implements GamePhaseExecutor {
wins.entrySet().stream()
.filter(entry -> entry.getValue() < winningScore)
.forEach(entry -> messages.add(miniMessage.deserialize("<yellow><team> had <score> captures.</yellow>",
Placeholder.component("team", entry.getKey().getName()),
Placeholder.parsed("score", String.valueOf(entry.getValue())))));
Placeholder.component("team", entry.getKey().getName()),
Placeholder.parsed("score", String.valueOf(entry.getValue())))));
}
@Override

View File

@ -36,13 +36,14 @@ public class GatheringPhase implements GamePhaseExecutor {
log.error("Unable to update world border due to missing Flag");
return;
}
gameManager.getTeams()
.forEach(team -> team.getPlayers().forEach(teamPlayer -> {
Player player = Bukkit.getPlayer(teamPlayer.getUuid());
if (player == null || !player.isOnline()) {
return;
}
teamPlayer.resetWorldBorder(player, worldBorderApi, nextPhase, flag.getFlagLocation());
}));
gameManager.getTeams().forEach(team -> {
team.getPlayers().forEach(teamPlayer -> {
Player player = Bukkit.getPlayer(teamPlayer.getUuid());
if (player == null || !player.isOnline()) {
return;
}
teamPlayer.resetWorldBorder(player, worldBorderApi, nextPhase, flag.getFlagLocation());
});
});
}
}

View File

@ -25,6 +25,8 @@ import java.util.List;
@Slf4j
public abstract class GameClass {
//TODO simple class that does powedered snow
//TODO mage uses up more snowballs shot gun style immediately spawn them when thrown 5 sec or so cooldown? mayb 3
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
private final List<Material> armor;

View File

@ -12,7 +12,9 @@ public class GameClassRetrieval {
public static HashMap<Integer, List<GameClass>> getGameClassesForAllTeams(GameManager gameManager) {
final HashMap<Integer, List<GameClass>> gameClasses = new HashMap<>();
gameManager.getTeams().forEach(team -> gameClasses.put(team.getId(), getGameClassesForTeam(team)));
gameManager.getTeams().forEach(team -> {
gameClasses.put(team.getId(), getGameClassesForTeam(team));
});
return gameClasses;
}

View File

@ -2,6 +2,7 @@ package com.alttd.ctf.game_class.creation;
import com.alttd.ctf.game_class.GameClass;
import com.alttd.ctf.game_class.implementations.Engineer;
import com.alttd.ctf.game_class.implementations.Fighter;
import com.alttd.ctf.team.TeamColor;
import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.minimessage.MiniMessage;

View File

@ -1,6 +1,7 @@
package com.alttd.ctf.game_class.creation;
import com.alttd.ctf.game_class.GameClass;
import com.alttd.ctf.game_class.implementations.Fighter;
import com.alttd.ctf.game_class.implementations.Mage;
import com.alttd.ctf.team.TeamColor;
import lombok.extern.slf4j.Slf4j;
@ -9,6 +10,8 @@ import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionType;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;

View File

@ -1,6 +1,7 @@
package com.alttd.ctf.game_class.creation;
import com.alttd.ctf.game_class.GameClass;
import com.alttd.ctf.game_class.implementations.Fighter;
import com.alttd.ctf.game_class.implementations.Tank;
import com.alttd.ctf.team.TeamColor;
import lombok.extern.slf4j.Slf4j;
@ -21,7 +22,7 @@ public class TankCreator {
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
@Contract("_ -> new")
public static @NotNull GameClass createTank(@NotNull TeamColor teamColor) {
public static @NotNull GameClass createTank(@NotNull TeamColor teamColor) {//TODO add ability to become temp invulnerable (with some particle effects mayb?)
return new Tank(getArmor(), getTools(teamColor), getDisplayItem(teamColor),
30, 7, 4);
}

View File

@ -14,6 +14,7 @@ import org.jetbrains.annotations.Unmodifiable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
@Slf4j
public class TrapperCreator {

View File

@ -1,9 +1,11 @@
package com.alttd.ctf.game_class.implementations;
import com.alttd.ctf.game_class.GameClass;
import com.alttd.ctf.team.TeamColor;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.List;

View File

@ -2,6 +2,8 @@ package com.alttd.ctf.gui;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.MerchantInventory;
import java.util.HashMap;
import java.util.UUID;

View File

@ -56,7 +56,9 @@ public class DiscordTeam {
}
Member nullableMember = guild.getMemberById(player.getDiscordID());
if (nullableMember == null) {
guild.retrieveMemberById(player.getDiscordID()).queue(member -> consumer.apply(role, member));
guild.retrieveMemberById(player.getDiscordID()).queue(member -> {
consumer.apply(role, member);
});
} else {
consumer.apply(role, nullableMember);
}
@ -81,7 +83,9 @@ public class DiscordTeam {
gameManager.getTeams().forEach(otherTeam ->
member.getRoles().stream()
.filter(otherRole -> otherRole.getIdLong() == otherTeam.getDiscordRole())
.forEach(otherRole -> member.getGuild().removeRoleFromMember(member, otherRole).queue()));
.forEach(otherRole -> {
member.getGuild().removeRoleFromMember(member, otherRole).queue();
}));
member.getGuild().addRoleToMember(member, role).queue(ignored -> kickFromVoiceIfNeeded(member));
});
}

View File

@ -2,6 +2,8 @@ package com.alttd.ctf.team;
import com.alttd.ctf.game.GameManager;
import com.alttd.ctf.game.GamePhase;
import io.papermc.paper.scoreboard.numbers.NumberFormat;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.*;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
@ -42,17 +44,17 @@ public class TeamScoreboard {
}
protected void setScore(int newScore) {
Objective objective = getOrCreateObjective();
Objective objective = getOrCreateObjective("teamScores", "<gold>CTF score</gold>");
Score score = objective.getScore(team.getLegacyTeamColor() +
PlainTextComponentSerializer.plainText().serialize(team.getName()));
score.setScore(newScore);
}
private static Objective getOrCreateObjective() {
Objective objective = scoreboard.getObjective("teamScores");
private static Objective getOrCreateObjective(String internalName, String displayName) {
Objective objective = scoreboard.getObjective(internalName);
if (objective == null) {
objective = scoreboard.registerNewObjective("teamScores", Criteria.DUMMY,
MiniMessage.miniMessage().deserialize("<gold>CTF score</gold>"));
objective = scoreboard.registerNewObjective(internalName, Criteria.DUMMY,
MiniMessage.miniMessage().deserialize(displayName));
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
return objective;
@ -62,11 +64,11 @@ public class TeamScoreboard {
private static PhaseScore phaseScore = null;
private static void updateTime(GamePhase gamePhase, Duration duration) {
if (phaseScore == null) {
phaseScore = new PhaseScore(gamePhase, getOrCreateObjective()
phaseScore = new PhaseScore(gamePhase, getOrCreateObjective("teamScores", "<gold>CTF score</gold>")
.getScore(ChatColor.GREEN + PlainTextComponentSerializer.plainText().serialize(gamePhase.getDisplayName())));
} else if (phaseScore.gamePhase() != gamePhase) {
phaseScore.score.resetScore();
phaseScore = new PhaseScore(gamePhase, getOrCreateObjective()
phaseScore = new PhaseScore(gamePhase, getOrCreateObjective("teamScores", "<gold>CTF score</gold>")
.getScore(ChatColor.GREEN + PlainTextComponentSerializer.plainText().serialize(gamePhase.getDisplayName())));
}
phaseScore.score.setScore(duration.toMinutesPart() == 0 ? duration.toSecondsPart() : duration.toMinutesPart());

View File

@ -1,3 +1,3 @@
#Sat Mar 01 01:12:24 CET 2025
buildNumber=95
#Sat Mar 01 00:39:55 CET 2025
buildNumber=91
version=0.1