Initial offground synchronization commit

This commit is contained in:
Axionize committed 2024-10-26 14:40:40 -04:00
1 parent 2d98d4cbff
commit 74ee5d8c7e
7 files changed
+97 -26

No files matched your search

+2
View File
@@ -17,4 +17,6 @@ permissions:
knockbacksync.ping:
default: op
knockbacksync.reload:
default: op
knockbacksync.toggleoffground:
default: op
@@ -9,6 +9,7 @@ import me.caseload.knockbacksync.command.subcommand.PingCommand;
import me.caseload.knockbacksync.command.subcommand.ReloadCommand;
import me.caseload.knockbacksync.command.subcommand.StatusCommand;
import me.caseload.knockbacksync.command.subcommand.ToggleCommand;
import me.caseload.knockbacksync.command.subcommand.ToggleOffGroundSubcommand;
import me.caseload.knockbacksync.event.Event;
import me.caseload.knockbacksync.event.EventBus;
import me.caseload.knockbacksync.event.OptimizedEventBus;
@@ -117,6 +118,7 @@ public abstract class Base {
new ReloadCommand(),
new PingCommand(),
new StatusCommand(),
new ToggleOffGroundSubcommand(),
new ToggleCommand()
);
list.forEach(command -> command.register(commandManager));
@@ -1,7 +1,11 @@
package me.caseload.knockbacksync.command.subcommand;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.ConfigWrapper;
import me.caseload.knockbacksync.command.generic.BuilderCommand;
import me.caseload.knockbacksync.event.KBSyncEventHandler;
import me.caseload.knockbacksync.event.events.ConfigReloadEvent;
import me.caseload.knockbacksync.manager.ConfigManager;
import me.caseload.knockbacksync.sender.Sender;
import me.caseload.knockbacksync.util.ChatUtil;
import org.incendo.cloud.CommandManager;
@@ -11,7 +15,14 @@ import java.util.function.Predicate;
public class ToggleOffGroundSubcommand implements BuilderCommand {
@Override
private String enableOffGroundSyncMessage;
private String disableOffGroundSyncMessage;
private boolean offGroundSyncEnabled;
public ToggleOffGroundSubcommand() {
loadConfigSettings();
}
public void register(CommandManager<Sender> manager) {
manager.command(
manager.commandBuilder("knockbacksync", "kbsync", "kbs")
@@ -25,14 +36,24 @@ public class ToggleOffGroundSubcommand implements BuilderCommand {
return PredicatePermission.of(senderPredicate).testPermission(sender);
}))
.handler(commandContext -> {
boolean toggledState = !Base.INSTANCE.getConfigManager().getConfigWrapper().getBoolean("enable_experimental_offground", false);
Base.INSTANCE.getConfigManager().getConfigWrapper().set("enable_experimental_offground", toggledState);
boolean toggledState = !offGroundSyncEnabled;
Base.INSTANCE.getConfigManager().getConfigWrapper().set("enable_offground_synchronization", toggledState);
Base.INSTANCE.getConfigManager().saveConfig();
String message = ChatUtil.translateAlternateColorCodes('&',
toggledState ?
Base.INSTANCE.getConfigManager().getConfigWrapper().getString("enable_experimental_offground_message", "&aSuccessfully enabled offground experiment.") :
Base.INSTANCE.getConfigManager().getConfigWrapper().getString("disable_experimental_offground_message", "&cSuccessfully disabled offground experiment."));
toggledState ? enableOffGroundSyncMessage : disableOffGroundSyncMessage);
commandContext.sender().sendMessage(message);
}));
}
@KBSyncEventHandler
public void onConfigReloadEvent(ConfigReloadEvent event) {
loadConfigSettings();
}
private void loadConfigSettings() {
ConfigWrapper configWrapper = Base.INSTANCE.getConfigManager().getConfigWrapper();
offGroundSyncEnabled = configWrapper.getBoolean("enable_offground_synchronization", false);
enableOffGroundSyncMessage = configWrapper.getString("enable_offground_synchronization_message", "&aSuccessfully enabled offground experiment.");
disableOffGroundSyncMessage = configWrapper.getString("disable_offground_synchronization_message", "&cSuccessfully disabled offground experiment.");
}
}
@@ -12,21 +12,26 @@ public abstract class PlayerKnockbackListener {
if (!Base.INSTANCE.getConfigManager().isToggled())
return;
PlayerData playerData = PlayerDataManager.getPlayerData(victim.getUUID());
if (playerData == null)
PlayerData victimPlayerData = PlayerDataManager.getPlayerData(victim.getUUID());
if (victimPlayerData == null)
return;
/* Integer damageTicks = playerData.getLastDamageTicks();
if (damageTicks != null && damageTicks > 8)
return;*/
Double verticalVelocity = playerData.getVerticalVelocity();
if (verticalVelocity == null || !playerData.isOnGround(velocity.getY()))
return;
Double verticalVelocity = victimPlayerData.getVerticalVelocity();
if(verticalVelocity == null) return;
// Since we're already changing types do we need to use withY to get a new object
// Or can we just go velocity.y = verticalVelocity ?
Vector3d adjustedVelocity = velocity.withY(verticalVelocity);
victim.setVelocity(adjustedVelocity); // Use PlatformPlayer's setVelocity
if (victimPlayerData.isOnGroundClientSide(velocity.getY())) {
// Since we're already changing types do we need to use withY to get a new object
// Or can we just go velocity.y = verticalVelocity ?
Vector3d adjustedVelocity = velocity.withY(verticalVelocity);
victim.setVelocity(adjustedVelocity); // Use PlatformPlayer's setVelocity
} else if (!victim.isOnGround()) {
if(!victimPlayerData.isOffGroundSyncEnabled()) return;
Vector3d adjustedVelocity = velocity.withY(victimPlayerData.getCompensatedOffGroundVelocity());
victim.setVelocity(adjustedVelocity); // Use PlatformPlayer's setVelocity
}
}
}
@@ -19,6 +19,7 @@ import lombok.Getter;
import lombok.Setter;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.event.KBSyncEventHandler;
import me.caseload.knockbacksync.event.events.ConfigReloadEvent;
import me.caseload.knockbacksync.event.events.ToggleOnOffEvent;
import me.caseload.knockbacksync.manager.CombatManager;
import me.caseload.knockbacksync.scheduler.AbstractTaskHandle;
@@ -80,6 +81,7 @@ public class PlayerData {
@Nullable @Setter private Integer lastDamageTicks;
@Setter private double gravityAttribute = 0.08;
@Setter private double knockbackResistanceAttribute = 0.0;
private boolean offGroundSyncEnabled;
public PlayerData(PlatformPlayer platformPlayer) {
this.uuid = platformPlayer.getUUID();
@@ -100,6 +102,8 @@ public class PlayerData {
}
this.user = tempUser;
this.offGroundSyncEnabled = Base.INSTANCE.getConfigManager().getConfigWrapper().getBoolean("enable_offground_synchronization",
true);
}
/**
@@ -128,10 +132,6 @@ public class PlayerData {
return (int) Math.ceil(getCompensatedPing() * TICK_RATE / 1000); // Multiply ping by seconds per tick
}
// public boolean isKeepAliveIDOurs(long id) {
// return id == lastKeepAliveID;
// }
public void sendPing(boolean async) {
if (user == null || user.getEncoderState() != ConnectionState.PLAY) return;
@@ -187,7 +187,7 @@ public class PlayerData {
* @param verticalVelocity The Player's current vertical velocity.
* @return <code>true</code> if the Player is on the ground; <code>false</code> otherwise.
*/
public boolean isOnGround(double verticalVelocity) {
public boolean isOnGroundClientSide(double verticalVelocity) {
WrappedBlockState blockState = platformPlayer.getWorld().getBlockStateAt(platformPlayer.getLocation());
if (platformPlayer.isGliding() ||
@@ -218,6 +218,27 @@ public class PlayerData {
return (tMax + tFall) - getTick() <= 0 && gDist <= 1.3;
}
/**
* Gets whether or not offGroundSynchronization is enabled for the player.
* @return <code>true</code> if enabled; <code>false</code> otherwise.
*/
public boolean isOffGroundSyncEnabled() {
// TODO, per-player offground sync toggles?
return offGroundSyncEnabled;
}
/**
* Gets the compensated off-ground velocity.
* This is used to make knockback feel more accurate off-ground.
*
* @return Compensated Y axis velocity
*/
public double getCompensatedOffGroundVelocity() {
Double ping = getPing();
if(ping == null) return platformPlayer.getVelocity().y;
return MathUtil.getCompensatedVerticalVelocity(platformPlayer.getVelocity().y, ping);
}
/**
* Ray traces from each corner of the player's bounding box to the ground,
* returning the smallest distance, with a maximum limit of 5 blocks.
@@ -272,7 +293,6 @@ public class PlayerData {
if (!attacker.isSprinting()) {
yAxis = 0.36080000519752503;
// double knockbackResistance = knockbackResistanceAttribute;
double resistanceFactor = 0.04000000119 * knockbackResistanceAttribute * 10;
yAxis -= resistanceFactor;
}
@@ -334,4 +354,10 @@ public class PlayerData {
keepaliveMap.clear();
}
}
@KBSyncEventHandler
public void onConfigReloadEvent(ConfigReloadEvent event) {
this.offGroundSyncEnabled = Base.INSTANCE.getConfigManager().getConfigWrapper().getBoolean("enable_offground_synchronization",
true);
}
}
@@ -1,11 +1,26 @@
package me.caseload.knockbacksync.util;
import static me.caseload.knockbacksync.player.PlayerData.TICK_RATE;
public class MathUtil {
private static final double TERMINAL_VELOCITY = 3.92;
private static final double MULTIPLIER = 0.98;
private static final int MAX_TICKS = 30;
public static double getCompensatedVerticalVelocity(double verticalVelocity, double ping) {
final double gravity = 0.08;
final double multiplier = 0.98;
int ticks = (int) Math.ceil(ping * TICK_RATE / 1000);
while(ticks > 0) {
verticalVelocity -= gravity;
verticalVelocity *= multiplier;
ticks--;
}
return verticalVelocity;
}
public static double calculateDistanceTraveled(double velocity, int time, double acceleration) {
double totalDistance = 0;
+5 -5
View File
@@ -3,7 +3,7 @@
#########################################
# Do not modify!
config_version: 4
config_version: 5
# Plugin enabled state
# Toggleable using /knockbacksync toggle
@@ -38,8 +38,8 @@ spike_threshold: 20
# ping measured in ms with PING/TRANSACTION is typically within ± 5ms of actual but can be up to 50ms off
ping_strategy: "KEEPALIVE"
# This setting has yet to be implemented. Enable if you want it to be enabled as soon as the next update add support
enable_experimental_offground: false
# Whether to try to detect when player is offground and apply less kb
enable_offground_synchronization: true
enable_message: "&aSuccessfully enabled KnockbackSync."
disable_message: "&cSuccessfully disabled KnockbackSync."
@@ -50,8 +50,8 @@ reload_message: "&aSuccessfully reloaded KnockbackSync config."
global_status_message: "&eGlobal KnockbackSync status: "
player_status_message: "&e%player%'s KnockbackSync status: "
player_disabled_global_message: "&cDisabled (Global toggle is off)"
enable_experimental_offground_message: "&aSuccessfully enabled offground experiment."
disable_experimental_offground_message: "&cSuccessfully disabled offground experiment."
enable_offground_synchronization_message: "&aSuccessfully enabled offground synchronization."
disable_offground_synchronization_message: "&cSuccessfully disabled offground synchronization."
# This is the rate the server will use for (amongst other things) sending packets about entities to players
# In other words it defines how often clients get updated velocity for other entities in the world