Skip to content

Commit

Permalink
Add config for the border and the knockback, cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Rollczi committed Feb 28, 2025
1 parent 0fb26d3 commit 7bc73f3
Show file tree
Hide file tree
Showing 26 changed files with 797 additions and 361 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.eternalcode.combat.border.BorderTriggerController;
import com.eternalcode.combat.border.BorderService;
import com.eternalcode.combat.border.BorderServiceImpl;
import com.eternalcode.combat.border.particle.BorderBlockController;
import com.eternalcode.combat.border.particle.BorderParticleController;
import com.eternalcode.combat.border.animation.block.BorderBlockController;
import com.eternalcode.combat.border.animation.particle.ParticleController;
import com.eternalcode.combat.bridge.BridgeService;
import com.eternalcode.combat.fight.drop.DropKeepInventoryService;
import com.eternalcode.combat.fight.FightManager;
Expand Down Expand Up @@ -128,7 +128,7 @@ public void onEnable() {
BridgeService bridgeService = new BridgeService(this.pluginConfig, server.getPluginManager(), this.getLogger(), this);
bridgeService.init(this.fightManager, server);
this.regionProvider = bridgeService.getRegionProvider();
BorderService borderService = new BorderServiceImpl(scheduler, server, regionProvider, eventCaller, () -> 6.5);
BorderService borderService = new BorderServiceImpl(scheduler, server, regionProvider, eventCaller, pluginConfig.border);
KnockbackService knockbackService = new KnockbackService(this.pluginConfig, scheduler);

NotificationAnnouncer notificationAnnouncer = new NotificationAnnouncer(this.audienceProvider, this.pluginConfig, miniMessage);
Expand Down Expand Up @@ -159,26 +159,26 @@ public void onEnable() {
new Metrics(this, BSTATS_METRICS_ID);

Stream.of(
new PercentDropModifier(this.pluginConfig.dropSettings),
new PlayersHealthDropModifier(this.pluginConfig.dropSettings, this.logoutService)
new PercentDropModifier(this.pluginConfig.drop),
new PlayersHealthDropModifier(this.pluginConfig.drop, this.logoutService)
).forEach(this.dropService::registerModifier);


Stream.of(
new DropController(this.dropService, this.dropKeepInventoryService, this.pluginConfig.dropSettings, this.fightManager),
new DropController(this.dropService, this.dropKeepInventoryService, this.pluginConfig.drop, this.fightManager),
new FightTagController(this.fightManager, this.pluginConfig),
new LogoutController(this.fightManager, this.logoutService, notificationAnnouncer, this.pluginConfig),
new FightUnTagController(this.fightManager, this.pluginConfig, this.logoutService),
new FightActionBlockerController(this.fightManager, notificationAnnouncer, this.pluginConfig),
new FightPearlController(this.pluginConfig.pearl, notificationAnnouncer, this.fightManager, this.fightPearlService),
new UpdaterNotificationController(updaterService, this.pluginConfig, this.audienceProvider, miniMessage),
new KnockbackRegionController(notificationAnnouncer, this.regionProvider, this.fightManager, this.pluginConfig, knockbackService, server),
new KnockbackRegionController(notificationAnnouncer, this.regionProvider, this.fightManager, knockbackService, server),
new FightEffectController(this.pluginConfig.effect, this.fightEffectService, this.fightManager, this.getServer()),
new FightTagOutController(this.fightTagOutService),
new FightMessageController(this.fightManager, notificationAnnouncer, this.pluginConfig, this.getServer()),
new BorderTriggerController(borderService, fightManager, server),
new BorderParticleController(borderService, scheduler, server),
new BorderBlockController(borderService, scheduler, server)
new BorderTriggerController(borderService, pluginConfig.border, fightManager, server),
new ParticleController(borderService, pluginConfig.border.particle, scheduler, server),
new BorderBlockController(borderService, pluginConfig.border.block, scheduler, server)
).forEach(listener -> this.getServer().getPluginManager().registerEvents(listener, this));

EternalCombatProvider.initialize(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@
import java.util.Set;
import java.util.stream.Collectors;

class LazyBorderResult implements BorderResult {
class BorderLazyResult implements BorderResult {

private final List<Lazy<List<BorderPoint>>> borderPoints = new ArrayList<>();

void addLazyBorderPoints(Lazy<List<BorderPoint>> supplier) {
borderPoints.add(supplier);
}

boolean isEmpty() {
return borderPoints.isEmpty();
}

@Override
public Set<BorderPoint> collect() {
return borderPoints.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,21 @@ public Set<BorderPoint> getActiveBorder(Player player) {
}

private Optional<BorderResult> resolveBorder(Location location) {
LazyBorderResult result = new LazyBorderResult();
List<BorderTrigger> triggered = borderIndexes.getTriggered(location);

for (BorderTrigger trigger : triggered) {
result.addLazyBorderPoints(new Lazy<>(() -> this.resolveBorderPoints(trigger, location)));
if (triggered.isEmpty()) {
return Optional.empty();
}

if (result.isEmpty()) {
return Optional.empty();
BorderLazyResult result = new BorderLazyResult();
for (BorderTrigger trigger : triggered) {
result.addLazyBorderPoints(new Lazy<>(() -> this.resolveBorderPoints(trigger, location)));
}

return Optional.of(result);
}

/* this code is ugly but is fast */
private List<BorderPoint> resolveBorderPoints(BorderTrigger trigger, Location playerLocation) {
BorderPoint borderMin = trigger.min();
BorderPoint borderMax = trigger.max();
Expand All @@ -114,16 +115,15 @@ private List<BorderPoint> resolveBorderPoints(BorderTrigger trigger, Location pl

List<BorderPoint> points = new ArrayList<>();

// this code is ugly but is fast
if (borderMin.y() >= realMinY) {
if (borderMin.y() >= realMinY) { // Bottom wall
for (int currentX = realMinX; currentX <= realMaxX - 1; currentX++) {
for (int currentZ = realMinZ; currentZ <= realMaxZ - 1; currentZ++) {
addPoint(points, currentX, realMinY, currentZ, playerLocation, null);
}
}
}

if (borderMax.y() <= realMaxY) {
if (borderMax.y() <= realMaxY) { // Top wall
for (int currentX = realMinX; currentX <= realMaxX; currentX++) {
for (int currentZ = realMinZ; currentZ <= realMaxZ; currentZ++) {
BorderPoint inclusive = new BorderPoint(Math.max(realMinX, currentX - 1), realMaxY - 1, Math.max(realMinZ, currentZ - 1));
Expand All @@ -132,15 +132,15 @@ private List<BorderPoint> resolveBorderPoints(BorderTrigger trigger, Location pl
}
}

if (borderMin.x() >= realMinX) {
if (borderMin.x() >= realMinX) { // West wall (left)
for (int currentY = realMinY; currentY <= realMaxY - 1; currentY++) {
for (int currentZ = realMinZ; currentZ <= realMaxZ - 1; currentZ++) {
addPoint(points, realMinX, currentY, currentZ, playerLocation, null);
}
}
}

if (borderMax.x() <= realMaxX) {
if (borderMax.x() <= realMaxX) { // East wall (right)
for (int currentY = realMinY; currentY <= realMaxY; currentY++) {
for (int currentZ = realMinZ; currentZ <= realMaxZ; currentZ++) {
BorderPoint inclusive = new BorderPoint(realMaxX - 1, Math.max(realMinY, currentY - 1), Math.max(realMinZ, currentZ - 1));
Expand All @@ -149,15 +149,15 @@ private List<BorderPoint> resolveBorderPoints(BorderTrigger trigger, Location pl
}
}

if (borderMin.z() >= realMinZ) {
if (borderMin.z() >= realMinZ) { // North wall (front)
for (int currentX = realMinX; currentX <= realMaxX - 1; currentX++) {
for (int currentY = realMinY; currentY <= realMaxY - 1; currentY++) {
addPoint(points, currentX, currentY, realMinZ, playerLocation, null);
}
}
}

if (borderMax.z() <= realMaxZ) {
if (borderMax.z() <= realMaxZ) { // South wall (back)
for (int currentX = realMinX; currentX <= realMaxX; currentX++) {
for (int currentY = realMinY; currentY <= realMaxY; currentY++) {
BorderPoint inclusive = new BorderPoint(Math.max(realMinX, currentX - 1), Math.max(realMinY, currentY - 1), realMaxZ - 1);
Expand All @@ -176,7 +176,7 @@ private void addPoint(List<BorderPoint> points, int x, int y, int z, Location pl
}

private boolean isVisible(int x, int y, int z, Location player) {
return Math.sqrt(Math.pow(x - player.getX(), 2) + Math.pow(y - player.getY(), 2) + Math.pow(z - player.getZ(), 2)) <= this.settings.distance();
return Math.sqrt(Math.pow(x - player.getX(), 2) + Math.pow(y - player.getY(), 2) + Math.pow(z - player.getZ(), 2)) <= this.settings.distance;
}

}
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
package com.eternalcode.combat.border;

import com.eternalcode.combat.border.animation.block.BlockSettings;
import com.eternalcode.combat.border.animation.particle.ParticleSettings;
import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;
import java.time.Duration;
import org.jetbrains.annotations.ApiStatus;

public interface BorderSettings {
public class BorderSettings extends OkaeriConfig {

@ApiStatus.Internal
default Duration indexRefreshDelay() {
@Comment("# Border view distance")
public double distance = 6.5;

@Comment("# Border block animation settings")
public BlockSettings block = new BlockSettings();

@Comment("# Border particle animation settings")
public ParticleSettings particle = new ParticleSettings();

public Duration indexRefreshDelay() {
return Duration.ofSeconds(1);
}

double distance();
public int distanceRounded() {
return (int) Math.ceil(this.distance);
}

default int distanceRounded() {
return (int) Math.ceil(this.distance());
public boolean isEnabled() {
return this.block.enabled || this.particle.enabled;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,23 @@
public class BorderTriggerController implements Listener {

private final BorderService borderService;
private final BorderSettings border;
private final FightManager fightManager;
private final Server server;

public BorderTriggerController(BorderService borderService, FightManager fightManager, Server server) {
public BorderTriggerController(BorderService borderService, BorderSettings border, FightManager fightManager, Server server) {
this.borderService = borderService;
this.border = border;
this.fightManager = fightManager;
this.server = server;
}

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
void onMove(PlayerMoveEvent event) {
if (!border.isEnabled()) {
return;
}

Location to = event.getTo();
Location from = event.getFrom();
if (to.getBlockX() == from.getBlockX() && to.getBlockY() == from.getBlockY() && to.getBlockZ() == from.getBlockZ()) {
Expand All @@ -41,6 +47,10 @@ void onMove(PlayerMoveEvent event) {

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
void onTeleport(PlayerTeleportEvent event) {
if (!border.isEnabled()) {
return;
}

Player player = event.getPlayer();
if (!fightManager.isInCombat(player.getUniqueId())) {
return;
Expand All @@ -51,6 +61,10 @@ void onTeleport(PlayerTeleportEvent event) {

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
void onFightEnd(FightUntagEvent event) {
if (!border.isEnabled()) {
return;
}

Player player = server.getPlayer(event.getPlayer());
if (player == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.eternalcode.combat.border.animation;

import java.awt.Color;

public final class BorderColorUtil {

private BorderColorUtil() {
}

public static Color xyzToRainbow(int x, int y, int z) {
float hue = (float) (((Math.sin(x * 0.05) + Math.cos(z * 0.05)) * 0.5 + 0.5) % 1.0);
float saturation = 1.0f;
float brightness = 0.8f + 0.2f * Math.max(0.0f, Math.min(1.0f, (float) y / 255));

return Color.getHSBColor(hue, saturation, brightness);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.eternalcode.combat.border.animation.block;

import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;
import java.time.Duration;

public class BlockSettings extends OkaeriConfig {

@Comment("# Enable block animation?")
public boolean enabled = true;

@Comment({
"# Block type used for rendering the border",
"# Custom: RAINBOW_GLASS, RAINBOW_WOOL, RAINBOW_TERRACOTTA, RAINBOW_CONCRETE",
"# Vanilla: https://javadocs.packetevents.com/com/github/retrooper/packetevents/protocol/world/states/type/StateTypes.html"
})
public BlockType type = BlockType.RAINBOW_GLASS;

@Comment({
"# Delay between each async animation update",
"# Lower values will decrease performance but will make the animation smoother",
"# Higher values will increase performance"
})
public Duration updateDelay = Duration.ofMillis(250);

@Comment({
"# Delay between each chunk cache update",
"# Lower values will decrease performance",
"# Higher values will increase performance but may cause overlapping existing blocks (this does not modify the world)"
})
public Duration chunkCacheDelay = Duration.ofMillis(300);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.eternalcode.combat.border.animation.block;

import com.eternalcode.combat.border.BorderPoint;
import static com.eternalcode.combat.border.animation.block.BorderBlockRainbowUtil.xyzToConcrete;
import static com.eternalcode.combat.border.animation.block.BorderBlockRainbowUtil.xyzToGlass;
import static com.eternalcode.combat.border.animation.block.BorderBlockRainbowUtil.xyzToTerracotta;
import static com.eternalcode.combat.border.animation.block.BorderBlockRainbowUtil.xyzToWool;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
import java.util.Locale;

public class BlockType {

public static final BlockType RAINBOW_GLASS = new BlockType("RAINBOW_GLASS", point -> xyzToGlass(point));
public static final BlockType RAINBOW_TERRACOTTA = new BlockType("RAINBOW_TERRACOTTA", point -> xyzToTerracotta(point));
public static final BlockType RAINBOW_WOOL = new BlockType("RAINBOW_WOOL", point -> xyzToWool(point));
public static final BlockType RAINBOW_CONCRETE = new BlockType("RAINBOW_CONCRETE", point -> xyzToConcrete(point));

private final String name;
private final TypeProvider type;

private BlockType(String name, TypeProvider type) {
this.name = name;
this.type = type;
}

public String getName() {
return name;
}

public StateType getStateType(BorderPoint point) {
return type.provide(point);
}

public static BlockType fromName(String name) {
return switch (name) {
case "RAINBOW_GLASS" -> RAINBOW_GLASS;
case "RAINBOW_WOOL" -> RAINBOW_WOOL;
case "RAINBOW_TERRACOTTA" -> RAINBOW_TERRACOTTA;
case "RAINBOW_CONCRETE" -> RAINBOW_CONCRETE;
default -> new BlockType(name, point -> StateTypes.getByName(name.toLowerCase(Locale.ROOT)));
};
}

private interface TypeProvider {
StateType provide(BorderPoint point);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.eternalcode.combat.border.animation.block;

import eu.okaeri.configs.schema.GenericsPair;
import eu.okaeri.configs.serdes.BidirectionalTransformer;
import eu.okaeri.configs.serdes.SerdesContext;
import java.util.Locale;

public class BlockTypeTransformer extends BidirectionalTransformer<String, BlockType> {

@Override
public GenericsPair<String, BlockType> getPair() {
return this.genericsPair(String.class, BlockType.class);
}

@Override
public BlockType leftToRight(String data, SerdesContext serdesContext) {
BlockType blockType = BlockType.fromName(data);
if (blockType == null) {
throw new IllegalArgumentException("Unknown block type: " + data);
}

return blockType;
}

@Override
public String rightToLeft(BlockType data, SerdesContext serdesContext) {
return data.getName().toUpperCase(Locale.ROOT);
}

}
Loading

0 comments on commit 7bc73f3

Please sign in to comment.