Prepare new block flags. Add comments.

To model differing behavior of fluids, i.e. half fall distance per
in-lava move vs. zero fall distance once in water, block flags will be
used. To really do this the NoFall check will be altered to account for
new flags. Once at it, the check should also treat from and to
independently of each other - there are some inconsistencies, such as
how oFallMaxY is set.

Further flags are reserved for MIN_HEIGHT..., indicating that
compatibility will be improved without compromising protection too much.
Thus instead of making a block entirely passable, you could set a
specific min height flag alongside ground_height (and possibly height
for max. height), in order to allow walking between level x and y but
not below (think of grass_path).
This commit is contained in:
asofold 2017-05-12 20:59:21 +02:00
parent 6347527c1c
commit 9478daaa02
3 changed files with 55 additions and 20 deletions

View File

@ -158,7 +158,8 @@ public class NoFall extends Check {
* @param to
* the to
*/
public void check(final Player player, final PlayerLocation pFrom, final PlayerLocation pTo, final MovingData data, final MovingConfig cc) {
public void check(final Player player, final PlayerLocation pFrom, final PlayerLocation pTo,
final MovingData data, final MovingConfig cc) {
final PlayerMoveData thisMove = data.playerMoves.getCurrentMove();
final LocationData from = thisMove.from;
@ -173,6 +174,11 @@ public class NoFall extends Check {
// Reset-cond is not touched by yOnGround.
// TODO: Distinguish water depth vs. fall distance ?
/*
* TODO: Account for flags instead (F_FALLDIST_ZERO and
* F_FALLDIST_HALF). Resetcond as trigger: if (resetFrom) { ...
*/
// TODO: Also handle from and to independently (rather fire twice than wait for next time).
final boolean fromReset = from.resetCond;
final boolean toReset = to.resetCond;
@ -204,12 +210,7 @@ public class NoFall extends Check {
}
else if (fromOnGround || !toOnGround && thisMove.touchedGround) {
// Check if to deal damage (fall back damage check).
if (cc.noFallDealDamage) {
handleOnGround(player, minY, true, data, cc);
}
else {
adjustFallDistance(player, minY, true, data, cc);
}
touchDown(player, minY, data, cc); // Includes the current y-distance on descend!
// Ensure very big/strange moves don't yield violations.
if (toY - fromY <= -Magic.FALL_DAMAGE_DIST) {
data.noFallSkipAirCheck = true;
@ -225,19 +226,17 @@ public class NoFall extends Check {
// In this case the player has traveled further: add the difference.
data.noFallFallDistance -= yDiff;
}
if (cc.noFallDealDamage) {
handleOnGround(player, minY, true, data, cc);
}
else {
adjustFallDistance(player, minY, true, data, cc);
}
touchDown(player, minY, data, cc);
}
else {
// Ensure fall distance is correct, or "anyway"?
}
// Set reference y for nofall (always).
// TODO: Consider setting this before handleOnGround (at least for resetTo).
/*
* TODO: Consider setting this before handleOnGround (at least for
* resetTo). This is after dealing damage, needs to be done differently.
*/
data.noFallMaxY = Math.max(Math.max(fromY, toY), data.noFallMaxY);
// TODO: fall distance might be behind (!)
@ -270,6 +269,22 @@ public class NoFall extends Check {
}
/**
* Called during check.
* @param player
* @param minY
* @param data
* @param cc
*/
private void touchDown(final Player player, final double minY, final MovingData data, final MovingConfig cc) {
if (cc.noFallDealDamage) {
handleOnGround(player, minY, true, data, cc);
}
else {
adjustFallDistance(player, minY, true, data, cc);
}
}
/**
* Set yOnGround for from and to, if needed, should be obsolete.
* @param from

View File

@ -46,7 +46,6 @@ import fr.neatmonster.nocheatplus.utilities.map.MapUtil;
*/
public class RichBoundsLocation implements IGetBukkitLocation, IGetBlockPosition, IGetBox3D {
// TODO: Store IBlockCacheNode (s) ?
// TODO: Consider switching back from default to private visibility (use getters for other places).
// Simple members //
@ -81,9 +80,11 @@ public class RichBoundsLocation implements IGetBukkitLocation, IGetBlockPosition
// "Light" object members (reset to null on set) //
// TODO: The following should be changed to primitive types, add one long for "checked"-flags. Booleans can be compressed into a long.
// TODO: primitive+isSet? AlmostBoolean?
// TODO: All properties that can be set should have a "checked" flag, thus resetting the flag suffices.
// TODO: nodeAbove ?
/** Type node for the block at the position. */
IBlockCacheNode node = null;

View File

@ -602,7 +602,25 @@ public class BlockProperties {
public static final long F_ALLOW_LOWJUMP = 0x4000000;
/** One eighth block height (0.125). */
public static final long F_HEIGHT8_1 = 0x8000000;
public static final long F_HEIGHT8_1 = 0x8000000;
/**
* Fall distance is divided by 2, if a move goes through this medium
* (currently only supports liquid).
*/
public static final long F_FALLDIST_HALF = 0x10000000;
/**
* Fall distance is set to zero, if a move goes through this medium
* (currently only supports liquid).
*/
public static final long F_FALLDIST_ZERO = 0x20000000;
/** Minimum height 15/16 (1 - 0.0625). */
public static final long F_MIN_HEIGHT16_15 = 0x40000000;
/** Minimum height 1/16 (1 - 0.0625). */
public static final long F_MIN_HEIGHT16_1 = 0x80000000; // TODO: Lily pad min height of MC versions?
// TODO: When flags are out, switch to per-block classes :p.
@ -615,7 +633,8 @@ public class BlockProperties {
*/
private static final Map<Long, String> flagNameMap = new LinkedHashMap<Long, String>();
/**
* Map flag name to flag, both names starting with F_... and the name without F_.
* Map flag name to flag, both names starting with F_... and the name
* without F_.
*/
private static final Map<String, Long> nameFlagMap = new LinkedHashMap<String, Long>();
@ -784,14 +803,14 @@ public class BlockProperties {
for (final Material mat : new Material[]{
Material.STATIONARY_WATER, Material.WATER,
}) {
blockFlags[mat.getId()] |= F_LIQUID | F_HEIGHT_8SIM_DEC | F_WATER;
blockFlags[mat.getId()] |= F_LIQUID | F_HEIGHT_8SIM_DEC | F_WATER | F_FALLDIST_ZERO;
}
// LAVA.
for (final Material mat : new Material[]{
Material.LAVA, Material.STATIONARY_LAVA,
}) {
blockFlags[mat.getId()] |= F_LIQUID | F_HEIGHT_8SIM_DEC | F_LAVA;
blockFlags[mat.getId()] |= F_LIQUID | F_HEIGHT_8SIM_DEC | F_LAVA | F_FALLDIST_HALF;
}
// Snow (1.4.x)