A library for other mods to scale sublevels safely. For Create: Pocket Sized.
Simulated Contraptions can be miniaturized down to tiny scales while continuing to function, with their mechanics physics and collisions scaled along with them. Mass reduces when shrunken for easy transportation, and increases when growing beyond 1x.
---
Pym 0.2.0 API
Pym handles resizing Sable sublevels. A scale of 1.0 is normal size,
0.5 is half size, 2.0 is double size.
Package: com.misterblusky9.pym.api
Everything starts from the Pym class:
Pym.scale() read scales
Pym.resize() change scales
Pym.frames() convert between sublevel and world coordinates
Pym.entities() scale entities (players, mobs)
Pym.connections() which sublevels are joined to each other
Pym.extensions() hook your own rules into Pym
READING SCALE - Pym.scale()
of(subLevel) current scale, mid-transition included
settled(subLevel) last scale it came to rest at
target(subLevel) scale it's heading to (server only)
at(level, pos) scale at a world position (1.0 if not on a sublevel)
isScaled(subLevel) true if not 1x
isSettled(subLevel) true if not currently resizing
RESIZING - Pym.resize()
Build a request, then submit it:
ResizeResult result = Pym.resize().request(subLevel)
.scaleTo(0.5)
.bounds(Pym.resize().supported())
.submit();
if (!result.accepted()) {
// result.describe() says why
}
Request options:
scaleTo(x) the scale to go to
bounds(b) allowed range (default: any)
anchor(p) local point that stays put while resizing
ticks(n) how long the transition takes (default 9 ticks)
propagate(b) also resize joined sublevels (default true)
fast() cheaper physics during the transition
immediate() snap straight to the scale, no transition
Use check() instead of submit() to test a resize without doing it.
Results:
ACCEPTED it's happening
INVALID_SCALE zero, negative, NaN or infinite
UNAVAILABLE sublevel is gone, or a joined one isn't loaded
OUT_OF_BOUNDS outside the bounds you passed
BLOCKED a no-shrink block is on board, or a ResizePolicy refused
Other useful calls:
supported() ScaleBounds.SAFE, 1/16x to 8x
contents(subLevel) block count, block entities, first no-shrink block
isNoShrink(state) is this block in #pym:noshrink or the config list
shrunkBlockLimit() max blocks allowed while below 1x
SCALE DRIVERS - continuous control
A ScaleDriver keeps commanding a scale every tick (Pocket's shrink ray
beam works this way). Implement commandedScale() and isRemoved(), then:
Pym.resize().drive(subLevel, driver)
Pym.resize().release(subLevelId)
Optional overrides: bounds, transition ticks, stepped stages, anchor,
and callbacks for when a transition starts, is refused or completes.
COORDINATES - Pym.frames()
toWorld / toLocal positions
vectorToWorld / vectorToLocal vectors that scale with the sublevel
directionToWorld / directionToLocal rotation only, no scaling
lengthToWorld / lengthToLocal distances
All of these accept a null sublevel and return the input unchanged.
ENTITIES - Pym.entities()
scaleOf(entity) current entity scale
target(entity) scale it's easing towards
set(entity, scale, ticks) set scale over n ticks
multiply(entity, ratio, ticks) scale relative to current
supports(entity) can this entity be scaled
backend(entity) PEHKUI, NATIVE_STATIC or UNAVAILABLE
pehkuiPresent() is Pehkui installed
CONNECTIONS - Pym.connections()
areJoined(a, b) are two sublevels joined
isJoinedToAnother(s) is this one joined to anything
coupled(s) every sublevel that resizes together with this one
ownerOf(id) parent sublevel, if any
EXTENSIONS - Pym.extensions()
register(ResizePolicy) return a message to refuse a resize, null to allow
register(Participation) exclude sublevels, bodies or entities from scaling
register(JointConductor) mark which joints carry scale between sublevels
register(ResizeFollower) entities that resize along with a sublevel
coupling(ScaleCoupling) your own groups of sublevels that resize together
nativeStaticEntity(pred) entities that scale without Pehkui
EVENTS (NeoForge.EVENT_BUS)
SubLevelScaleEvent.Settled a sublevel finished resizing
SubLevelScaleEvent.Released a scaled sublevel was removed
ScaleTickEvent fires every scale tick per level
PhysicsSceneClosingEvent physics scene for a level is shutting down
OTHER
Pym.internalForces(subLevel) wrap your own forces on a scaled sublevel in
try-with-resources so they're applied at
the right strength
Pym.shape(subLevel) collision boxes of a sublevel
Pym.physicsLive(subLevel) is the physics body active
ScaleFormat.label(0.25) "1/4×"
client.ScaleReadout.of(...) display label that holds steady while resizing
