"Quickly" add lostground and a few specific workarounds to creativefly.

Later the ordinary envelope should be checked by survivalfly, possibly
adding exceptions for specific side conditions, e.g. elytra is worn.

Could lead to unifying cf + sf some day, rather using different kind of
sub-check methods, depending on side conditions (flying, allow flying,
elytra, ...).
This commit is contained in:
asofold 2016-03-21 18:13:25 +01:00
parent 206c985a08
commit 336b518082
10 changed files with 143 additions and 44 deletions

View File

@ -13,9 +13,12 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.checks.moving.magic.LostGround;
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
import fr.neatmonster.nocheatplus.checks.moving.model.ModelFlying;
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
@ -67,9 +70,26 @@ public class CreativeFly extends Check {
final double hDistance = thisMove.hDistance;
final boolean flying = gameMode == BridgeMisc.GAME_MODE_SPECTATOR || player.isFlying();
final boolean sprinting = time <= data.timeSprinting + cc.sprintingGrace;
// Lost ground, if set so.
if (model.ground) {
MovingUtil.prepareFullCheck(from, to, thisMove, Math.max(cc.yOnGround, cc.noFallyOnGround));
if (!thisMove.from.onGroundOrResetCond) {
if (from.isSamePos(to)) {
if (lastMove.toIsValid && lastMove.hDistance > 0.0 && lastMove.yDistance < -0.3 // Copy and paste from sf.
&& LostGround.lostGroundStill(player, from, to, hDistance, yDistance, sprinting, lastMove, data, cc, tags)) {
// Nothing to do.
}
}
else if (LostGround.lostGround(player, from, to, hDistance, yDistance, sprinting, lastMove, data, cc, tags)) {
// Nothing to do.
}
}
}
// Horizontal distance check.
double[] resH = hDist(player, from, to, hDistance, yDistance, flying, lastMove, time, model, data, cc);
double[] resH = hDist(player, from, to, hDistance, yDistance, sprinting, flying, lastMove, time, model, data, cc);
double limitH = resH[0];
double resultH = resH[1];
@ -104,7 +124,7 @@ public class CreativeFly extends Check {
// Distinguish checking method by y-direction of the move.
if (yDistance > 0.0) {
// Ascend.
double[] res = vDistAscend(from, to, yDistance, flying, lastMove, model, data, cc);
double[] res = vDistAscend(from, to, yDistance, flying, thisMove, lastMove, model, data, cc);
resultV = Math.max(resultV, res[1]);
limitV = res[0];
}
@ -189,11 +209,22 @@ public class CreativeFly extends Check {
debug(player, "Maximum height exceeded by set-back, correct to: " + setBack.getY());
}
}
data.sfJumpPhase = 0;
return setBack;
}
else {
// Adjust the set-back and other last distances.
data.setSetBack(to);
// Adjust jump phase.
if (!thisMove.from.onGroundOrResetCond && !thisMove.to.onGroundOrResetCond) {
data.sfJumpPhase ++;
}
else if (thisMove.touchedGround && !thisMove.to.onGroundOrResetCond) {
data.sfJumpPhase = 1;
}
else {
data.sfJumpPhase = 0;
}
return null;
}
}
@ -213,9 +244,8 @@ public class CreativeFly extends Check {
* @param cc
* @return limitH, resultH (not normalized).
*/
private double[] hDist(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean flying, final MoveData lastMove, final long time, final ModelFlying model, final MovingData data, final MovingConfig cc) {
private double[] hDist(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final boolean flying, final MoveData lastMove, final long time, final ModelFlying model, final MovingData data, final MovingConfig cc) {
// Modifiers.
final boolean sprinting = time <= data.timeSprinting + cc.sprintingGrace;
double fSpeed;
// TODO: Make this configurable ! [Speed effect should not affect flying if not on ground.]
@ -290,7 +320,7 @@ public class CreativeFly extends Check {
* @param cc
* @return limitV, resultV (not normalized).
*/
private double[] vDistAscend(final PlayerLocation from, final PlayerLocation to, final double yDistance, final boolean flying, final MoveData lastMove, final ModelFlying model, final MovingData data, final MovingConfig cc) {
private double[] vDistAscend(final PlayerLocation from, final PlayerLocation to, final double yDistance, final boolean flying, final MoveData thisMove, final MoveData lastMove, final ModelFlying model, final MovingData data, final MovingConfig cc) {
double limitV = model.vModAscendSpeed / 100.0 * ModelFlying.VERTICAL_ASCEND_SPEED; // * data.jumpAmplifier;
double resultV = 0.0;
if (model.applyModifiers && flying && yDistance > 0.0) {
@ -298,31 +328,58 @@ public class CreativeFly extends Check {
limitV *= data.flySpeed / 0.1;
}
if (model.gravity && lastMove.toIsValid && yDistance > limitV) { // TODO: gravity/friction?
// (Disregard gravity.)
// TODO: Use last friction (as well)?
double frictionDist = lastMove.yDistance * Magic.FRICTION_MEDIUM_AIR;
if (!flying) {
frictionDist -= Magic.GRAVITY_MIN;
if (model.gravity) {
// Friction with gravity.
if (model.gravity && lastMove.toIsValid && yDistance > limitV) { // TODO: gravity/friction?
// (Disregard gravity.)
// TODO: Use last friction (as well)?
double frictionDist = lastMove.yDistance * Magic.FRICTION_MEDIUM_AIR;
if (!flying) {
frictionDist -= Magic.GRAVITY_MIN;
}
if (frictionDist > limitV) {
limitV = frictionDist;
tags.add("vfrict_g");
}
}
if (frictionDist > limitV) {
limitV = frictionDist;
tags.add("vfrict_g");
}
if (model.ground) {
// Jump lift off gain.
// NOTE: This assumes SurvivalFly busies about moves with from.onGroundOrResetCond.
if (yDistance > limitV && !thisMove.to.onGroundOrResetCond && !thisMove.from.onGroundOrResetCond && (
// Last move touched ground.
lastMove.toIsValid && lastMove.touchedGround &&
(lastMove.yDistance <= 0.0 || lastMove.to.extraPropertiesValid && lastMove.to.onGround)
// This move touched ground by a workaround.
|| thisMove.touchedGroundWorkaround
)) {
// Allow normal jumping.
final double maxGain = LiftOffEnvelope.NORMAL.getMaxJumpGain(data.jumpAmplifier);
if (maxGain > limitV) {
limitV = maxGain;
tags.add("jump_gain");
}
}
}
// Ordinary step up.
// TODO: Might be within a 'if (model.ground)' block?
// TODO: sfStepHeight should be a common modeling parameter?
if (yDistance > limitV && yDistance <= cc.sfStepHeight
&& (lastMove.toIsValid && lastMove.yDistance < 0.0 || from.isOnGroundOrResetCond() || thisMove.touchedGroundWorkaround)
&& to.isOnGround()) {
// (Jump effect not checked yet.)
limitV = cc.sfStepHeight;
tags.add("step_up");
}
// Determine violation amount.
resultV = Math.max(0.0, yDistance - limitV);
// Post-violation recovery.
// Ordinary step up. TODO: sfStepHeight should be a common modeling parameter?
if (yDistance <= cc.sfStepHeight
&& (lastMove.toIsValid && lastMove.yDistance < 0.0 || from.isOnGroundOrResetCond())
&& to.isOnGround()) {
// (Jump effect not checked yet.)
resultV = 0.0;
tags.add("step_up");
}
return new double[] {limitV, resultV};
}
@ -383,6 +440,8 @@ public class CreativeFly extends Check {
builder.append(" , tags: ");
builder.append(StringUtil.join(tags, "+"));
}
builder.append(" , jumpphase: " + data.sfJumpPhase);
data.thisMove.addExtraProperties(builder, " , ");
debug(player, builder.toString());
}

View File

@ -661,23 +661,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
if (checkSf) {
// SurvivalFly
// Collect block flags.
// Prepare from, to, thisMove for full checking.
// TODO: Could further differentiate if really needed to (newTo / NoFall).
final double maxYNoFall = Math.max(cc.noFallyOnGround, cc.yOnGround);
pFrom.collectBlockFlags(maxYNoFall);
final boolean isSamePos = pFrom.isSamePos(pTo);
if (isSamePos) {
// TODO: Could consider pTo = pFrom, set pitch / yaw elsewhere.
// Sets all properties, but only once.
pTo.prepare(pFrom);
}
else {
// Might collect block flags for small distances with the containing bounds for both.
pTo.collectBlockFlags(maxYNoFall);
}
// Set basic properties for past move bookkeeping.
data.thisMove.setExtraProperties(pFrom, pTo);
MovingUtil.prepareFullCheck(pFrom, pTo, data.thisMove, Math.max(cc.noFallyOnGround, cc.yOnGround));
// Hack: Add velocity for transitions between creativefly and survivalfly.
if (lastMove.toIsValid && lastMove.flyCheck == CheckType.MOVING_CREATIVEFLY) {
@ -687,7 +673,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// Actual check.
if (newTo == null) {
// Only check if passable has not already set back.
newTo = survivalFly.check(player, pFrom, pTo, isSamePos, mightBeMultipleMoves, data, cc, time);
newTo = survivalFly.check(player, pFrom, pTo, mightBeMultipleMoves, data, cc, time);
}
// Only check NoFall, if not already vetoed.
if (checkNf) {

View File

@ -87,10 +87,11 @@ public class SurvivalFly extends Check {
* @param isSamePos
* @return the location
*/
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final boolean isSamePos, final boolean mightBeMultipleMoves, final MovingData data, final MovingConfig cc, final long now) {
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final boolean mightBeMultipleMoves, final MovingData data, final MovingConfig cc, final long now) {
tags.clear();
final MoveData thisMove = data.thisMove;
final MoveData lastMove = data.moveData.getFirst();
final boolean isSamePos = from.isSamePos(to);
// Calculate some distances.
final double xDistance, yDistance, zDistance, hDistance;

View File

@ -233,7 +233,7 @@ public class Magic {
* @param thisMove
* @return
*/
static boolean excludeStaticSpeed(final MoveData thisMove) {
public static boolean excludeStaticSpeed(final MoveData thisMove) {
return !thisMove.from.inWeb && !thisMove.to.inWeb
&& !thisMove.from.onClimbable && !thisMove.to.onClimbable;
}

View File

@ -121,4 +121,16 @@ public class LocationData {
onGroundOrResetCond = false;
}
public void addExtraProperties(final StringBuilder builder) {
if (!extraPropertiesValid) {
return;
}
if (onGround) {
builder.append(" ground");
}
if (resetCond) {
builder.append(" resetcond");
}
}
}

View File

@ -33,8 +33,11 @@ public class ModelFlying {
public final boolean applyModifiers;
/** Allow falling with gravity, including friction. */
public final boolean gravity;
/** Default ground moving mechanics (jump, lost ground). */
public final boolean ground;
public ModelFlying(String id, double hModSpeed, double hModSprint, double vModAscendSpeed, double maxHeight, boolean applyModifiers, boolean gravity) {
public ModelFlying(String id, double hModSpeed, double hModSprint, double vModAscendSpeed, double maxHeight,
boolean applyModifiers, boolean gravity, final boolean ground) {
// TODO: vertical ascend/descend, limit gain a/d/v, limit abs. distance a/d/v
// TODO: possibly other friction based envelope constraints.
// TODO: Check if needed: use fly/walk speed.
@ -45,6 +48,7 @@ public class ModelFlying {
this.maxHeight = maxHeight;
this.applyModifiers = applyModifiers;
this.gravity = gravity;
this.ground = ground;
}
public ModelFlying(String id, ConfigurationSection config, String prefix, ModelFlying defaults) {
@ -56,12 +60,13 @@ public class ModelFlying {
config.getDouble(prefix + ConfPaths.SUB_VERTICAL_ASCEND_SPEED, defaults.vModAscendSpeed),
config.getDouble(prefix + ConfPaths.SUB_VERTICAL_MAXHEIGHT, defaults.maxHeight),
config.getBoolean(prefix + ConfPaths.SUB_MODIFIERS, defaults.applyModifiers),
config.getBoolean(prefix + ConfPaths.SUB_VERTICAL_GRAVITY, defaults.gravity)
config.getBoolean(prefix + ConfPaths.SUB_VERTICAL_GRAVITY, defaults.gravity),
config.getBoolean(prefix + ConfPaths.SUB_GROUND, defaults.ground)
);
}
public ModelFlying() {
this(null, 100.0, 1.92, 100.0, 128, true, true);
this(null, 100.0, 1.92, 100.0, 128, true, true, false);
}
}

View File

@ -244,4 +244,21 @@ public class MoveData {
to.extraPropertiesValid = false;
}
public void addExtraProperties(final StringBuilder builder, final String prefix) {
if (from.extraPropertiesValid && from.onGroundOrResetCond) {
if (prefix != null && !prefix.isEmpty()) {
builder.append(prefix);
}
builder.append("from/x: ");
from.addExtraProperties(builder);
}
if (to.extraPropertiesValid && to.onGroundOrResetCond) {
if (prefix != null && !prefix.isEmpty()) {
builder.append(prefix);
}
builder.append(" to/x: ");
to.addExtraProperties(builder);
}
}
}

View File

@ -252,4 +252,21 @@ public class MovingUtil {
}
}
public static void prepareFullCheck(final PlayerLocation from, final PlayerLocation to, final MoveData thisMove, final double yOnGround) {
// Collect block flags.
from.collectBlockFlags(yOnGround);
if (from.isSamePos(to)) {
// TODO: Could consider pTo = pFrom, set pitch / yaw elsewhere.
// Sets all properties, but only once.
to.prepare(from);
}
else {
// Might collect block flags for small distances with the containing bounds for both.
to.collectBlockFlags(yOnGround);
}
// Set basic properties for past move bookkeeping.
thisMove.setExtraProperties(from, to);
}
}

View File

@ -20,6 +20,7 @@ public abstract class ConfPaths {
public static final String SUB_DEBUG = "debug";
public static final String SUB_DESCEND = "descend";
public static final String SUB_GRAVITY = "gravity";
public static final String SUB_GROUND = "ground";
public static final String SUB_HORIZONTAL = "horizontal";
public static final String SUB_HORIZONTALSPEED = "horizontalspeed"; // Phase out.
public static final String SUB_IGNOREPASSABLE = "ignorepassable";

View File

@ -375,6 +375,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.MOVING_CREATIVEFLY_MODEL + "elytra." + ConfPaths.SUB_VERTICAL_ASCEND_SPEED, 0);
set(ConfPaths.MOVING_CREATIVEFLY_MODEL + "elytra." + ConfPaths.SUB_VERTICAL_MAXHEIGHT, 8);
set(ConfPaths.MOVING_CREATIVEFLY_MODEL + "elytra." + ConfPaths.SUB_MODIFIERS, false);
set(ConfPaths.MOVING_CREATIVEFLY_MODEL + "elytra." + ConfPaths.SUB_GROUND, true);
}
set(ConfPaths.MOVING_CREATIVEFLY_ACTIONS,
"log:flyshort:3:5:f cancel vl>100 log:flyshort:0:5:if cancel vl>400 log:flylong:0:5:cif cancel");