Use a common method for judging if gliding with elytra is valid.

This commit is contained in:
asofold 2017-05-06 17:30:20 +02:00
parent c59b4ac11a
commit bfaa71fa5b
3 changed files with 50 additions and 15 deletions

View File

@ -34,6 +34,7 @@ import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
import fr.neatmonster.nocheatplus.checks.moving.model.ModelFlying;
import fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod;
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
import fr.neatmonster.nocheatplus.command.CommandUtil;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
@ -432,7 +433,21 @@ public class MovingConfig extends ACheckConfig {
}
}
/**
* Fetches data and config for sub checks (potentially redundant fetching).
*
* @param player
* @param fromLocation
* @return
* @deprecated Having a from location but no config/data ...
*/
@Deprecated
public ModelFlying getModelFlying(final Player player, final PlayerLocation fromLocation) {
return getModelFlying(player, fromLocation, MovingData.getData(player), MovingConfig.getConfig(player));
}
public ModelFlying getModelFlying(final Player player, final PlayerLocation fromLocation,
final MovingData data, final MovingConfig cc) {
final GameMode gameMode = player.getGameMode();
final ModelFlying modelGameMode = flyingModelGameMode.get(gameMode);
switch(gameMode) {
@ -442,25 +457,21 @@ public class MovingConfig extends ACheckConfig {
// Specific checks.
break;
default:
// Default by game mode (spectator, yet unknown).
return modelGameMode;
}
// TODO: Short touch of water/vines (/ground?) is possible - use past moves or in-medium-count.
final boolean isGlidingWithElytra = Bridge1_9.isGlidingWithElytra(player);
final boolean isGlidingWithElytra = Bridge1_9.isGlidingWithElytra(player)
&& MovingUtil.isGlidingWithElytraValid(player, fromLocation, data, cc);
// Actual flying (ignoreAllowFlight is a legacy option for rocket boots like flying).
if (player.isFlying() || !isGlidingWithElytra && !ignoreAllowFlight && player.getAllowFlight()) {
return modelGameMode;
}
// TODO: ORDER IS RANDOM GUESSING. Is mixtures possible?
if (fromLocation.isInLiquid()) {
// TODO: INCONSISTENT. Check in medium count / past moves.
return modelGameMode;
}
if (gameMode != GameMode.CREATIVE && !Double.isInfinite(Bridge1_9.getLevitationAmplifier(player))) {
// Levitation.
if (gameMode != GameMode.CREATIVE && !Double.isInfinite(Bridge1_9.getLevitationAmplifier(player))
&& !fromLocation.isInLiquid()) {
return flyingModelLevitation;
}
if (fromLocation.isOnGroundOrResetCond()) {
// TODO: INCONSISTENT. Check in medium count / past moves.
return modelGameMode;
}
// Elytra.
if (isGlidingWithElytra) { // Defensive: don't demand isGliding.
return flyingModelElytra;
}

View File

@ -79,7 +79,7 @@ public class CreativeFly extends Check {
// Some edge data for this move.
final GameMode gameMode = player.getGameMode();
final ModelFlying model = cc.getModelFlying(player, from);
final ModelFlying model = cc.getModelFlying(player, from, data, cc);
final PlayerMoveData thisMove = data.playerMoves.getCurrentMove();
// if (!data.thisMove.from.extraPropertiesValid) {
// // TODO: Confine by model config flag or just always do [if the latter: do it in the listener]?

View File

@ -76,17 +76,41 @@ public class MovingUtil {
* @param cc
* @return
*/
public static final boolean shouldCheckSurvivalFly(final Player player, final PlayerLocation fromLocation, final MovingData data, final MovingConfig cc) {
public static final boolean shouldCheckSurvivalFly(final Player player, final PlayerLocation fromLocation,
final MovingData data, final MovingConfig cc) {
final GameMode gameMode = player.getGameMode();
/*
* TODO: Model rare to check conditions (elytra, ...) on base of one
* pre-check and a method to delegate to. Reuse method(s) with
* MovingConfig.
*/
return cc.survivalFlyCheck && gameMode != BridgeMisc.GAME_MODE_SPECTATOR
&& (cc.ignoreCreative || gameMode != GameMode.CREATIVE) && !player.isFlying()
&& (cc.ignoreAllowFlight || !player.getAllowFlight())
&& !NCPExemptionManager.isExempted(player, CheckType.MOVING_SURVIVALFLY, true)
&& (Double.isInfinite(Bridge1_9.getLevitationAmplifier(player)) || fromLocation.isInLiquid())
&& (!Bridge1_9.isGlidingWithElytra(player) || fromLocation.isOnGroundOrResetCond())
&& (!Bridge1_9.isGlidingWithElytra(player)
|| !isGlidingWithElytraValid(player, fromLocation, data, cc))
&& !player.hasPermission(Permissions.MOVING_SURVIVALFLY);
}
/**
* Prerequisite is Bridge1_9.isGlidingWithElytra(player) having returned
* true.
*
* @param player
* @param fromLocation
* @param data
* @param cc
* @return
*/
public static boolean isGlidingWithElytraValid(final Player player, final PlayerLocation fromLocation,
final MovingData data, final MovingConfig cc) {
// TODO: Extend by thisMove / past moves checking (partly a cheat detection).
// TODO: Short touch of water/vines (/ground?) is possible - use past moves or in-medium-count.
return !fromLocation.isOnGroundOrResetCond();
}
/**
* Handle an illegal move by a player, attempt to restore a valid location.
* <br>