Skip to content

Commit 8c786cf

Browse files
committed
Keep player view rotation on spawn point updates. Closes #398
1 parent 7eacac3 commit 8c786cf

File tree

9 files changed

+73
-36
lines changed

9 files changed

+73
-36
lines changed

src/api/java/dev/compactmods/machines/api/codec/CodecExtensions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.mojang.serialization.DataResult;
55
import net.minecraft.Util;
66
import net.minecraft.world.level.ChunkPos;
7+
import net.minecraft.world.phys.Vec2;
78
import net.minecraft.world.phys.Vec3;
89

910
import java.util.UUID;
@@ -24,6 +25,10 @@ public abstract class CodecExtensions {
2425
.comapFlatMap(i -> DoubleStreamExtensions.fixedDoubleSize(i, 3)
2526
.map(out -> new Vec3(out[0], out[1], out[2])), vec -> DoubleStream.of(vec.x, vec.y, vec.z));
2627

28+
public static final Codec<Vec2> VECTOR2 = DoubleStreamExtensions.CODEC
29+
.comapFlatMap(i -> DoubleStreamExtensions.fixedDoubleSize(i, 2)
30+
.map(out -> new Vec2((float) out[0], (float) out[1])), vec -> DoubleStream.of(vec.x, vec.y));
31+
2732
public static final Codec<ChunkPos> CHUNKPOS = Codec.INT_STREAM
2833
.comapFlatMap(i -> Util.fixedSize(i, 2)
2934
.map(arr -> new ChunkPos(arr[0], arr[1])), pos -> IntStream.of(pos.x, pos.z));
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package dev.compactmods.machines.api.location;
22

3-
import java.util.Optional;
4-
5-
import com.mojang.serialization.Codec;
3+
import net.minecraft.core.BlockPos;
64
import net.minecraft.core.Direction;
75
import net.minecraft.resources.ResourceKey;
86
import net.minecraft.server.MinecraftServer;
9-
import net.minecraft.core.BlockPos;
107
import net.minecraft.server.level.ServerLevel;
118
import net.minecraft.world.level.Level;
9+
import net.minecraft.world.phys.Vec2;
1210
import net.minecraft.world.phys.Vec3;
1311

12+
import java.util.Optional;
13+
1414
public interface IDimensionalPosition {
1515

1616
BlockPos getBlockPosition();
@@ -21,7 +21,7 @@ public interface IDimensionalPosition {
2121

2222
IDimensionalPosition relative(Direction direction);
2323

24-
Optional<Vec3> getRotation();
24+
Optional<Vec2> getRotation();
2525

2626
boolean isLoaded(MinecraftServer serv);
2727
}

src/main/java/dev/compactmods/machines/location/LevelBlockPosition.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import net.minecraft.world.entity.LivingEntity;
1919
import net.minecraft.world.level.Level;
2020
import net.minecraft.world.level.block.state.BlockState;
21+
import net.minecraft.world.phys.Vec2;
2122
import net.minecraft.world.phys.Vec3;
2223
import net.minecraftforge.common.util.INBTSerializable;
2324

@@ -29,12 +30,12 @@ public class LevelBlockPosition implements INBTSerializable<CompoundTag>, IDimen
2930

3031
private ResourceKey<Level> dimension;
3132
private Vec3 position;
32-
private Vec3 rotation;
33+
private Vec2 rotation;
3334

3435
public static final Codec<LevelBlockPosition> CODEC = RecordCodecBuilder.create(i -> i.group(
3536
ResourceKey.codec(Registry.DIMENSION_REGISTRY).fieldOf("dim").forGetter(LevelBlockPosition::getDimension),
3637
CodecExtensions.VECTOR3D.fieldOf("pos").forGetter(LevelBlockPosition::getExactPosition),
37-
CodecExtensions.VECTOR3D.optionalFieldOf("rot", Vec3.ZERO).forGetter(x -> x.rotation)
38+
CodecExtensions.VECTOR2.optionalFieldOf("rot", Vec2.ZERO).forGetter(x -> x.rotation)
3839
).apply(i, LevelBlockPosition::new));
3940

4041
private LevelBlockPosition() {
@@ -43,29 +44,29 @@ private LevelBlockPosition() {
4344
public LevelBlockPosition(IDimensionalBlockPosition base) {
4445
this.dimension = base.dimensionKey();
4546
this.position = base.getExactPosition();
46-
this.rotation = Vec3.ZERO;
47+
this.rotation = Vec2.ZERO;
4748
}
4849

4950
public LevelBlockPosition(ResourceKey<Level> world, BlockPos positionBlock) {
50-
this(world, Vec3.ZERO, Vec3.ZERO);
51+
this(world, Vec3.ZERO, Vec2.ZERO);
5152
this.position = new Vec3(positionBlock.getX(), positionBlock.getY(), positionBlock.getZ());
52-
this.rotation = Vec3.ZERO;
53+
this.rotation = Vec2.ZERO;
5354
}
5455

5556
public LevelBlockPosition(ResourceKey<Level> world, Vec3 positionBlock) {
56-
this(world, positionBlock, Vec3.ZERO);
57+
this(world, positionBlock, Vec2.ZERO);
5758
this.dimension = world;
58-
this.rotation = Vec3.ZERO;
59+
this.rotation = Vec2.ZERO;
5960
}
6061

61-
public LevelBlockPosition(ResourceKey<Level> dim, Vec3 pos, Vec3 rotation) {
62+
public LevelBlockPosition(ResourceKey<Level> dim, Vec3 pos, Vec2 rotation) {
6263
this.dimension = dim;
6364
this.position = pos;
6465
this.rotation = rotation;
6566
}
6667

6768
public static LevelBlockPosition fromEntity(LivingEntity entity) {
68-
return new LevelBlockPosition(entity.level.dimension(), entity.position());
69+
return new LevelBlockPosition(entity.level.dimension(), entity.position(), entity.getRotationVector());
6970
}
7071

7172
public ServerLevel level(@Nonnull MinecraftServer server) {
@@ -97,7 +98,7 @@ public static LevelBlockPosition fromNBT(CompoundTag nbt) {
9798
@Override
9899
public CompoundTag serializeNBT() {
99100
if(this.rotation == null)
100-
this.rotation = Vec3.ZERO;
101+
this.rotation = Vec2.ZERO;
101102

102103
DataResult<Tag> nbt = CODEC.encodeStart(NbtOps.INSTANCE, this);
103104
return (CompoundTag) nbt.result().orElse(null);
@@ -120,7 +121,7 @@ public ResourceKey<Level> getDimension() {
120121
return this.dimension;
121122
}
122123

123-
public Optional<Vec3> getRotation() {
124+
public Optional<Vec2> getRotation() {
124125
return Optional.of(this.rotation);
125126
}
126127

src/main/java/dev/compactmods/machines/location/PreciseDimensionalPosition.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.mojang.serialization.codecs.RecordCodecBuilder;
55
import dev.compactmods.machines.api.codec.CodecExtensions;
66
import dev.compactmods.machines.api.location.IDimensionalPosition;
7-
import dev.compactmods.machines.util.MathUtil;
87
import net.minecraft.core.BlockPos;
98
import net.minecraft.core.Direction;
109
import net.minecraft.core.Registry;
@@ -13,6 +12,7 @@
1312
import net.minecraft.server.level.ServerLevel;
1413
import net.minecraft.world.entity.player.Player;
1514
import net.minecraft.world.level.Level;
15+
import net.minecraft.world.phys.Vec2;
1616
import net.minecraft.world.phys.Vec3;
1717

1818
import java.util.Objects;
@@ -77,7 +77,7 @@ public IDimensionalPosition relative(Direction direction) {
7777
}
7878

7979
@Override
80-
public Optional<Vec3> getRotation() {
80+
public Optional<Vec2> getRotation() {
8181
return Optional.empty();
8282
}
8383

src/main/java/dev/compactmods/machines/location/SimpleTeleporter.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,31 @@
22

33
import net.minecraft.server.level.ServerLevel;
44
import net.minecraft.world.entity.Entity;
5+
import net.minecraft.world.level.portal.PortalInfo;
6+
import net.minecraft.world.phys.Vec2;
57
import net.minecraft.world.phys.Vec3;
68
import net.minecraftforge.common.util.ITeleporter;
9+
import org.jetbrains.annotations.Nullable;
710

811
import java.util.function.Function;
912

10-
public record SimpleTeleporter(Vec3 pos) implements ITeleporter {
13+
public record SimpleTeleporter(Vec3 pos, Vec2 rotation) implements ITeleporter {
1114

1215
public static SimpleTeleporter to(Vec3 pos) {
13-
return new SimpleTeleporter(pos);
16+
return new SimpleTeleporter(pos, Vec2.ZERO);
17+
}
18+
19+
public static SimpleTeleporter to(Vec3 pos, Vec2 rotation) {
20+
return new SimpleTeleporter(pos, rotation);
21+
}
22+
23+
@Override
24+
public @Nullable PortalInfo getPortalInfo(Entity entity, ServerLevel destWorld, Function<ServerLevel, PortalInfo> defaultPortalInfo) {
25+
return new PortalInfo(pos, Vec3.ZERO, rotation.y, rotation.x);
1426
}
1527

1628
@Override
1729
public Entity placeEntity(Entity entity, ServerLevel currentWorld, ServerLevel destWorld, float yaw, Function<Boolean, Entity> repositionEntity) {
18-
entity = repositionEntity.apply(false);
19-
entity.teleportTo(pos.x, pos.y, pos.z);
20-
return entity;
30+
return repositionEntity.apply(false);
2131
}
2232
}

src/main/java/dev/compactmods/machines/room/Rooms.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import net.minecraft.server.MinecraftServer;
1717
import net.minecraft.world.level.ChunkPos;
1818
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
19+
import net.minecraft.world.phys.Vec2;
1920
import net.minecraft.world.phys.Vec3;
2021

2122
import javax.naming.OperationNotSupportedException;
@@ -98,7 +99,7 @@ public static void resetSpawn(MinecraftServer server, ChunkPos room) throws None
9899
final var centerPoint = Vec3.atCenterOf(roomInfo.getCenter());
99100
final var newSpawn = centerPoint.subtract(0, (roomInfo.getSize().getInternalSize() / 2f), 0);
100101

101-
data.setSpawn(room, newSpawn);
102+
data.setSpawn(room, newSpawn, Vec2.ZERO);
102103
}
103104

104105
public static Optional<String> getRoomName(MinecraftServer server, ChunkPos room) throws NonexistentRoomException {

src/main/java/dev/compactmods/machines/room/data/CompactRoomData.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import net.minecraft.world.level.saveddata.SavedData;
2424
import net.minecraft.world.level.storage.DimensionDataStorage;
2525
import net.minecraft.world.phys.AABB;
26+
import net.minecraft.world.phys.Vec2;
2627
import net.minecraft.world.phys.Vec3;
2728

2829
import javax.annotation.Nonnull;
@@ -124,20 +125,26 @@ public LevelBlockPosition getSpawn(ChunkPos roomChunk) {
124125

125126
return new LevelBlockPosition(
126127
CompactDimension.LEVEL_KEY,
127-
roomData.getSpawn()
128+
roomData.getSpawn(),
129+
roomData.getSpawnRotation()
128130
);
129131
}
130132

131133
public int getNextSpiralPosition() {
132134
return this.roomData.size() + 1;
133135
}
134136

137+
@Deprecated
135138
public void setSpawn(ChunkPos roomChunk, Vec3 position) {
139+
setSpawn(roomChunk, position, Vec2.ZERO);
140+
}
141+
142+
public void setSpawn(ChunkPos roomChunk, Vec3 position, Vec2 rotation) {
136143
if (!roomData.containsKey(roomChunk))
137144
return;
138145

139146
RoomData roomData = this.roomData.get(roomChunk);
140-
roomData.setSpawn(position);
147+
roomData.setSpawn(position, rotation);
141148

142149
setDirty();
143150
}
@@ -218,7 +225,7 @@ public NewRoomRegistration chunk(ChunkPos chunk) {
218225
}
219226

220227
public void register() throws OperationNotSupportedException {
221-
RoomData data = new RoomData(owner, center, spawn, size, Optional.empty());
228+
RoomData data = new RoomData(owner, center, spawn, Vec2.ZERO, size, Optional.empty());
222229
storage.register(chunk, data);
223230
}
224231
}
@@ -229,21 +236,24 @@ public static class RoomData {
229236
CodecExtensions.UUID_CODEC.fieldOf("owner").forGetter(RoomData::getOwner),
230237
BlockPos.CODEC.fieldOf("center").forGetter(RoomData::getCenter),
231238
CodecExtensions.VECTOR3D.fieldOf("spawn").forGetter(RoomData::getSpawn),
239+
CodecExtensions.VECTOR2.optionalFieldOf("spawnRot", Vec2.ZERO).forGetter(RoomData::getSpawnRotation),
232240
RoomSize.CODEC.fieldOf("size").forGetter(RoomData::getSize),
233241
Codec.STRING.optionalFieldOf("name").forGetter(RoomData::getName)
234242
).apply(i, RoomData::new));
235243

236244
private final UUID owner;
237245
private final BlockPos center;
238246
private Vec3 spawn;
247+
private @org.jetbrains.annotations.Nullable Vec2 spawnRotation;
239248
private final RoomSize size;
240249
private boolean hasCustomName;
241250
private String name;
242251

243-
public RoomData(UUID owner, BlockPos center, Vec3 spawn, RoomSize size, Optional<String> name) {
252+
public RoomData(UUID owner, BlockPos center, Vec3 spawn, Vec2 spawnRotation, RoomSize size, Optional<String> name) {
244253
this.owner = owner;
245254
this.center = center;
246255
this.spawn = spawn;
256+
this.spawnRotation = spawnRotation;
247257
this.size = size;
248258

249259
name.ifPresentOrElse(n -> {
@@ -278,12 +288,22 @@ public Vec3 getSpawn() {
278288
return this.spawn;
279289
}
280290

291+
public Vec2 getSpawnRotation() {
292+
return this.spawnRotation;
293+
}
294+
281295
public BlockPos getCenter() {
282296
return this.center;
283297
}
284298

299+
@Deprecated(forRemoval = true)
285300
public void setSpawn(Vec3 newSpawn) {
301+
setSpawn(newSpawn, Vec2.ZERO);
302+
}
303+
304+
public void setSpawn(Vec3 newSpawn, Vec2 rotation) {
286305
this.spawn = newSpawn;
306+
this.spawnRotation = rotation;
287307
}
288308

289309
public AABB getRoomBounds() {

src/main/java/dev/compactmods/machines/shrinking/PersonalShrinkingDevice.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public InteractionResultHolder<ItemStack> use(Level world, Player player, Intera
6969
final CompactRoomData intern = CompactRoomData.get(playerDim);
7070

7171
// Use internal data to set new spawn point
72-
intern.setSpawn(machineChunk, player.position());
72+
intern.setSpawn(machineChunk, player.position(), player.getRotationVector());
7373

7474
MutableComponent tc = TranslationUtil.message(Messages.ROOM_SPAWNPOINT_SET)
7575
.withStyle(ChatFormatting.GREEN);

src/main/java/dev/compactmods/machines/util/PlayerUtil.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import net.minecraft.world.level.ChunkPos;
2525
import net.minecraft.world.level.Level;
2626
import net.minecraft.world.level.LevelAccessor;
27+
import net.minecraft.world.phys.Vec2;
2728
import net.minecraft.world.phys.Vec3;
2829
import net.minecraftforge.common.util.LazyOptional;
2930

@@ -90,11 +91,11 @@ public static void teleportPlayerIntoRoom(MinecraftServer serv, Player player, C
9091

9192
serv.submitAsync(() -> {
9293
Vec3 sp = spawn.getExactPosition();
93-
Vec3 sr = spawn.getRotation().orElse(new Vec3(player.xRotO, player.yRotO, 0));
94+
Vec2 sr = spawn.getRotation().orElse(player.getRotationVector());
9495

9596
if (player instanceof ServerPlayer servPlayer) {
96-
servPlayer.changeDimension(compactDim, SimpleTeleporter.to(sp));
97-
97+
servPlayer.changeDimension(compactDim, SimpleTeleporter.to(sp, sr));
98+
servPlayer.setCamera(null); // force camera update
9899
if (grantAdvancement)
99100
AdvancementTriggers.getTriggerForMachineClaim(roomSize).trigger(servPlayer);
100101
}
@@ -120,11 +121,10 @@ public static void teleportPlayerOutOfMachine(ServerLevel world, @Nonnull Server
120121

121122
final var level = spawnPoint.level(serv);
122123

123-
Vec3 worldPos, entryRot;
124-
worldPos = spawnPoint.getExactPosition();
125-
entryRot = spawnPoint.getRotation().orElse(Vec3.ZERO);
124+
Vec3 worldPos = spawnPoint.getExactPosition();
125+
Vec2 entryRot = spawnPoint.getRotation().orElse(Vec2.ZERO);
126126

127-
serverPlayer.changeDimension(level, SimpleTeleporter.to(worldPos));
127+
serverPlayer.changeDimension(level, SimpleTeleporter.to(worldPos, entryRot));
128128
} else {
129129
howDidYouGetThere(serverPlayer);
130130

0 commit comments

Comments
 (0)