Skip to content

Commit 6b9681d

Browse files
committed
bug: Fixed walkways and escalators not working on Sable sublevels
1 parent 28dab14 commit 6b9681d

5 files changed

Lines changed: 122 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## [1.3.0] - Unreleased
4+
5+
Create: Escalated now has compatibility with Sable (Create: Aeronautics) on NeoForge 1.21.1.
6+
7+
### Fixed:
8+
- Fixed walkways and escalators not working on Sable sublevels
9+
310
## [1.2.1] - 2026-01-07
411

512
Create: Escalated now supports Create v6.0.8.1 on Fabric 1.20.1.

src/main/java/rbasamoyai/escalated/CreateEscalatedNeoForge.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
1010
import net.neoforged.neoforge.event.tick.ServerTickEvent;
1111
import net.neoforged.neoforge.registries.RegisterEvent;
12+
import rbasamoyai.escalated.compat.sable.SableCompat;
1213
import rbasamoyai.escalated.config.EscalatedConfigs;
1314
import rbasamoyai.escalated.index.EscalatedDataComponents;
1415
import rbasamoyai.escalated.index.EscalatedTriggers;
@@ -33,6 +34,8 @@ public CreateEscalatedNeoForge(IEventBus modBus) {
3334

3435
forgeBus.addListener(this::onServerTick);
3536
forgeBus.addListener(this::onServerStopping);
37+
38+
EscalatedModsNeoForge.SABLE.executeIfInstalled(() -> () -> SableCompat.register());
3639
}
3740

