Skip to content

Commit 7bc73f3

Browse files
committed
Add config for the border and the knockback, cleanup
1 parent 0fb26d3 commit 7bc73f3

26 files changed

+797
-361
lines changed

eternalcombat-plugin/src/main/java/com/eternalcode/combat/CombatPlugin.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.eternalcode.combat.border.BorderTriggerController;
44
import com.eternalcode.combat.border.BorderService;
55
import com.eternalcode.combat.border.BorderServiceImpl;
6-
import com.eternalcode.combat.border.particle.BorderBlockController;
7-
import com.eternalcode.combat.border.particle.BorderParticleController;
6+
import com.eternalcode.combat.border.animation.block.BorderBlockController;
7+
import com.eternalcode.combat.border.animation.particle.ParticleController;
88
import com.eternalcode.combat.bridge.BridgeService;
99
import com.eternalcode.combat.fight.drop.DropKeepInventoryService;
1010
import com.eternalcode.combat.fight.FightManager;
@@ -128,7 +128,7 @@ public void onEnable() {
128128
BridgeService bridgeService = new BridgeService(this.pluginConfig, server.getPluginManager(), this.getLogger(), this);
129129
bridgeService.init(this.fightManager, server);
130130
this.regionProvider = bridgeService.getRegionProvider();
131-
BorderService borderService = new BorderServiceImpl(scheduler, server, regionProvider, eventCaller, () -> 6.5);
131+
BorderService borderService = new BorderServiceImpl(scheduler, server, regionProvider, eventCaller, pluginConfig.border);
132132
KnockbackService knockbackService = new KnockbackService(this.pluginConfig, scheduler);
133133

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

161161
Stream.of(
162-
new PercentDropModifier(this.pluginConfig.dropSettings),
163-
new PlayersHealthDropModifier(this.pluginConfig.dropSettings, this.logoutService)
162+
new PercentDropModifier(this.pluginConfig.drop),
163+
new PlayersHealthDropModifier(this.pluginConfig.drop, this.logoutService)
164164
).forEach(this.dropService::registerModifier);
165165

166166

167167
Stream.of(
168-
new DropController(this.dropService, this.dropKeepInventoryService, this.pluginConfig.dropSettings, this.fightManager),
168+
new DropController(this.dropService, this.dropKeepInventoryService, this.pluginConfig.drop, this.fightManager),
169169
new FightTagController(this.fightManager, this.pluginConfig),
170170
new LogoutController(this.fightManager, this.logoutService, notificationAnnouncer, this.pluginConfig),
171171
new FightUnTagController(this.fightManager, this.pluginConfig, this.logoutService),
172172
new FightActionBlockerController(this.fightManager, notificationAnnouncer, this.pluginConfig),
173173
new FightPearlController(this.pluginConfig.pearl, notificationAnnouncer, this.fightManager, this.fightPearlService),
174174
new UpdaterNotificationController(updaterService, this.pluginConfig, this.audienceProvider, miniMessage),
175-
new KnockbackRegionController(notificationAnnouncer, this.regionProvider, this.fightManager, this.pluginConfig, knockbackService, server),
175+
new KnockbackRegionController(notificationAnnouncer, this.regionProvider, this.fightManager, knockbackService, server),
176176
new FightEffectController(this.pluginConfig.effect, this.fightEffectService, this.fightManager, this.getServer()),
177177
new FightTagOutController(this.fightTagOutService),
178178
new FightMessageController(this.fightManager, notificationAnnouncer, this.pluginConfig, this.getServer()),
179-
new BorderTriggerController(borderService, fightManager, server),
180-
new BorderParticleController(borderService, scheduler, server),
181-
new BorderBlockController(borderService, scheduler, server)
179+
new BorderTriggerController(borderService, pluginConfig.border, fightManager, server),
180+
new ParticleController(borderService, pluginConfig.border.particle, scheduler, server),
181+
new BorderBlockController(borderService, pluginConfig.border.block, scheduler, server)
182182
).forEach(listener -> this.getServer().getPluginManager().registerEvents(listener, this));
183183

184184
EternalCombatProvider.initialize(this);

eternalcombat-plugin/src/main/java/com/eternalcode/combat/border/LazyBorderResult.java renamed to eternalcombat-plugin/src/main/java/com/eternalcode/combat/border/BorderLazyResult.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,14 @@
66
import java.util.Set;
77
import java.util.stream.Collectors;
88

9-
class LazyBorderResult implements BorderResult {
9+
class BorderLazyResult implements BorderResult {
1010

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

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

17-
boolean isEmpty() {
18-
return borderPoints.isEmpty();
19-
}
20-
2117
@Override
2218
public Set<BorderPoint> collect() {
2319
return borderPoints.stream()

eternalcombat-plugin/src/main/java/com/eternalcode/combat/border/BorderServiceImpl.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,21 @@ public Set<BorderPoint> getActiveBorder(Player player) {
8383
}
8484

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

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

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

9797
return Optional.of(result);
9898
}
9999

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

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

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

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

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

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

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

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

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

182182
}
Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
package com.eternalcode.combat.border;
22

3+
import com.eternalcode.combat.border.animation.block.BlockSettings;
4+
import com.eternalcode.combat.border.animation.particle.ParticleSettings;
5+
import eu.okaeri.configs.OkaeriConfig;
6+
import eu.okaeri.configs.annotation.Comment;
37
import java.time.Duration;
4-
import org.jetbrains.annotations.ApiStatus;
58

6-
public interface BorderSettings {
9+
public class BorderSettings extends OkaeriConfig {
710

8-
@ApiStatus.Internal
9-
default Duration indexRefreshDelay() {
11+
@Comment("# Border view distance")
12+
public double distance = 6.5;
13+
14+
@Comment("# Border block animation settings")
15+
public BlockSettings block = new BlockSettings();
16+
17+
@Comment("# Border particle animation settings")
18+
public ParticleSettings particle = new ParticleSettings();
19+
20+
public Duration indexRefreshDelay() {
1021
return Duration.ofSeconds(1);
1122
}
1223

13-
double distance();
24+
public int distanceRounded() {
25+
return (int) Math.ceil(this.distance);
26+
}
1427

15-
default int distanceRounded() {
16-
return (int) Math.ceil(this.distance());
28+
public boolean isEnabled() {
29+
return this.block.enabled || this.particle.enabled;
1730
}
1831

1932
}

eternalcombat-plugin/src/main/java/com/eternalcode/combat/border/BorderTriggerController.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,23 @@
1414
public class BorderTriggerController implements Listener {
1515

1616
private final BorderService borderService;
17+
private final BorderSettings border;
1718
private final FightManager fightManager;
1819
private final Server server;
1920

20-
public BorderTriggerController(BorderService borderService, FightManager fightManager, Server server) {
21+
public BorderTriggerController(BorderService borderService, BorderSettings border, FightManager fightManager, Server server) {
2122
this.borderService = borderService;
23+
this.border = border;
2224
this.fightManager = fightManager;
2325
this.server = server;
2426
}
2527

2628
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
2729
void onMove(PlayerMoveEvent event) {
30+
if (!border.isEnabled()) {
31+
return;
32+
}
33+
2834
Location to = event.getTo();
2935
Location from = event.getFrom();
3036
if (to.getBlockX() == from.getBlockX() && to.getBlockY() == from.getBlockY() && to.getBlockZ() == from.getBlockZ()) {
@@ -41,6 +47,10 @@ void onMove(PlayerMoveEvent event) {
4147

4248
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
4349
void onTeleport(PlayerTeleportEvent event) {
50+
if (!border.isEnabled()) {
51+
return;
52+
}
53+
4454
Player player = event.getPlayer();
4555
if (!fightManager.isInCombat(player.getUniqueId())) {
4656
return;
@@ -51,6 +61,10 @@ void onTeleport(PlayerTeleportEvent event) {
5161

5262
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
5363
void onFightEnd(FightUntagEvent event) {
64+
if (!border.isEnabled()) {
65+
return;
66+
}
67+
5468
Player player = server.getPlayer(event.getPlayer());
5569
if (player == null) {
5670
return;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.eternalcode.combat.border.animation;
2+
3+
import java.awt.Color;
4+
5+
public final class BorderColorUtil {
6+
7+
private BorderColorUtil() {
8+
}
9+
10+
public static Color xyzToRainbow(int x, int y, int z) {
11+
float hue = (float) (((Math.sin(x * 0.05) + Math.cos(z * 0.05)) * 0.5 + 0.5) % 1.0);
12+
float saturation = 1.0f;
13+
float brightness = 0.8f + 0.2f * Math.max(0.0f, Math.min(1.0f, (float) y / 255));
14+
15+
return Color.getHSBColor(hue, saturation, brightness);
16+
}
17+
18+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.eternalcode.combat.border.animation.block;
2+
3+
import eu.okaeri.configs.OkaeriConfig;
4+
import eu.okaeri.configs.annotation.Comment;
5+
import java.time.Duration;
6+
7+
public class BlockSettings extends OkaeriConfig {
8+
9+
@Comment("# Enable block animation?")
10+
public boolean enabled = true;
11+
12+
@Comment({
13+
"# Block type used for rendering the border",
14+
"# Custom: RAINBOW_GLASS, RAINBOW_WOOL, RAINBOW_TERRACOTTA, RAINBOW_CONCRETE",
15+
"# Vanilla: https://javadocs.packetevents.com/com/github/retrooper/packetevents/protocol/world/states/type/StateTypes.html"
16+
})
17+
public BlockType type = BlockType.RAINBOW_GLASS;
18+
19+
@Comment({
20+
"# Delay between each async animation update",
21+
"# Lower values will decrease performance but will make the animation smoother",
22+
"# Higher values will increase performance"
23+
})
24+
public Duration updateDelay = Duration.ofMillis(250);
25+
26+
@Comment({
27+
"# Delay between each chunk cache update",
28+
"# Lower values will decrease performance",
29+
"# Higher values will increase performance but may cause overlapping existing blocks (this does not modify the world)"
30+
})
31+
public Duration chunkCacheDelay = Duration.ofMillis(300);
32+
33+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.eternalcode.combat.border.animation.block;
2+
3+
import com.eternalcode.combat.border.BorderPoint;
4+
import static com.eternalcode.combat.border.animation.block.BorderBlockRainbowUtil.xyzToConcrete;
5+
import static com.eternalcode.combat.border.animation.block.BorderBlockRainbowUtil.xyzToGlass;
6+
import static com.eternalcode.combat.border.animation.block.BorderBlockRainbowUtil.xyzToTerracotta;
7+
import static com.eternalcode.combat.border.animation.block.BorderBlockRainbowUtil.xyzToWool;
8+
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
9+
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
10+
import java.util.Locale;
11+
12+
public class BlockType {
13+
14+
public static final BlockType RAINBOW_GLASS = new BlockType("RAINBOW_GLASS", point -> xyzToGlass(point));
15+
public static final BlockType RAINBOW_TERRACOTTA = new BlockType("RAINBOW_TERRACOTTA", point -> xyzToTerracotta(point));
16+
public static final BlockType RAINBOW_WOOL = new BlockType("RAINBOW_WOOL", point -> xyzToWool(point));
17+
public static final BlockType RAINBOW_CONCRETE = new BlockType("RAINBOW_CONCRETE", point -> xyzToConcrete(point));
18+
19+
private final String name;
20+
private final TypeProvider type;
21+
22+
private BlockType(String name, TypeProvider type) {
23+
this.name = name;
24+
this.type = type;
25+
}
26+
27+
public String getName() {
28+
return name;
29+
}
30+
31+
public StateType getStateType(BorderPoint point) {
32+
return type.provide(point);
33+
}
34+
35+
public static BlockType fromName(String name) {
36+
return switch (name) {
37+
case "RAINBOW_GLASS" -> RAINBOW_GLASS;
38+
case "RAINBOW_WOOL" -> RAINBOW_WOOL;
39+
case "RAINBOW_TERRACOTTA" -> RAINBOW_TERRACOTTA;
40+
case "RAINBOW_CONCRETE" -> RAINBOW_CONCRETE;
41+
default -> new BlockType(name, point -> StateTypes.getByName(name.toLowerCase(Locale.ROOT)));
42+
};
43+
}
44+
45+
private interface TypeProvider {
46+
StateType provide(BorderPoint point);
47+
}
48+
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.eternalcode.combat.border.animation.block;
2+
3+
import eu.okaeri.configs.schema.GenericsPair;
4+
import eu.okaeri.configs.serdes.BidirectionalTransformer;
5+
import eu.okaeri.configs.serdes.SerdesContext;
6+
import java.util.Locale;
7+
8+
public class BlockTypeTransformer extends BidirectionalTransformer<String, BlockType> {
9+
10+
@Override
11+
public GenericsPair<String, BlockType> getPair() {
12+
return this.genericsPair(String.class, BlockType.class);
13+
}
14+
15+
@Override
16+
public BlockType leftToRight(String data, SerdesContext serdesContext) {
17+
BlockType blockType = BlockType.fromName(data);
18+
if (blockType == null) {
19+
throw new IllegalArgumentException("Unknown block type: " + data);
20+
}
21+
22+
return blockType;
23+
}
24+
25+
@Override
26+
public String rightToLeft(BlockType data, SerdesContext serdesContext) {
27+
return data.getName().toUpperCase(Locale.ROOT);
28+
}
29+
30+
}

0 commit comments

Comments
 (0)