[SAFETY COMMIT] Freeze changes to vertical velocity.

Since other fixes migth be in focus, some changes are commited
merged/commented out:
* Prepare AxisVelocity to carry positive and negative values.
* Prepare MovingData to use vertical AxisVelocity. Rename hVel.
* Prepare CreativeFly (...), do not count velocity for height limit.

(Most preparations were unfinished, just hinting at the direction.)
This commit is contained in:
asofold 2014-10-10 15:15:22 +02:00
parent 3ea098876f
commit af974a85ac
4 changed files with 100 additions and 38 deletions

View File

@ -11,12 +11,19 @@ import java.util.List;
*/
public class AxisVelocity {
/** Velocity with a smaller absolute amount is removed. */
private static final double minValue = 0.001;
private static final double frictionFactor = 0.93;
private final List<Velocity> queued = new ArrayList<Velocity>();
private final List<Velocity> active = new ArrayList<Velocity>();
public void add(Velocity vel) {
// TODO: Merging behavior?
queued.add(vel);
if (Math.abs(vel.value) != 0.0) {
queued.add(vel);
}
}
public boolean hasActive() {
@ -34,10 +41,11 @@ public class AxisVelocity {
// Decrease counts for active.
// TODO: Actual friction. Could pass as an argument (special value for not to be used).
// TODO: Consider removing already invalidated here.
// TODO: Consider working removeInvalid into this ?
for (final Velocity vel : active) {
vel.valCount --;
vel.sum += vel.value;
vel.value *= 0.93; // vel.frictionFactor;
vel.value *= frictionFactor; // vel.frictionFactor;
// (Altered entries should be kept, since they get used right away.)
}
// Decrease counts for queued.
@ -61,7 +69,7 @@ public class AxisVelocity {
final Velocity vel = it.next();
// TODO: 0.001 can be stretched somewhere else, most likely...
// TODO: Somehow use tick here too (actCount, valCount)?
if (vel.valCount <= 0 || vel.value <= 0.001) {
if (vel.valCount <= 0 || Math.abs(vel.value) <= minValue) {
// System.out.prsintln("Invalidate active: " + vel);
it.remove();
}
@ -69,6 +77,7 @@ public class AxisVelocity {
// Queued.
it = queued.iterator();
while (it.hasNext()) {
// TODO: Could check for alternating signum (error).
final Velocity vel = it.next();
if (vel.actCount <= 0 || vel.tick < tick) {
// System.out.println("Invalidate queued: " + vel);
@ -79,10 +88,10 @@ public class AxisVelocity {
/**
* Get the sum of active velocity values.
* @return
* @return Can be positive or negative.
*/
public double getFreedom() {
// TODO: model/calculate it as accurate as possible...
// TODO: model/calculate it as accurate as possible...
double f = 0;
for (final Velocity vel : active) {
f += vel.value;
@ -95,18 +104,31 @@ public class AxisVelocity {
* Amount is the horizontal distance that is to be covered by velocity (active has already been checked).
* <br>
* If the modeling changes (max instead of sum or similar), then this will be affected.
* @param amount The amount used.
* @param amount The amount used, should be negative or positive depending on direction.
* @return
*/
public double use(final double amount) {
if (!active.isEmpty()) {
// Invalidate active on "direction change" [direction of consumption].
if (amount * active.get(0).value < 0.0) {
active.clear();
}
}
final Iterator<Velocity> it = queued.iterator();
double used = 0;
while (it.hasNext()) {
final Velocity vel = it.next();
if (vel.value * amount < 0.0) {
// Not aligned.
// TODO: This could be a problem with small amounts of velocity.
// TODO: break or remove !? -> need find "next fitting one" and remove all non-fitting before (iff fitting found) ...
it.remove(); // TODO: queues ~ continue? vs. invalidate (remove) vs. break; vs. collect and invalidate non-matching BEFORE.
continue;
}
used += vel.value;
active.add(vel);
it.remove();
if (used >= amount) {
if (Math.abs(used) >= Math.abs(amount)) {
break;
}
}

View File

@ -50,9 +50,10 @@ public class CreativeFly extends Check {
// Before doing anything, do a basic height check to determine if players are flying too high.
final int maximumHeight = cc.creativeFlyMaxHeight + player.getWorld().getMaxHeight();
if (to.getY() - data.verticalFreedom > maximumHeight)
return new Location(player.getWorld(), data.getSetBackX(), maximumHeight - 10D, data.getSetBackZ(),
to.getYaw(), to.getPitch());
if (to.getY() > maximumHeight) {
// TODO: USE velocity if possible.
return new Location(player.getWorld(), data.getSetBackX(), Math.max(maximumHeight - 10D, to.getWorld().getMaxHeight()), data.getSetBackZ(), to.getYaw(), to.getPitch());
}
// Calculate some distances.
final double xDistance = to.getX() - from.getX();
@ -96,7 +97,7 @@ public class CreativeFly extends Check {
}
}
else{
data.clearActiveHVel(); // TODO: test/check !
data.clearActiveHorVel(); // TODO: test/check !
}
final boolean sprinting = time <= data.timeSprinting + cc.sprintingGrace;
@ -119,8 +120,16 @@ public class CreativeFly extends Check {
// Super simple, just check distance compared to max distance vertical.
// TODO: max descending speed ! [max fall speed, use maximum with speed or added ?]
// TODO:_ signum considerations (aligned ...).
// double vDistanceAboveLimit = yDistance - data.getVerticalFreedom() - limitV;
// if (vDistanceAboveLimit > 0.0) {
// // TODO: consume / use vvel
// }
// final double resultV = (vDistanceAboveLimit - limitV) * 100D;
// final double result = Math.max(0.0, resultH) + Math.max(0D, resultV);
// Old handling.
final double resultV = (yDistance - data.verticalFreedom - limitV) * 100D;
final double result = Math.max(0.0, resultH) + Math.max(0D, resultV);
// The player went to far, either horizontal or vertical.

View File

@ -116,12 +116,15 @@ public class MovingData extends ACheckData {
// Velocity handling.
// TODO: consider resetting these with clearFlyData and onSetBack.
/** Vertical velocity modeled as an axis (positive and negative possible) */
//private final AxisVelocity verVel = new AxisVelocity();
public int verticalVelocityCounter;
public double verticalFreedom;
public double verticalVelocity;
public int verticalVelocityUsed = 0;
public int verticalVelocityUsed = 0;
/** Horizontal velocity modeled as an axis (always positive) */
private final AxisVelocity hVel = new AxisVelocity();
private final AxisVelocity horVel = new AxisVelocity();
// Coordinates.
/** Last from coordinates. */
@ -515,18 +518,26 @@ public class MovingData extends ACheckData {
/**
* Add horizontal velocity (distance). <br>
* Since velocity is seldom an access method should be better. Flying players are expensive anyway, so this should not matter too much.
* @param vel
* @param vel Assumes positive values always.
*/
public void addHorizontalVelocity(final Velocity vel) {
hVel.add(vel);
horVel.add(vel);
}
/**
* Add vertical velocity (distance). <br>
* @param vel
*/
public void addVerticalVelocity(final Velocity vel) {
horVel.add(vel);
}
/**
* Currently only applies to horizontal velocity.
* Remove all vertical and horizontal velocity.
*/
public void removeAllVelocity() {
hVel.clear();
horVel.clear();
// verVel.clear();
}
/**
@ -535,32 +546,49 @@ public class MovingData extends ACheckData {
* @param tick All velocity added before this tick gets removed.
*/
public void removeInvalidVelocity(final int tick) {
hVel.removeInvalid(tick);
horVel.removeInvalid(tick);
// verVel.removeInvalid(tick);
}
/**
* Clear only active horizontal velocity.
*/
public void clearActiveHVel() {
hVel.clearActive();
public void clearActiveHorVel() {
horVel.clearActive();
}
/**
* Clear only active horizontal velocity.
*/
public void clearActiveVerVel() {
horVel.clearActive();
}
public boolean hasActiveHVel() {
return hVel.hasActive();
public boolean hasActiveHorVel() {
return horVel.hasActive();
}
public boolean hasQueuedHVel() {
return hVel.hasQueued();
public boolean hasQueuedHorVel() {
return horVel.hasQueued();
}
// public boolean hasActiveVerVel() {
// return verVel.hasActive();
// }
// public boolean hasQueuedVerVel() {
// return verVel.hasQueued();
// }
/**
* Called for moving events, increase age of velocity, decrease amounts, check which entries are invalid. Both horizontal and vertical.
*/
public void velocityTick() {
// Horizontal velocity (intermediate concept).
hVel.tick();
// Vertical velocity (old concept).
horVel.tick();
// Vertical velocity (new concept).
// verVel.tick();
if (verticalVelocity <= 0.09D) {
verticalVelocityUsed ++;
verticalVelocityCounter--;
@ -590,7 +618,7 @@ public class MovingData extends ACheckData {
* @return
*/
public double getHorizontalFreedom() {
return hVel.getFreedom();
return horVel.getFreedom();
}
/**
@ -602,7 +630,7 @@ public class MovingData extends ACheckData {
* @return
*/
public double useHorizontalVelocity(final double amount) {
return hVel.use(amount);
return horVel.use(amount);
}
/**
@ -610,13 +638,13 @@ public class MovingData extends ACheckData {
* @param builder
*/
public void addHorizontalVelocity(final StringBuilder builder) {
if (hVel.hasActive()) {
if (horVel.hasActive()) {
builder.append("\n" + " horizontal velocity (active):");
hVel.addActive(builder);
horVel.addActive(builder);
}
if (hVel.hasQueued()) {
if (horVel.hasQueued()) {
builder.append("\n" + " horizontal velocity (queued):");
hVel.AddQueued(builder);
horVel.AddQueued(builder);
}
}

View File

@ -204,7 +204,7 @@ public class SurvivalFly extends Check {
hFreedom = res[2];
}
else{
data.clearActiveHVel();
data.clearActiveHorVel();
hFreedom = 0.0;
if (resetFrom && data.bunnyhopDelay <= 6) {
data.bunnyhopDelay = 0;
@ -223,7 +223,7 @@ public class SurvivalFly extends Check {
}
// Prevent players from sprinting if they're moving backwards (allow buffers to cover up !?).
if (sprinting && data.lostSprintCount == 0 && !cc.assumeSprint && hDistance > walkSpeed && !data.hasActiveHVel()) {
if (sprinting && data.lostSprintCount == 0 && !cc.assumeSprint && hDistance > walkSpeed && !data.hasActiveHorVel()) {
// (Ignore some cases, in order to prevent false positives.)
// TODO: speed effects ?
if (TrigUtil.isMovingBackwards(xDistance, zDistance, from.getYaw()) && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SPRINTING)) {
@ -474,7 +474,7 @@ public class SurvivalFly extends Check {
// TODO: Should there be other side conditions?
// Invalidate used horizontal velocity.
// System.out.println("*** INVALIDATE ON SPEED");
data.clearActiveHVel();
data.clearActiveHorVel();
// if (data.horizontalVelocityUsed > cc.velocityGraceTicks) {
// data.horizontalFreedom = 0;
// data.horizontalVelocityCounter = 0;
@ -727,6 +727,8 @@ public class SurvivalFly extends Check {
private double yDirChange(final PlayerLocation from, final PlayerLocation to, final double yDistance, double vDistanceAboveLimit, final MovingData data) {
// TODO: Does this account for velocity in a sufficient way?
if (yDistance > 0) {
// TODO: Clear active vertical velocity here ?
// TODO: Demand consuming queued velocity for valid change (!).
// Increase
if (data.toWasReset) {
tags.add("ychinc");
@ -747,6 +749,7 @@ public class SurvivalFly extends Check {
// Decrease
tags.add("ychdec");
// Detect low jumping.
// TODO: sfDirty: Account for actual velocity (demands consuming queued for dir-change(!))!
if (!data.sfNoLowJump && !data.sfDirty && data.mediumLiftOff == MediumLiftOff.GROUND) {
final double setBackYDistance = to.getY() - data.getSetBackY();
if (setBackYDistance > 0.0) {