3841

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package rbasamoyai.escalated;
2+
3+
import com.simibubi.create.foundation.utility.CreateLang;
4+
import net.minecraft.core.registries.BuiltInRegistries;
5+
import net.minecraft.resources.ResourceLocation;
6+
import net.minecraft.world.level.block.Block;
7+
import net.neoforged.fml.ModList;
8+
9+
import java.util.Optional;
10+
import java.util.function.Supplier;
11+
12+
// Copied from Create's Mods class --ritchie
13+
public enum EscalatedModsNeoForge {
14+
SABLE;
15+
16+
private final String id;
17+
18+
EscalatedModsNeoForge() { this.id = CreateLang.asId(name()); }
19+
20+
public String id() { return this.id; }
21+
22+
public ResourceLocation resource(String path) { return ResourceLocation.fromNamespaceAndPath(this.id, path); }
23+
24+
public Block getBlock(String id) { return BuiltInRegistries.BLOCK.get(this.resource(id)); }
25+
26+
public boolean isLoaded() { return ModList.get().isLoaded(this.id); }
27+
28+
public <T> Optional<T> runIfInstalled(Supplier<Supplier<T>> toRun) {
29+
return this.isLoaded() ? Optional.of(toRun.get().get()) : Optional.empty();
30+
}
31+
32+
public void executeIfInstalled(Supplier<Runnable> toExecute) { if (isLoaded()) toExecute.get().run(); }
33+
34+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package rbasamoyai.escalated.compat.sable;
2+
3+
import dev.ryanhcode.sable.Sable;
4+
import dev.ryanhcode.sable.sublevel.SubLevel;
5+
import net.minecraft.world.entity.Entity;
6+
import net.minecraft.world.level.block.entity.BlockEntity;
7+
import net.minecraft.world.phys.Vec3;
8+
import rbasamoyai.escalated.walkways.WalkwayMovementHandler;
9+
10+
import java.util.Optional;
11+
12+
public class SableCompat {
13+
14+
public static void register() {
15+
WalkwayMovementHandler.addWalkwayTransformer(new WalkwayTransformer());
16+
}
17+
18+
private static class WalkwayTransformer implements WalkwayMovementHandler.WalkwayTransformer {
19+
public Optional<Vec3> transformPos(Entity entity, BlockEntity be) {
20+
SubLevel subLevel = Sable.HELPER.getContaining(be);
21+
return subLevel != null ? Optional.of(subLevel.logicalPose().transformPositionInverse(entity.position())) : Optional.empty();
22+
}
23+
24+
@Override
25+
public Optional<Vec3> transformMovement(Vec3 movement, BlockEntity be) {
26+
SubLevel subLevel = Sable.HELPER.getContaining(be);
27+
return subLevel != null ? Optional.of(subLevel.logicalPose().transformNormal(movement)) : Optional.empty();
28+
}
29+
}
30+
31+
}

src/main/java/rbasamoyai/escalated/walkways/WalkwayMovementHandler.java

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package rbasamoyai.escalated.walkways;
22

3+
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
34
import net.minecraft.core.BlockPos;
45
import net.minecraft.core.Direction;
56
import net.minecraft.core.Vec3i;
@@ -19,6 +20,7 @@
1920
import rbasamoyai.escalated.advancements.WalkwayTravelTracker;
2021

2122
import java.util.List;
23+
import java.util.Optional;
2224

2325
import static net.minecraft.core.Direction.AxisDirection.NEGATIVE;
2426
import static net.minecraft.core.Direction.AxisDirection.POSITIVE;
@@ -77,8 +79,10 @@ public static void transportEntity(WalkwayBlockEntity walkwayBE, Entity entity,
7779
if (Math.abs(walkwayBE.getSpeed()) < 1 || !walkwayBlock.movesEntities(blockState))
7880
return;
7981

82+
Vec3 entityPos = getEntityPos(entity, walkwayBE);
83+
double entityY = entityPos.y;
8084
// Not on top
81-
if (entity.getY() + 0.25f < pos.getY())
85+
if (entityY + 0.25d < pos.getY())
8286
return;
8387

8488
// Lock entities in place
@@ -95,13 +99,13 @@ public static void transportEntity(WalkwayBlockEntity walkwayBE, Entity entity,
9599
Vec3i centeringDirection = Direction.get(POSITIVE, walkwayFacing.getClockWise().getAxis()).getNormal();
96100
Vec3 movement = Vec3.atLowerCornerOf(movementDirection.getNormal()).scale(movementSpeed);
97101

98-
double diffCenter = axis == Direction.Axis.Z ? (pos.getX() + .5f - entity.getX()) : (pos.getZ() + .5f - entity.getZ());
99-
if (Math.abs(diffCenter) > 48 / 64f)
102+
double diffCenter = axis == Direction.Axis.Z ? (pos.getX() + .5d - entityPos.x) : (pos.getZ() + .5d - entityPos.z);
103+
if (Math.abs(diffCenter) > 48 / 64d)
100104
return;
101105

102-
float top = 15.5f / 16f;
103-
boolean onSlope = slope == WalkwaySlope.MIDDLE || slope == WalkwaySlope.TOP && entity.getY() - pos.getY() < top
104-
|| slope == WalkwaySlope.BOTTOM && entity.getY() - pos.getY() > top;
106+
double top = 15.5d / 16d;
107+
boolean onSlope = slope == WalkwaySlope.MIDDLE || slope == WalkwaySlope.TOP && entityY - pos.getY() < top
108+
|| slope == WalkwaySlope.BOTTOM && entityY - pos.getY() > top;
105109

106110
boolean movingDown = onSlope && movementFacing != walkwayFacing;
107111
boolean movingUp = onSlope && movementFacing == walkwayFacing;
@@ -117,7 +121,7 @@ public static void transportEntity(WalkwayBlockEntity walkwayBE, Entity entity,
117121
if (movingDown)
118122
movement = movement.add(0, -Math.abs(axis.choose(movement.x, movement.y, movement.z)), 0);
119123

120-
Vec3 centering = Vec3.atLowerCornerOf(centeringDirection).scale(diffCenter * Math.min(Math.abs(movementSpeed), .1f) * 4);
124+
Vec3 centering = Vec3.atLowerCornerOf(centeringDirection).scale(diffCenter * Math.min(Math.abs(movementSpeed), .1d) * 4);
121125

122126
if (!(entity instanceof LivingEntity living) || living.zza == 0 && living.xxa == 0)
123127
movement = movement.add(centering);
@@ -130,7 +134,7 @@ public static void transportEntity(WalkwayBlockEntity walkwayBE, Entity entity,
130134
}
131135

132136
// Entity Collisions
133-
if (Math.abs(movementSpeed) < .5f) {
137+
if (Math.abs(movementSpeed) < .5d) {
134138
Vec3 checkDistance = movement.normalize()
135139
.scale(0.5);
136140
AABB bb = entity.getBoundingBox();
@@ -150,17 +154,17 @@ public static void transportEntity(WalkwayBlockEntity walkwayBE, Entity entity,
150154

151155
if (movingUp) {
152156
Vec3 prevPos = entity.position();
153-
entity.move(SELF, movement);
157+
entity.move(SELF, transformMovement(movement, walkwayBE));
154158
if (entity.horizontalCollision) {
155159
entity.setPos(prevPos); // Restore position and try again, but with adjusted starting condition
156-
entity.move(SELF, new Vec3(0, movement.y * 0.1, 0)); // adjusted
157-
entity.move(SELF, movement);
160+
entity.move(SELF, transformMovement(new Vec3(0, movement.y * 0.1, 0), walkwayBE)); // adjusted
161+
entity.move(SELF, transformMovement(movement, walkwayBE));
158162
}
159163
} else if (movingDown) {
160-
entity.move(SELF, movement.multiply(1, 0, 1));
161-
entity.move(SELF, movement.multiply(0, 1, 0));
164+
entity.move(SELF, transformMovement(movement.multiply(1, 0, 1), walkwayBE));
165+
entity.move(SELF, transformMovement(movement.multiply(0, 1, 0), walkwayBE));
162166
} else {
163-
entity.move(SELF, movement);
167+
entity.move(SELF, transformMovement(movement, walkwayBE));
164168
}
165169

166170
// Placement on steps
@@ -192,4 +196,33 @@ public static boolean isRidingOrBeingRiddenBy(Entity me, Entity other) {
192196
return false;
193197
}
194198

199+
// Compatibility code //
200+
201+
private static final List<WalkwayTransformer> TRANSFORMERS = new ReferenceArrayList<>();
202+
203+
public static void addWalkwayTransformer(WalkwayTransformer t) { TRANSFORMERS.add(t); }
204+
205+
public static Vec3 getEntityPos(Entity entity, BlockEntity be) {
206+
for (WalkwayTransformer t : TRANSFORMERS) {
207+
Optional<Vec3> o = t.transformPos(entity, be);
208+
if (o.isPresent())
209+
return o.get();
210+
}
211+
return entity.position();
212+
}
213+
214+
public static Vec3 transformMovement(Vec3 movement, BlockEntity be) {
215+
for (WalkwayTransformer t : TRANSFORMERS) {
216+
Optional<Vec3> o = t.transformMovement(movement, be);
217+
if (o.isPresent())
218+
return o.get();
219+
}
220+
return movement;
221+
}
222+
223+
public interface WalkwayTransformer {
224+
Optional<Vec3> transformPos(Entity entity, BlockEntity be);
225+
Optional<Vec3> transformMovement(Vec3 movement, BlockEntity be);
226+
}
227+
195228
}

0 commit comments

Comments
 (0)