Still incomplete, could contain bugs (endless loops, perhaps).
Invalidation
mechanics may need to be refined.
Not covered:
* Exemption for moves resulting from horizontal push/pull.
*
* In case of non-full bounds + variable, allow ground to be found
underneath. Can concern fences (tested on 1.11).
* There has been a probably misplaced/leftover check assuming the block
above to be passable, without checking for it (iMaxY). Since the
access.getMaxBlockY() has already been checked, this part appears to be
not of use, thus iMaxY has been removed from the signature together with
this exception.
If this causes something, please provide debug logs / circumstances :).
This is unfinished, but gives an outlook on what we may be able to do
with this.
* Double doors are not covered (upper/lower half are).
* Interaction with levers / directly with doors is not covered.
* Only doors + gates (not sure what else there is).
* More fine grained configurability is missing (+ only register
listeners if needed).
* Possibly other things.
Tracking BlockRedstone seems to be more promising than BlockPhysics, as
long as we don't have to inspect neighbour blocks to check for door like
blocks at all.
Currently the oldest available entries are used, as if the player had
the maximum allowed latency always. Later on, at least attempting to hit
a global latency estimate (+window) should be attempted.
We'll still have a (moderate) fast-forward implementation to see what
opportunistic checking can do on live servers (elevators, doors etc.).
Intention is to work towards passing stored IBlockCacheNode instances to
methods in BlockProperties, i.e. to have
isOnGroundInAnOverlyOpportunisticWay implemented.
If you need one of the old BlockProperties signatures (or a more
simplified one), just open a GitHub issue.
This is a slightly peculiar change.
* Passing node and nodeAbove is a little bit odd, despite seemingly
efficient at present.
* Later we might need a BlockCache instance that busies about past
states (currently too complicated to implement).
* Uncertain impact (could perform better, could perform worse).
* Possibly left out a couple of places.
* Might have introduced bugs (fast forward).
On the other hand there may be a lot of other types of changes, if we
ever go for a less opportunistic implementation, which can not be
estimated simply, so this may be about the best that can be done, to get
a quick step in.
Already have the signature use IBlockCacheNode for node+nodeAbove, like
it will be done with other methods like collidesBlock.
This will allow calling this with past block states, once other methods
have been adapted as well.
Within BlockProperties BlockCache and IBlockCacheNode ("read only") get
passed, removing id/data/shape from arguments. If a property is not set
in the node, it'll be fetched from the block cache, but the node is not
updated from outside the BlockCache. For subsequent calls, the node
would be updated by the block cache, if it isn't a node stored by the
BlockChangeTracker from an earlier time, and similar.
This way, opportunistic passable checking can be implemented, by
switching to cached nodes instead of id/data/shape arguments with lazy
fetching from BlockCache.
The name IBlockCacheNode seems to be appropriate, since we'll pass it
alongside with a BlockCache anyway.