rayTraceAll was the one method the read-path cleanup restructured, moving
from an indexed loop over a copied list to an iterator with a manual
counter, and nothing covered it. The index it writes into ExtendedMOP.data
is what reduceMOP hands back to every click, activate, harvest and pick
block, so an off-by-one there would misroute interactions silently.
Six tests pin the index production: a part that misses still consumes its
index, sorting by distance happens after the indices are assigned, the
part's own data is nested underneath rather than replaced, subHit keeps
its default because data is assigned directly, and an index taken from a
hit still selects the part that produced it. harvestPart's indexing and
collisionRayTrace's nearest-or-null are covered alongside.
All six also pass against the pre-cleanup implementation at 370b353^,
which is the evidence that the restructure preserved behavior.
Everything this class does needs a client, so nothing here can run it. What is
pinned is the contract two other parties depend on and the ABI diff cannot see.
guidenh reflects on both MultipartRenderer and MultipartRenderer$ by name,
calling renderWorldBlock as a static first and falling back to the companion's
MODULE$, so both the static's exact signature and the singleton field are
pinned. Forge needs that singleton to be both a TileEntitySpecialRenderer and
an ISimpleBlockRenderingHandler or it rejects the registration. Both classes
carry class-level @SideOnly(CLIENT) and are stripped on a dedicated server.
Every lookup uses initialize = false: initialising the companion runs its
constructor, which claims a render id from Forge's RenderingRegistry.
125 plain-JVM tests, 22 Forge server tests.
A Scala package object compiles to a class literally named 'package', and that
is a Java keyword, so no Java source can declare or even name it. The
characterization had to reach both through Class.forName, which is the argument
in one line. There is no Java form to port to.
Each held exactly one member, a logger alias for its proxy, so the indirection
is inlined at its eight call sites: ConfigContent (7) and MultipartGenerator
(1). The functional characterization asserted beforehand that each alias
returned the very instance its proxy holds, so the substitution is an identity;
both classes are descriptor-identical afterwards.
Exactly four classes leave the jar and nothing else changes. No consumer
referenced them, and no Java consumer could have.
120 plain-JVM tests and 22 Forge server tests pass. PackageObjectCharacterization
went with its subject; ProxyLoggerFunctionalTest keeps the assertion worth
having, that both proxies publish a logger during preInit.
Each holds one member, a logger alias for its proxy's logger. Everything goes
through reflection because 'package' is a Java keyword and cannot appear as a
type name in Java source, which is also why these two classes have no Java
form at all.
The plain-JVM half pins the shape and that the alias reads the proxy's var
rather than holding anything, so it reports null before preInit. The Forge
server half pins the part that matters for what comes next: after preInit each
alias returns the very instance its proxy holds, adding nothing.
123 plain-JVM tests, 23 Forge server tests.
Plain-JVM coverage is structural: the Java-facing isControlDown(EntityPlayer)
static that the reference scaladoc calls out as existing for Java callers, and
the typo in the class name, which is the published name.
Forge server coverage for the behavior. isControlDown branches on whether the
player's world is remote, so it needs a real player; a Forge FakePlayer on a
dedicated server world takes the server branch and reads the map the client
keeps in sync through packet 1. Unknown players default to not holding, the map
reflects the last recorded value, and clearing resets it.
The client branch reads isClientPressing instead and no harness has a client.
120 plain-JVM tests, 21 Forge server tests.
IScheduledPacketPart is descriptor-identical and schedulePacket is unchanged.
TScheduledPacketPart.read stays abstract: TMultiPart declares read, so a
default would be shadowed and a part would silently read a description instead
of a mask. The dispatch that lived in the $class helper is now the interface
static readMask, with the one-line forwarder documented on read.
writeScheduled and readScheduled became defaults. TMultiPart declares neither,
and empty bodies are what mixing the Scala trait in already gave a Scala
implementor -- only Java implementors ever had to write them out.
sendScheduled is public because the reference's private[multipart] reaches the
handler package and Java has no equivalent scope. An unsupported mask width now
throws IllegalArgumentException rather than scala.MatchError; both are
RuntimeException and the map is still left uncleared on that path, as before.
Dropped PacketScheduler$, TScheduledPacketPart$class and two closure classes,
none referenced in bytecode or by reflective name.
118 plain-JVM tests and 18 Forge server tests pass.