Skip to content
Open
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
2 changes: 2 additions & 0 deletions src/main/java/org/battleplugins/arena/ctf/ArenaCtf.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.battleplugins.arena.ctf.arena.CtfArena;
import org.battleplugins.arena.ctf.event.ArenaFlagCaptureEvent;
import org.battleplugins.arena.ctf.event.ArenaFlagReturnEvent;
import org.battleplugins.arena.ctf.event.ArenaFlagTakeEvent;
import org.battleplugins.arena.event.ArenaEventType;
import org.battleplugins.arena.event.action.EventActionType;
import org.battleplugins.arena.stat.ArenaStat;
Expand All @@ -29,6 +30,7 @@ public class ArenaCtf extends JavaPlugin {

public static final ArenaEventType<ArenaFlagCaptureEvent> FLAG_CAPTURE_EVENT = ArenaEventType.create("on-flag-capture", ArenaFlagCaptureEvent.class);
public static final ArenaEventType<ArenaFlagReturnEvent> FLAG_RETURN_EVENT = ArenaEventType.create("on-flag-return", ArenaFlagReturnEvent.class);
public static final ArenaEventType<ArenaFlagTakeEvent> FLAG_TAKE_EVENT = ArenaEventType.create("on-flag-take", ArenaFlagTakeEvent.class);

private static ArenaCtf instance;

Expand Down
66 changes: 53 additions & 13 deletions src/main/java/org/battleplugins/arena/ctf/arena/CtfCompetition.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.battleplugins.arena.ctf.CtfUtil;
import org.battleplugins.arena.ctf.event.ArenaFlagCaptureEvent;
import org.battleplugins.arena.ctf.event.ArenaFlagReturnEvent;
import org.battleplugins.arena.ctf.event.ArenaFlagTakeEvent;
import org.battleplugins.arena.messages.Message;
import org.battleplugins.arena.team.ArenaTeam;
import org.battleplugins.arena.util.ItemColor;
Expand All @@ -27,6 +28,7 @@
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -128,8 +130,15 @@ public void tickFlags() {
continue;
}

if (!flag.placed) {
continue;
}

boolean alreadyCapturing = this.isFlagBeingCaptured(flag);
this.capturingFlags.put(arenaPlayer, new CaptureInfo(flag, System.currentTimeMillis()));
this.broadcast(CtfMessages.FLAG_BEING_TAKEN, flag.team.getFormattedName(), Component.text(arenaPlayer.getPlayer().getName()));
if (!alreadyCapturing) {
this.broadcast(CtfMessages.FLAG_BEING_TAKEN, flag.team.getFormattedName(), Component.text(arenaPlayer.getPlayer().getName()));
}
} else if (!flag.team.equals(arenaPlayer.getTeam())) {
// No longer in capture region - cancel
this.capturingFlags.remove(arenaPlayer);
Expand All @@ -138,19 +147,33 @@ public void tickFlags() {
}

Duration captureTime = ArenaCtf.getInstance().getMainConfig().getCaptureTime();
for (Map.Entry<ArenaPlayer, CaptureInfo> entry : this.capturingFlags.entrySet()) {
Set<ActiveFlag> flagsBeingCaptured = new HashSet<>();
for (Map.Entry<ArenaPlayer, CaptureInfo> entry : List.copyOf(this.capturingFlags.entrySet())) {
if (!entry.getValue().flag.placed) {
this.capturingFlags.remove(entry.getKey());
continue;
}

// Check if the player has been capturing the flag for the required time
if (Duration.ofMillis(System.currentTimeMillis() - entry.getValue().startTime).compareTo(captureTime) >= 0) {
this.stealFlag(entry.getKey(), entry.getValue().flag);
} else {
// Send animation
Component progressBar = CtfUtil.getProgressBar('■', entry.getValue().startTime(), captureTime);
Component component = CtfMessages.CAPTURE_PROGRESS.toComponent(progressBar);
entry.getKey().getPlayer().sendActionBar(component);
continue;
}

// Send animation
Component progressBar = CtfUtil.getProgressBar('■', entry.getValue().startTime(), captureTime);
Component component = CtfMessages.CAPTURE_PROGRESS.toComponent(progressBar);
entry.getKey().getPlayer().sendActionBar(component);

flagsBeingCaptured.add(entry.getValue().flag);
}

// Play flame particles at the flag
entry.getValue().flag.flagLocation.getWorld().spawnParticle(Particle.FLAME, entry.getValue().flag.flagLocation.toCenterLocation(), 5, 0.3, 0.75, 0.3, 0);
for (ActiveFlag flag : flagsBeingCaptured) {
if (!flag.placed) {
continue;
}

flag.flagLocation.getWorld().spawnParticle(Particle.FLAME, flag.flagLocation.toCenterLocation(), 5, 0.3, 0.75, 0.3, 0);
}

for (Map.Entry<ArenaPlayer, ActiveFlag> entry : this.capturedFlags.entrySet()) {
Expand All @@ -159,8 +182,9 @@ public void tickFlags() {
}

private void stealFlag(ArenaPlayer player, ActiveFlag flag) {
this.cancelCapturesForFlag(flag);
this.capturedFlags.put(player, flag);
this.capturingFlags.remove(player);
this.getArena().getEventManager().callEvent(new ArenaFlagTakeEvent(player));

this.broadcast(CtfMessages.FLAG_STOLEN, flag.team.getFormattedName(), Component.text(player.getPlayer().getName()));
this.broadcastSounds(player, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.BLOCK_ANVIL_PLACE, 0.0f);
Expand All @@ -172,6 +196,7 @@ private void pickUpFlag(ArenaPlayer player, ActiveFlag flag) {
flag.dropTime = -1;

this.capturedFlags.put(player, flag);
this.getArena().getEventManager().callEvent(new ArenaFlagTakeEvent(player));
this.broadcast(CtfMessages.FLAG_PICKED_UP, flag.team.getFormattedName(), Component.text(player.getPlayer().getName()));
this.broadcastSounds(player, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.ENTITY_ALLAY_DEATH, 1.0f);

Expand Down Expand Up @@ -207,6 +232,7 @@ private void captureFlag(ArenaPlayer player) {
}

private void returnFlag(ActiveFlag flag, @Nullable ArenaPlayer player) {
this.cancelCapturesForFlag(flag);
if (player != null) {
this.getArena().getEventManager().callEvent(new ArenaFlagReturnEvent(player));

Expand Down Expand Up @@ -334,8 +360,8 @@ public void dropFlag(Location location) {
}

public void updateLocation(Location location) {
int highestBlockY = location.getWorld().getHighestBlockYAt(location) + 1;
this.flagLocation = new Location(location.getWorld(), location.getX(), highestBlockY, location.getZ(), location.getYaw(), location.getPitch());
Location blockLocation = location.toBlockLocation();
this.flagLocation = new Location(location.getWorld(), blockLocation.getBlockX(), blockLocation.getBlockY(), blockLocation.getBlockZ(), location.getYaw(), location.getPitch());
}

public void playAnimation(Location location) {
Expand All @@ -358,7 +384,21 @@ public void playAnimation(Location location, int count, int step, int steps) {
}
}
}


private boolean isFlagBeingCaptured(ActiveFlag flag) {
for (CaptureInfo captureInfo : this.capturingFlags.values()) {
if (captureInfo.flag == flag) {
return true;
}
}

return false;
}

private void cancelCapturesForFlag(ActiveFlag flag) {
this.capturingFlags.entrySet().removeIf(entry -> entry.getValue().flag == flag);
}

public record CaptureInfo(ActiveFlag flag, long startTime) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.battleplugins.arena.ctf.event;

import org.battleplugins.arena.ArenaPlayer;
import org.battleplugins.arena.event.EventTrigger;
import org.battleplugins.arena.event.player.BukkitArenaPlayerEvent;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;

@EventTrigger("on-flag-take")
public class ArenaFlagTakeEvent extends BukkitArenaPlayerEvent {
private static final HandlerList HANDLERS = new HandlerList();

public ArenaFlagTakeEvent(@NotNull ArenaPlayer player) {
super(player.getArena(), player);
}

@NotNull
@Override
public HandlerList getHandlers() {
return HANDLERS;
}

public static HandlerList getHandlerList() {
return HANDLERS;
}
}