24w09a
This commit is contained in:
1 parent
2dd8674ea6
commit
4e57eecf2d
37 files changed
+511
-458
No files matched your search
+2
-2
@@ -3,8 +3,8 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check https://fabricmc.net/develop/
|
# check https://fabricmc.net/develop/
|
||||||
minecraft_version=24w07a
|
minecraft_version=24w09a
|
||||||
loader_version=0.15.6
|
loader_version=0.15.7
|
||||||
jsr305_version=3.0.2
|
jsr305_version=3.0.2
|
||||||
fabric_version=0.91.1+1.20.3
|
fabric_version=0.91.1+1.20.3
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import com.mojang.brigadier.arguments.StringArgumentType;
|
|||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.commands.CommandBuildContext;
|
import net.minecraft.commands.CommandBuildContext;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.commands.arguments.DimensionArgument;
|
import net.minecraft.commands.arguments.DimensionArgument;
|
||||||
@@ -304,7 +305,7 @@ public class PlayerCommand
|
|||||||
|
|
||||||
private static int maxNameLength(MinecraftServer server)
|
private static int maxNameLength(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return server.getPort() >= 0 ? Player.MAX_NAME_LENGTH : 40;
|
return server.getPort() >= 0 ? SharedConstants.MAX_PLAYER_NAME_LENGTH : 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int manipulate(CommandContext<CommandSourceStack> context, Consumer<EntityPlayerActionPack> action)
|
private static int manipulate(CommandContext<CommandSourceStack> context, Consumer<EntityPlayerActionPack> action)
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package carpet.fakes;
|
package carpet.fakes;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Either;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.ChunkResult;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.util.thread.BlockableEventLoop;
|
import net.minecraft.util.thread.BlockableEventLoop;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
@@ -10,5 +9,5 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
|||||||
|
|
||||||
public interface ChunkHolderInterface
|
public interface ChunkHolderInterface
|
||||||
{
|
{
|
||||||
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> setDefaultProtoChunk(ChunkPos chpos, BlockableEventLoop<Runnable> executor, ServerLevel world);
|
CompletableFuture<ChunkResult<ChunkAccess>> setDefaultProtoChunk(ChunkPos chpos, BlockableEventLoop<Runnable> executor, ServerLevel world);
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.fakes.ChunkHolderInterface;
|
import carpet.fakes.ChunkHolderInterface;
|
||||||
import com.mojang.datafixers.util.Either;
|
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.server.level.ChunkResult;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
@@ -14,23 +15,22 @@ import net.minecraft.server.level.ServerLevel;
|
|||||||
import net.minecraft.util.thread.BlockableEventLoop;
|
import net.minecraft.util.thread.BlockableEventLoop;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import net.minecraft.world.level.chunk.UpgradeData;
|
import net.minecraft.world.level.chunk.UpgradeData;
|
||||||
|
|
||||||
@Mixin(ChunkHolder.class)
|
@Mixin(ChunkHolder.class)
|
||||||
public abstract class ChunkHolder_scarpetChunkCreationMixin implements ChunkHolderInterface
|
public abstract class ChunkHolder_scarpetChunkCreationMixin implements ChunkHolderInterface
|
||||||
{
|
{
|
||||||
@Shadow protected abstract void updateChunkToSave(CompletableFuture<? extends Either<? extends ChunkAccess, ChunkHolder.ChunkLoadingFailure>> newChunkFuture, String type);
|
@Shadow protected abstract void updateChunkToSave(CompletableFuture<? extends ChunkResult<? extends ChunkAccess>> newChunkFuture, String type);
|
||||||
|
|
||||||
@Shadow @Final private AtomicReferenceArray<CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> futures;
|
@Shadow @Final private AtomicReferenceArray<CompletableFuture<ChunkResult<ChunkAccess>>> futures;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> setDefaultProtoChunk(ChunkPos chpos, BlockableEventLoop<Runnable> executor, ServerLevel world)
|
public CompletableFuture<ChunkResult<ChunkAccess>> setDefaultProtoChunk(ChunkPos chpos, BlockableEventLoop<Runnable> executor, ServerLevel world)
|
||||||
{
|
{
|
||||||
int i = ChunkStatus.EMPTY.getIndex();
|
int i = ChunkStatus.EMPTY.getIndex();
|
||||||
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completableFuture2 = CompletableFuture.supplyAsync(
|
CompletableFuture<ChunkResult<ChunkAccess>> completableFuture2 = CompletableFuture.supplyAsync(
|
||||||
() -> Either.left(new ProtoChunk(chpos, UpgradeData.EMPTY, world, world.registryAccess().registryOrThrow(Registries.BIOME), null)), // todo figure out what that does - maybe add an option to reset with blending enabled..?
|
() -> ChunkResult.of(new ProtoChunk(chpos, UpgradeData.EMPTY, world, world.registryAccess().registryOrThrow(Registries.BIOME), null)), // todo figure out what that does - maybe add an option to reset with blending enabled..?
|
||||||
executor
|
executor
|
||||||
);
|
);
|
||||||
updateChunkToSave(completableFuture2, "unfull"); // possible debug data
|
updateChunkToSave(completableFuture2, "unfull"); // possible debug data
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ import net.minecraft.core.registries.BuiltInRegistries;
|
|||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.TickTask;
|
import net.minecraft.server.TickTask;
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
import net.minecraft.server.level.ChunkHolder.ChunkLoadingFailure;
|
|
||||||
import net.minecraft.server.level.ChunkMap;
|
import net.minecraft.server.level.ChunkMap;
|
||||||
import net.minecraft.server.level.ChunkMap.DistanceManager;
|
import net.minecraft.server.level.ChunkMap.DistanceManager;
|
||||||
|
import net.minecraft.server.level.ChunkResult;
|
||||||
import net.minecraft.server.level.ChunkTaskPriorityQueueSorter;
|
import net.minecraft.server.level.ChunkTaskPriorityQueueSorter;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||||
@@ -32,8 +32,8 @@ import net.minecraft.world.entity.Entity;
|
|||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFile;
|
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
@@ -44,8 +44,6 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Either;
|
|
||||||
|
|
||||||
import carpet.fakes.ChunkHolderInterface;
|
import carpet.fakes.ChunkHolderInterface;
|
||||||
import carpet.fakes.ChunkTicketManagerInterface;
|
import carpet.fakes.ChunkTicketManagerInterface;
|
||||||
import carpet.fakes.ServerLightingProviderInterface;
|
import carpet.fakes.ServerLightingProviderInterface;
|
||||||
@@ -104,7 +102,8 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
protected abstract Iterable<ChunkHolder> getChunks();
|
protected abstract Iterable<ChunkHolder> getChunks();
|
||||||
|
|
||||||
|
|
||||||
@Shadow protected abstract CompletableFuture<Either<List<ChunkAccess>, ChunkLoadingFailure>> getChunkRangeFuture(final ChunkHolder chunkHolder, final int i, final IntFunction<ChunkStatus> intFunction);
|
@Shadow
|
||||||
|
protected abstract CompletableFuture<ChunkResult<List<ChunkAccess>>> getChunkRangeFuture(ChunkHolder chunkHolder, int i, IntFunction<ChunkStatus> intFunction);
|
||||||
|
|
||||||
//@Shadow protected abstract void postLoadProtoChunk(final ServerLevel serverLevel, final List<CompoundTag> list);
|
//@Shadow protected abstract void postLoadProtoChunk(final ServerLevel serverLevel, final List<CompoundTag> list);
|
||||||
|
|
||||||
@@ -112,8 +111,8 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
|
|
||||||
// in protoChunkToFullChunk
|
// in protoChunkToFullChunk
|
||||||
// fancier version of the one below, ensuring that the event is triggered when the chunk is actually loaded.
|
// fancier version of the one below, ensuring that the event is triggered when the chunk is actually loaded.
|
||||||
@Inject(method = "method_20460", at = @At("HEAD"), remap = false)
|
@Inject(method = "method_17227", at = @At("HEAD"), remap = false)
|
||||||
private void onChunkGeneratedStart(ChunkHolder chunkHolder, Either<ChunkAccess, ChunkLoadingFailure> chunk, CallbackInfoReturnable<CompletableFuture<Either<ChunkAccess, ChunkLoadingFailure>>> cir)
|
private void onChunkGeneratedStart(ChunkHolder chunkHolder, ChunkAccess chunkAccess, CallbackInfoReturnable<ChunkAccess> cir)
|
||||||
{
|
{
|
||||||
if (CHUNK_GENERATED.isNeeded() || CHUNK_LOADED.isNeeded())
|
if (CHUNK_GENERATED.isNeeded() || CHUNK_LOADED.isNeeded())
|
||||||
{
|
{
|
||||||
@@ -125,27 +124,31 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "method_20460", at = @At("RETURN"), remap = false)
|
@Inject(method = "method_17227", at = @At("RETURN"), remap = false)
|
||||||
private void onChunkGeneratedEnd(ChunkHolder chunkHolder, Either<ChunkAccess, ChunkLoadingFailure> chunk, CallbackInfoReturnable<CompletableFuture<Either<ChunkAccess, ChunkLoadingFailure>>> cir)
|
private void onChunkGeneratedEnd(ChunkHolder chunkHolder, ChunkAccess chunk, CallbackInfoReturnable<CompletableFuture<ChunkResult<ChunkAccess>>> cir)
|
||||||
{
|
{
|
||||||
Boolean localGenerated= generated.get();
|
Boolean localGenerated = generated.get();
|
||||||
if (localGenerated != null)
|
if (localGenerated != null)
|
||||||
{
|
{
|
||||||
MinecraftServer server = this.level.getServer();
|
MinecraftServer server = this.level.getServer();
|
||||||
int ticks = server.getTickCount();
|
int ticks = server.getTickCount();
|
||||||
ChunkPos chpos = chunkHolder.getPos();
|
ChunkPos chpos = chunkHolder.getPos();
|
||||||
// need to send these because if an app does something with that event, it may lock the thread
|
// need to send these because if an app does something with that event, it may lock the thread
|
||||||
// so better be safe and schedule it for later, aSaP
|
// so better be safe and schedule it for later, aSaP
|
||||||
if (CHUNK_GENERATED.isNeeded() && localGenerated)
|
if (CHUNK_GENERATED.isNeeded() && localGenerated)
|
||||||
server.tell(new TickTask(ticks, () -> CHUNK_GENERATED.onChunkEvent(this.level, chpos, true)));
|
{
|
||||||
|
server.tell(new TickTask(ticks, () -> CHUNK_GENERATED.onChunkEvent(this.level, chpos, true)));
|
||||||
|
}
|
||||||
if (CHUNK_LOADED.isNeeded())
|
if (CHUNK_LOADED.isNeeded())
|
||||||
server.tell(new TickTask(ticks, () -> CHUNK_LOADED.onChunkEvent(this.level, chpos, localGenerated)));
|
{
|
||||||
|
server.tell(new TickTask(ticks, () -> CHUNK_LOADED.onChunkEvent(this.level, chpos, localGenerated)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* simple but a version that doesn't guarantee that the chunk is actually loaded
|
/* simple but a version that doesn't guarantee that the chunk is actually loaded
|
||||||
@Inject(method = "convertToFullChunk", at = @At("HEAD"))
|
@Inject(method = "convertToFullChunk", at = @At("HEAD"))
|
||||||
private void onChunkGeneratedEnd(ChunkHolder chunkHolder, CallbackInfoReturnable<CompletableFuture<Either<Chunk, Unloaded>>> cir)
|
private void onChunkGeneratedEnd(ChunkHolder chunkHolder, CallbackInfoReturnable<CompletableFuture<ChunkResult<ChunkAccess>>> cir)
|
||||||
{
|
{
|
||||||
if (CHUNK_GENERATED.isNeeded() && chunkHolder.getCurrentChunk().getStatus() != ChunkStatus.FULL)
|
if (CHUNK_GENERATED.isNeeded() && chunkHolder.getCurrentChunk().getStatus() != ChunkStatus.FULL)
|
||||||
{
|
{
|
||||||
@@ -162,29 +165,29 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void addTicket(final ChunkPos pos, final ChunkStatus status)
|
private void addTicket(ChunkPos pos, ChunkStatus status)
|
||||||
{ // UNKNOWN
|
{ // UNKNOWN
|
||||||
this.distanceManager.addTicket(TicketType.UNKNOWN, pos, 33 + ChunkStatus.getDistance(status), pos);
|
this.distanceManager.addTicket(TicketType.UNKNOWN, pos, 33 + ChunkStatus.getDistance(status), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void addTicket(final ChunkPos pos)
|
private void addTicket(ChunkPos pos)
|
||||||
{
|
{
|
||||||
this.addTicket(pos, ChunkStatus.EMPTY);
|
this.addTicket(pos, ChunkStatus.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void addRelightTicket(final ChunkPos pos)
|
private void addRelightTicket(ChunkPos pos)
|
||||||
{
|
{
|
||||||
this.distanceManager.addRegionTicket(TicketType.LIGHT, pos, 1, pos);
|
this.distanceManager.addRegionTicket(TicketType.LIGHT, pos, 1, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releaseRelightTicket(final ChunkPos pos)
|
public void releaseRelightTicket(ChunkPos pos)
|
||||||
{
|
{
|
||||||
this.mainThreadExecutor.tell(Util.name(
|
this.mainThreadExecutor.tell(Util.name(
|
||||||
() -> this.distanceManager.removeRegionTicket(TicketType.LIGHT, pos, 1, pos),
|
() -> this.distanceManager.removeRegionTicket(TicketType.LIGHT, pos, 1, pos),
|
||||||
() -> "release relight ticket " + pos
|
() -> "release relight ticket " + pos
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,57 +198,69 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private Set<ChunkPos> getExistingChunks(final Set<ChunkPos> requestedChunks)
|
private Set<ChunkPos> getExistingChunks(Set<ChunkPos> requestedChunks)
|
||||||
{
|
{
|
||||||
final Map<String, RegionFile> regionCache = new HashMap<>();
|
Map<String, RegionFile> regionCache = new HashMap<>();
|
||||||
final Set<ChunkPos> ret = new HashSet<>();
|
Set<ChunkPos> ret = new HashSet<>();
|
||||||
|
|
||||||
for (final ChunkPos pos : requestedChunks)
|
for (ChunkPos pos : requestedChunks)
|
||||||
|
{
|
||||||
if (WorldTools.canHasChunk(this.level, pos, regionCache, true))
|
if (WorldTools.canHasChunk(this.level, pos, regionCache, true))
|
||||||
|
{
|
||||||
ret.add(pos);
|
ret.add(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private Set<ChunkPos> loadExistingChunksFromDisk(final Set<ChunkPos> requestedChunks)
|
private Set<ChunkPos> loadExistingChunksFromDisk(Set<ChunkPos> requestedChunks)
|
||||||
{
|
{
|
||||||
final Set<ChunkPos> existingChunks = this.getExistingChunks(requestedChunks);
|
Set<ChunkPos> existingChunks = this.getExistingChunks(requestedChunks);
|
||||||
for (final ChunkPos pos : existingChunks)
|
for (ChunkPos pos : existingChunks)
|
||||||
|
{
|
||||||
this.updatingChunkMap.get(pos.toLong()).getOrScheduleFuture(ChunkStatus.EMPTY, (ChunkMap) (Object) this);
|
this.updatingChunkMap.get(pos.toLong()).getOrScheduleFuture(ChunkStatus.EMPTY, (ChunkMap) (Object) this);
|
||||||
|
}
|
||||||
|
|
||||||
return existingChunks;
|
return existingChunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private Set<ChunkPos> loadExistingChunks(final Set<ChunkPos> requestedChunks, final Object2IntMap<String> report)
|
private Set<ChunkPos> loadExistingChunks(Set<ChunkPos> requestedChunks, Object2IntMap<String> report)
|
||||||
{
|
{
|
||||||
if (report != null)
|
if (report != null)
|
||||||
|
{
|
||||||
report.put("requested_chunks", requestedChunks.size());
|
report.put("requested_chunks", requestedChunks.size());
|
||||||
|
}
|
||||||
|
|
||||||
// Load all relevant ChunkHolders into this.currentChunkHolders
|
// Load all relevant ChunkHolders into this.currentChunkHolders
|
||||||
// This will not trigger loading from disk yet
|
// This will not trigger loading from disk yet
|
||||||
|
|
||||||
for (final ChunkPos pos : requestedChunks)
|
for (ChunkPos pos : requestedChunks)
|
||||||
|
{
|
||||||
this.addTicket(pos);
|
this.addTicket(pos);
|
||||||
|
}
|
||||||
|
|
||||||
this.tickTicketManager();
|
this.tickTicketManager();
|
||||||
|
|
||||||
// Fetch all currently loaded chunks
|
// Fetch all currently loaded chunks
|
||||||
|
|
||||||
final Set<ChunkPos> loadedChunks = requestedChunks.stream().filter(
|
Set<ChunkPos> loadedChunks = requestedChunks.stream().filter(
|
||||||
pos -> this.updatingChunkMap.get(pos.toLong()).getLastAvailable() != null // all relevant ChunkHolders exist
|
pos -> this.updatingChunkMap.get(pos.toLong()).getLastAvailable() != null // all relevant ChunkHolders exist
|
||||||
).collect(Collectors.toSet());
|
).collect(Collectors.toSet());
|
||||||
|
|
||||||
if (report != null)
|
if (report != null)
|
||||||
|
{
|
||||||
report.put("loaded_chunks", loadedChunks.size());
|
report.put("loaded_chunks", loadedChunks.size());
|
||||||
|
}
|
||||||
|
|
||||||
// Load remaining chunks from disk
|
// Load remaining chunks from disk
|
||||||
|
|
||||||
final Set<ChunkPos> unloadedChunks = new HashSet<>(requestedChunks);
|
Set<ChunkPos> unloadedChunks = new HashSet<>(requestedChunks);
|
||||||
unloadedChunks.removeAll(loadedChunks);
|
unloadedChunks.removeAll(loadedChunks);
|
||||||
|
|
||||||
final Set<ChunkPos> existingChunks = this.loadExistingChunksFromDisk(unloadedChunks);
|
Set<ChunkPos> existingChunks = this.loadExistingChunksFromDisk(unloadedChunks);
|
||||||
|
|
||||||
existingChunks.addAll(loadedChunks);
|
existingChunks.addAll(loadedChunks);
|
||||||
|
|
||||||
@@ -253,27 +268,27 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private Set<ChunkPos> loadExistingChunks(final Set<ChunkPos> requestedChunks)
|
private Set<ChunkPos> loadExistingChunks(Set<ChunkPos> requestedChunks)
|
||||||
{
|
{
|
||||||
return this.loadExistingChunks(requestedChunks, null);
|
return this.loadExistingChunks(requestedChunks, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void waitFor(final Future<?> future)
|
private void waitFor(Future<?> future)
|
||||||
{
|
{
|
||||||
this.mainThreadExecutor.managedBlock(future::isDone);
|
this.mainThreadExecutor.managedBlock(future::isDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void waitFor(final List<? extends CompletableFuture<?>> futures)
|
private void waitFor(List<? extends CompletableFuture<?>> futures)
|
||||||
{
|
{
|
||||||
this.waitFor(Util.sequenceFailFast(futures));
|
this.waitFor(Util.sequenceFailFast(futures));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private ChunkAccess getCurrentChunk(final ChunkPos pos)
|
private ChunkAccess getCurrentChunk(ChunkPos pos)
|
||||||
{
|
{
|
||||||
final CompletableFuture<ChunkAccess> future = this.updatingChunkMap.get(pos.toLong()).getChunkToSave();
|
CompletableFuture<ChunkAccess> future = this.updatingChunkMap.get(pos.toLong()).getChunkToSave();
|
||||||
this.waitFor(future);
|
this.waitFor(future);
|
||||||
|
|
||||||
return future.join();
|
return future.join();
|
||||||
@@ -285,95 +300,125 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
this.addTicket(pos);
|
this.addTicket(pos);
|
||||||
this.tickTicketManager();
|
this.tickTicketManager();
|
||||||
if (this.updatingChunkMap.get(pos.toLong()).getLastAvailable() == null) // chunk unloaded
|
if (this.updatingChunkMap.get(pos.toLong()).getLastAvailable() == null) // chunk unloaded
|
||||||
|
{
|
||||||
if (WorldTools.canHasChunk(this.level, pos, null, true))
|
if (WorldTools.canHasChunk(this.level, pos, null, true))
|
||||||
|
{
|
||||||
this.updatingChunkMap.get(pos.toLong()).getOrScheduleFuture(ChunkStatus.EMPTY, (ChunkMap) (Object) this);
|
this.updatingChunkMap.get(pos.toLong()).getOrScheduleFuture(ChunkStatus.EMPTY, (ChunkMap) (Object) this);
|
||||||
final ChunkAccess chunk = this.getCurrentChunk(pos);
|
}
|
||||||
if (!(chunk.getStatus().isOrAfter(ChunkStatus.LIGHT.getParent()))) return;
|
}
|
||||||
|
ChunkAccess chunk = this.getCurrentChunk(pos);
|
||||||
|
if (!(chunk.getStatus().isOrAfter(ChunkStatus.LIGHT.getParent())))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
((ServerLightingProviderInterface) this.lightEngine).removeLightData(chunk);
|
((ServerLightingProviderInterface) this.lightEngine).removeLightData(chunk);
|
||||||
this.addRelightTicket(pos);
|
this.addRelightTicket(pos);
|
||||||
ChunkHolder chunkHolder = this.updatingChunkMap.get(pos.toLong());
|
ChunkHolder chunkHolder = this.updatingChunkMap.get(pos.toLong());
|
||||||
final CompletableFuture<?> lightFuture = this.getChunkRangeFuture(chunkHolder, 1, (pos_) -> ChunkStatus.LIGHT)
|
CompletableFuture<?> lightFuture = this.getChunkRangeFuture(chunkHolder, 1, (pos_) -> ChunkStatus.LIGHT)
|
||||||
.thenCompose(
|
.thenCompose(results -> {
|
||||||
either -> either.map(
|
List<ChunkAccess> depList = results.orElse(null);
|
||||||
list -> ((ServerLightingProviderInterface) this.lightEngine).relight(chunk),
|
if (depList == null)
|
||||||
unloaded -> {
|
{
|
||||||
this.releaseRelightTicket(pos);
|
this.releaseRelightTicket(pos);
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(ChunkResult.error(results::getError));
|
||||||
}
|
}
|
||||||
)
|
((ServerLightingProviderInterface) this.lightEngine).relight(chunk);
|
||||||
|
return CompletableFuture.completedFuture(ChunkResult.of(depList));
|
||||||
|
}
|
||||||
);
|
);
|
||||||
this.waitFor(lightFuture);
|
this.waitFor(lightFuture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Integer> regenerateChunkRegion(final List<ChunkPos> requestedChunksList)
|
public Map<String, Integer> regenerateChunkRegion(List<ChunkPos> requestedChunksList)
|
||||||
{
|
{
|
||||||
final Object2IntMap<String> report = new Object2IntOpenHashMap<>();
|
Object2IntMap<String> report = new Object2IntOpenHashMap<>();
|
||||||
final Set<ChunkPos> requestedChunks = new HashSet<>(requestedChunksList);
|
Set<ChunkPos> requestedChunks = new HashSet<>(requestedChunksList);
|
||||||
|
|
||||||
// Load requested chunks
|
// Load requested chunks
|
||||||
|
|
||||||
final Set<ChunkPos> existingChunks = this.loadExistingChunks(requestedChunks, report);
|
Set<ChunkPos> existingChunks = this.loadExistingChunks(requestedChunks, report);
|
||||||
|
|
||||||
// Finish pending generation stages
|
// Finish pending generation stages
|
||||||
// This ensures that no generation events will be put back on the main thread after the chunks have been deleted
|
// This ensures that no generation events will be put back on the main thread after the chunks have been deleted
|
||||||
|
|
||||||
final Set<ChunkAccess> affectedChunks = new HashSet<>();
|
Set<ChunkAccess> affectedChunks = new HashSet<>();
|
||||||
|
|
||||||
for (final ChunkPos pos : existingChunks)
|
for (ChunkPos pos : existingChunks)
|
||||||
|
{
|
||||||
affectedChunks.add(this.getCurrentChunk(pos));
|
affectedChunks.add(this.getCurrentChunk(pos));
|
||||||
|
}
|
||||||
|
|
||||||
report.put("affected_chunks", affectedChunks.size());
|
report.put("affected_chunks", affectedChunks.size());
|
||||||
|
|
||||||
// Load neighbors for light removal
|
// Load neighbors for light removal
|
||||||
|
|
||||||
final Set<ChunkPos> neighbors = new HashSet<>();
|
Set<ChunkPos> neighbors = new HashSet<>();
|
||||||
|
|
||||||
for (final ChunkAccess chunk : affectedChunks)
|
for (ChunkAccess chunk : affectedChunks)
|
||||||
{
|
{
|
||||||
final ChunkPos pos = chunk.getPos();
|
ChunkPos pos = chunk.getPos();
|
||||||
|
|
||||||
for (int x = -1; x <= 1; ++x)
|
for (int x = -1; x <= 1; ++x)
|
||||||
|
{
|
||||||
for (int z = -1; z <= 1; ++z)
|
for (int z = -1; z <= 1; ++z)
|
||||||
|
{
|
||||||
if (x != 0 || z != 0)
|
if (x != 0 || z != 0)
|
||||||
{
|
{
|
||||||
final ChunkPos nPos = new ChunkPos(pos.x + x, pos.z + z);
|
ChunkPos nPos = new ChunkPos(pos.x + x, pos.z + z);
|
||||||
if (!requestedChunks.contains(nPos))
|
if (!requestedChunks.contains(nPos))
|
||||||
|
{
|
||||||
neighbors.add(nPos);
|
neighbors.add(nPos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadExistingChunks(neighbors);
|
this.loadExistingChunks(neighbors);
|
||||||
|
|
||||||
// Determine affected neighbors
|
// Determine affected neighbors
|
||||||
|
|
||||||
final Set<ChunkAccess> affectedNeighbors = new HashSet<>();
|
Set<ChunkAccess> affectedNeighbors = new HashSet<>();
|
||||||
|
|
||||||
for (final ChunkPos pos : neighbors)
|
for (ChunkPos pos : neighbors)
|
||||||
{
|
{
|
||||||
final ChunkAccess chunk = this.getCurrentChunk(pos);
|
ChunkAccess chunk = this.getCurrentChunk(pos);
|
||||||
|
|
||||||
if (chunk.getStatus().isOrAfter(ChunkStatus.LIGHT.getParent()))
|
if (chunk.getStatus().isOrAfter(ChunkStatus.LIGHT.getParent()))
|
||||||
|
{
|
||||||
affectedNeighbors.add(chunk);
|
affectedNeighbors.add(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unload affected chunks
|
// Unload affected chunks
|
||||||
|
|
||||||
for (final ChunkAccess chunk : affectedChunks)
|
for (ChunkAccess chunk : affectedChunks)
|
||||||
{
|
{
|
||||||
final ChunkPos pos = chunk.getPos();
|
ChunkPos pos = chunk.getPos();
|
||||||
|
|
||||||
// remove entities
|
// remove entities
|
||||||
long longPos = pos.toLong();
|
long longPos = pos.toLong();
|
||||||
if (this.entitiesInLevel.contains(longPos) && chunk instanceof LevelChunk)
|
if (this.entitiesInLevel.contains(longPos) && chunk instanceof LevelChunk)
|
||||||
((SimpleEntityLookupInterface<Entity>)((ServerWorldInterface)level).getEntityLookupCMPublic()).getChunkEntities(pos).forEach(entity -> { if (!(entity instanceof Player)) entity.discard();});
|
{
|
||||||
|
((SimpleEntityLookupInterface<Entity>) ((ServerWorldInterface) level).getEntityLookupCMPublic()).getChunkEntities(pos).forEach(entity -> {
|
||||||
|
if (!(entity instanceof Player))
|
||||||
|
{
|
||||||
|
entity.discard();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (chunk instanceof LevelChunk)
|
if (chunk instanceof LevelChunk)
|
||||||
|
{
|
||||||
((LevelChunk) chunk).setLoaded(false);
|
((LevelChunk) chunk).setLoaded(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.entitiesInLevel.remove(pos.toLong()) && chunk instanceof LevelChunk)
|
if (this.entitiesInLevel.remove(pos.toLong()) && chunk instanceof LevelChunk)
|
||||||
|
{
|
||||||
this.level.unload((LevelChunk) chunk); // block entities only
|
this.level.unload((LevelChunk) chunk); // block entities only
|
||||||
|
}
|
||||||
|
|
||||||
((ServerLightingProviderInterface) this.lightEngine).invokeUpdateChunkStatus(pos);
|
((ServerLightingProviderInterface) this.lightEngine).invokeUpdateChunkStatus(pos);
|
||||||
((ServerLightingProviderInterface) this.lightEngine).removeLightData(chunk);
|
((ServerLightingProviderInterface) this.lightEngine).removeLightData(chunk);
|
||||||
@@ -383,13 +428,13 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
|
|
||||||
// Replace ChunkHolders
|
// Replace ChunkHolders
|
||||||
|
|
||||||
for (final ChunkAccess chunk : affectedChunks)
|
for (ChunkAccess chunk : affectedChunks)
|
||||||
{
|
{
|
||||||
final ChunkPos cPos = chunk.getPos();
|
ChunkPos cPos = chunk.getPos();
|
||||||
final long pos = cPos.toLong();
|
long pos = cPos.toLong();
|
||||||
|
|
||||||
final ChunkHolder oldHolder = this.updatingChunkMap.remove(pos);
|
ChunkHolder oldHolder = this.updatingChunkMap.remove(pos);
|
||||||
final ChunkHolder newHolder = new ChunkHolder(cPos, oldHolder.getTicketLevel(), level, this.lightEngine, this.queueSorter, (ChunkHolder.PlayerProvider) this);
|
ChunkHolder newHolder = new ChunkHolder(cPos, oldHolder.getTicketLevel(), level, this.lightEngine, this.queueSorter, (ChunkHolder.PlayerProvider) this);
|
||||||
((ChunkHolderInterface) newHolder).setDefaultProtoChunk(cPos, this.mainThreadExecutor, level); // enable chunk blending?
|
((ChunkHolderInterface) newHolder).setDefaultProtoChunk(cPos, this.mainThreadExecutor, level); // enable chunk blending?
|
||||||
this.updatingChunkMap.put(pos, newHolder);
|
this.updatingChunkMap.put(pos, newHolder);
|
||||||
|
|
||||||
@@ -400,50 +445,54 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
this.promoteChunkMap();
|
this.promoteChunkMap();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Force generation to previous states
|
// Force generation to previous states
|
||||||
// This ensures that the world is in a consistent state after this method
|
// This ensures that the world is in a consistent state after this method
|
||||||
// Also, this is needed to ensure chunks are saved to disk
|
// Also, this is needed to ensure chunks are saved to disk
|
||||||
|
|
||||||
final Map<ChunkPos, ChunkStatus> targetGenerationStatus = affectedChunks.stream().collect(
|
Map<ChunkPos, ChunkStatus> targetGenerationStatus = affectedChunks.stream().collect(
|
||||||
Collectors.toMap(ChunkAccess::getPos, ChunkAccess::getStatus)
|
Collectors.toMap(ChunkAccess::getPos, ChunkAccess::getStatus)
|
||||||
);
|
);
|
||||||
|
|
||||||
for (final Entry<ChunkPos, ChunkStatus> entry : targetGenerationStatus.entrySet())
|
for (Entry<ChunkPos, ChunkStatus> entry : targetGenerationStatus.entrySet())
|
||||||
|
{
|
||||||
this.addTicket(entry.getKey(), entry.getValue());
|
this.addTicket(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
this.tickTicketManager();
|
this.tickTicketManager();
|
||||||
|
|
||||||
final List<Pair<ChunkStatus, CompletableFuture<?>>> targetGenerationFutures = new ArrayList<>();
|
List<Pair<ChunkStatus, CompletableFuture<?>>> targetGenerationFutures = new ArrayList<>();
|
||||||
|
|
||||||
for (final Entry<ChunkPos, ChunkStatus> entry : targetGenerationStatus.entrySet())
|
for (Entry<ChunkPos, ChunkStatus> entry : targetGenerationStatus.entrySet())
|
||||||
|
{
|
||||||
targetGenerationFutures.add(Pair.of(
|
targetGenerationFutures.add(Pair.of(
|
||||||
entry.getValue(),
|
entry.getValue(),
|
||||||
this.updatingChunkMap.get(entry.getKey().toLong()).getOrScheduleFuture(entry.getValue(), (ChunkMap) (Object) this)
|
this.updatingChunkMap.get(entry.getKey().toLong()).getOrScheduleFuture(entry.getValue(), (ChunkMap) (Object) this)
|
||||||
));
|
));
|
||||||
|
}
|
||||||
|
|
||||||
final Map<ChunkStatus, List<CompletableFuture<?>>> targetGenerationFuturesGrouped = targetGenerationFutures.stream().collect(
|
Map<ChunkStatus, List<CompletableFuture<?>>> targetGenerationFuturesGrouped = targetGenerationFutures.stream().collect(
|
||||||
Collectors.groupingBy(
|
Collectors.groupingBy(
|
||||||
Pair::getKey,
|
Pair::getKey,
|
||||||
Collectors.mapping(
|
Collectors.mapping(
|
||||||
Entry::getValue,
|
Entry::getValue,
|
||||||
Collectors.toList()
|
Collectors.toList()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
for (final ChunkStatus status : ChunkStatus.getStatusList())
|
for (ChunkStatus status : ChunkStatus.getStatusList())
|
||||||
{
|
{
|
||||||
final List<CompletableFuture<?>> futures = targetGenerationFuturesGrouped.get(status);
|
List<CompletableFuture<?>> futures = targetGenerationFuturesGrouped.get(status);
|
||||||
|
|
||||||
if (futures == null)
|
if (futures == null)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String statusName = BuiltInRegistries.CHUNK_STATUS.getKey(status).getPath();
|
String statusName = BuiltInRegistries.CHUNK_STATUS.getKey(status).getPath();
|
||||||
|
|
||||||
report.put("layer_count_" + statusName, futures.size());
|
report.put("layer_count_" + statusName, futures.size());
|
||||||
final long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
this.waitFor(futures);
|
this.waitFor(futures);
|
||||||
|
|
||||||
@@ -451,42 +500,46 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
report.put("relight_count", affectedNeighbors.size());
|
report.put("relight_count", affectedNeighbors.size());
|
||||||
|
|
||||||
// Remove light for affected neighbors
|
// Remove light for affected neighbors
|
||||||
|
|
||||||
for (final ChunkAccess chunk : affectedNeighbors)
|
for (ChunkAccess chunk : affectedNeighbors)
|
||||||
|
{
|
||||||
((ServerLightingProviderInterface) this.lightEngine).removeLightData(chunk);
|
((ServerLightingProviderInterface) this.lightEngine).removeLightData(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
// Schedule relighting of neighbors
|
// Schedule relighting of neighbors
|
||||||
|
|
||||||
for (final ChunkAccess chunk : affectedNeighbors)
|
for (ChunkAccess chunk : affectedNeighbors)
|
||||||
|
{
|
||||||
this.addRelightTicket(chunk.getPos());
|
this.addRelightTicket(chunk.getPos());
|
||||||
|
}
|
||||||
|
|
||||||
this.tickTicketManager();
|
this.tickTicketManager();
|
||||||
|
|
||||||
final List<CompletableFuture<?>> lightFutures = new ArrayList<>();
|
List<CompletableFuture<?>> lightFutures = new ArrayList<>();
|
||||||
|
|
||||||
for (final ChunkAccess chunk : affectedNeighbors)
|
for (ChunkAccess chunk : affectedNeighbors)
|
||||||
{
|
{
|
||||||
final ChunkPos pos = chunk.getPos();
|
ChunkPos pos = chunk.getPos();
|
||||||
|
|
||||||
lightFutures.add(this.getChunkRangeFuture (this.updatingChunkMap.get(pos.toLong()), 1, (pos_) -> ChunkStatus.LIGHT).thenCompose(
|
lightFutures.add(this.getChunkRangeFuture(this.updatingChunkMap.get(pos.toLong()), 1, (pos_) -> ChunkStatus.LIGHT).thenCompose(
|
||||||
either -> either.map(
|
results -> {
|
||||||
list -> ((ServerLightingProviderInterface) this.lightEngine).relight(chunk),
|
List<ChunkAccess> depList = results.orElse(null);
|
||||||
unloaded -> {
|
if (depList == null)
|
||||||
this.releaseRelightTicket(pos);
|
{
|
||||||
return CompletableFuture.completedFuture(null);
|
this.releaseRelightTicket(pos);
|
||||||
}
|
return CompletableFuture.completedFuture(ChunkResult.error(results::getError));
|
||||||
)
|
}
|
||||||
|
((ServerLightingProviderInterface) this.lightEngine).relight(chunk);
|
||||||
|
return CompletableFuture.completedFuture(ChunkResult.of(depList));
|
||||||
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final long relightStart = System.currentTimeMillis();
|
long relightStart = System.currentTimeMillis();
|
||||||
|
|
||||||
this.waitFor(lightFutures);
|
this.waitFor(lightFutures);
|
||||||
|
|
||||||
@@ -496,7 +549,8 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<ChunkHolder> getChunksCM() {
|
public Iterable<ChunkHolder> getChunksCM()
|
||||||
|
{
|
||||||
return getChunks();
|
return getChunks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,6 @@ import static carpet.script.CarpetEventServer.Event.PLAYER_PICKS_UP_ITEM;
|
|||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
@Mixin(Inventory.class)
|
@Mixin(Inventory.class)
|
||||||
@@ -27,13 +26,11 @@ public abstract class Inventory_scarpetEventMixin
|
|||||||
{
|
{
|
||||||
if (!PLAYER_PICKS_UP_ITEM.isNeeded() || !(player instanceof ServerPlayer))
|
if (!PLAYER_PICKS_UP_ITEM.isNeeded() || !(player instanceof ServerPlayer))
|
||||||
return playerInventory.add(-1, stack);
|
return playerInventory.add(-1, stack);
|
||||||
Item item = stack.getItem();
|
|
||||||
int count = stack.getCount();
|
int count = stack.getCount();
|
||||||
boolean res = playerInventory.add(-1, stack);
|
boolean res = playerInventory.add(-1, stack);
|
||||||
if (count != stack.getCount()) // res returns false for larger item adding to a almost full ineventory
|
if (count != stack.getCount()) // res returns false for larger item adding to a almost full ineventory
|
||||||
{
|
{
|
||||||
ItemStack diffStack = new ItemStack(item, count - stack.getCount());
|
ItemStack diffStack = stack.copyWithCount(count - stack.getCount());
|
||||||
diffStack.setTag(stack.getTag());
|
|
||||||
PLAYER_PICKS_UP_ITEM.onItemAction((ServerPlayer) player, null, diffStack);
|
PLAYER_PICKS_UP_ITEM.onItemAction((ServerPlayer) player, null, diffStack);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||||||
public class PickaxeItem_missingToolsMixin extends DiggerItem
|
public class PickaxeItem_missingToolsMixin extends DiggerItem
|
||||||
{
|
{
|
||||||
|
|
||||||
protected PickaxeItem_missingToolsMixin(float attackDamage, float attackSpeed, Tier material, TagKey<Block> tag, Properties settings) {
|
protected PickaxeItem_missingToolsMixin(Tier material, TagKey<Block> tag, Properties settings) {
|
||||||
super(attackDamage, attackSpeed, material, tag, settings);
|
super(material, tag, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ public class CarpetClient
|
|||||||
ListTag outputTag = (ListTag) tag.get("output");
|
ListTag outputTag = (ListTag) tag.get("output");
|
||||||
for (int i = 0; i < outputTag.size(); i++)
|
for (int i = 0; i < outputTag.size(); i++)
|
||||||
{
|
{
|
||||||
CarpetSettings.LOG.info(" - response: " + Component.Serializer.fromJson(outputTag.getString(i)).getString());
|
CarpetSettings.LOG.info(" - response: " + Component.Serializer.fromJson(outputTag.getString(i), clientPlayer.registryAccess()).getString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public class ServerNetworkHandler
|
|||||||
ListTag outputResult = new ListTag();
|
ListTag outputResult = new ListTag();
|
||||||
for (Component line : output)
|
for (Component line : output)
|
||||||
{
|
{
|
||||||
outputResult.add(StringTag.valueOf(Component.Serializer.toJson(line)));
|
outputResult.add(StringTag.valueOf(Component.Serializer.toJson(line, player.registryAccess())));
|
||||||
}
|
}
|
||||||
if (!output.isEmpty())
|
if (!output.isEmpty())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import java.util.Optional;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import carpet.script.CarpetContext;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.ClassUtils;
|
import org.apache.commons.lang3.ClassUtils;
|
||||||
|
|
||||||
@@ -101,8 +103,8 @@ public final class AnnotationParser
|
|||||||
* <p>Additionally, if the class contains annotated instance (non-static) methods, the class must be concrete and provide a no-arg constructor
|
* <p>Additionally, if the class contains annotated instance (non-static) methods, the class must be concrete and provide a no-arg constructor
|
||||||
* to instantiate it.</p>
|
* to instantiate it.</p>
|
||||||
*
|
*
|
||||||
* @see ScarpetFunction
|
|
||||||
* @param clazz The class to parse
|
* @param clazz The class to parse
|
||||||
|
* @see ScarpetFunction
|
||||||
*/
|
*/
|
||||||
public static void parseFunctionClass(Class<?> clazz)
|
public static void parseFunctionClass(Class<?> clazz)
|
||||||
{
|
{
|
||||||
@@ -119,7 +121,7 @@ public final class AnnotationParser
|
|||||||
catch (ReflectiveOperationException e)
|
catch (ReflectiveOperationException e)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Couldn't create instance of given " + clazz + ". This is needed for non-static methods. Make sure default constructor is available", e);
|
"Couldn't create instance of given " + clazz + ". This is needed for non-static methods. Make sure default constructor is available", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Method[] methodz = clazz.getDeclaredMethods();
|
Method[] methodz = clazz.getDeclaredMethods();
|
||||||
@@ -132,7 +134,7 @@ public final class AnnotationParser
|
|||||||
|
|
||||||
if (method.getExceptionTypes().length != 0)
|
if (method.getExceptionTypes().length != 0)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Annotated method '" + method.getName() +"', provided in '"+clazz+"' must not declare checked exceptions");
|
throw new IllegalArgumentException("Annotated method '" + method.getName() + "', provided in '" + clazz + "' must not declare checked exceptions");
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedFunction function = new ParsedFunction(method, clazz, instanceSupplier);
|
ParsedFunction function = new ParsedFunction(method, clazz, instanceSupplier);
|
||||||
@@ -233,7 +235,8 @@ public final class AnnotationParser
|
|||||||
MethodHandle tempHandle = MethodHandles.publicLookup().unreflect(method).asFixedArity().asSpreader(Object[].class, this.methodParamCount);
|
MethodHandle tempHandle = MethodHandles.publicLookup().unreflect(method).asFixedArity().asSpreader(Object[].class, this.methodParamCount);
|
||||||
tempHandle = tempHandle.asType(tempHandle.type().changeReturnType(Object.class));
|
tempHandle = tempHandle.asType(tempHandle.type().changeReturnType(Object.class));
|
||||||
this.handle = Modifier.isStatic(method.getModifiers()) ? tempHandle : tempHandle.bindTo(instance.get());
|
this.handle = Modifier.isStatic(method.getModifiers()) ? tempHandle : tempHandle.bindTo(instance.get());
|
||||||
} catch (IllegalAccessException e)
|
}
|
||||||
|
catch (IllegalAccessException e)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException(e);
|
throw new IllegalArgumentException(e);
|
||||||
}
|
}
|
||||||
@@ -245,6 +248,8 @@ public final class AnnotationParser
|
|||||||
@Override
|
@Override
|
||||||
public LazyValue apply(Context context, Context.Type t, List<LazyValue> lazyValues)
|
public LazyValue apply(Context context, Context.Type t, List<LazyValue> lazyValues)
|
||||||
{
|
{
|
||||||
|
// yes we are making a minecraft dependency, because of the stupid registry access required to parse stuff
|
||||||
|
RegistryAccess regs = ((CarpetContext) context).registryAccess();
|
||||||
List<Value> lv = AbstractLazyFunction.unpackLazy(lazyValues, context, contextType);
|
List<Value> lv = AbstractLazyFunction.unpackLazy(lazyValues, context, contextType);
|
||||||
if (isEffectivelyVarArgs)
|
if (isEffectivelyVarArgs)
|
||||||
{
|
{
|
||||||
@@ -262,7 +267,7 @@ public final class AnnotationParser
|
|||||||
Object[] params = getMethodParams(lv, context, t);
|
Object[] params = getMethodParams(lv, context, t);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Value result = outputConverter.convert(handle.invokeExact(params));
|
Value result = outputConverter.convert(handle.invokeExact(params), regs);
|
||||||
return (cc, tt) -> result;
|
return (cc, tt) -> result;
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
@@ -306,8 +311,9 @@ public final class AnnotationParser
|
|||||||
}
|
}
|
||||||
varArgsList.add(obj);
|
varArgsList.add(obj);
|
||||||
}
|
}
|
||||||
varArgs = varArgsList.toArray((Object[])Array.newInstance(varArgsType, 0));
|
varArgs = varArgsList.toArray((Object[]) Array.newInstance(varArgsType, 0));
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
varArgs = (Object[]) Array.newInstance(varArgsType, remaining / varArgsConverter.valueConsumption());
|
varArgs = (Object[]) Array.newInstance(varArgsType, remaining / varArgsConverter.valueConsumption());
|
||||||
for (int i = 0; lvIterator.hasNext(); i++)
|
for (int i = 0; lvIterator.hasNext(); i++)
|
||||||
@@ -337,7 +343,8 @@ public final class AnnotationParser
|
|||||||
builder.append(", ");
|
builder.append(", ");
|
||||||
builder.append(varArgsConverter.getTypeName());
|
builder.append(varArgsConverter.getTypeName());
|
||||||
builder.append("s...)");
|
builder.append("s...)");
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
builder.append(')');
|
builder.append(')');
|
||||||
}
|
}
|
||||||
@@ -346,5 +353,7 @@ public final class AnnotationParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnnotationParser() {}
|
private AnnotationParser()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,11 @@ package carpet.script.annotation;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.GlobalPos;
|
import net.minecraft.core.GlobalPos;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
@@ -29,36 +31,36 @@ import javax.annotation.Nullable;
|
|||||||
* <p>A converter from a given {@link Object} of type T into a {@link Value}, used in order to convert the outputs of methods into usable Scarpet
|
* <p>A converter from a given {@link Object} of type T into a {@link Value}, used in order to convert the outputs of methods into usable Scarpet
|
||||||
* values.</p>
|
* values.</p>
|
||||||
*
|
*
|
||||||
* @see #register(Class, Function)
|
* @see #register(Class, BiFunction)
|
||||||
* @param <T> The type to convert from into a {@link Value}
|
* @param <T> The type to convert from into a {@link Value}
|
||||||
*/
|
*/
|
||||||
public final class OutputConverter<T>
|
public final class OutputConverter<T>
|
||||||
{
|
{
|
||||||
private static final Map<Class<?>, OutputConverter<?>> byResult = new HashMap<>();
|
private static final Map<Class<?>, OutputConverter<?>> byResult = new HashMap<>();
|
||||||
private static final OutputConverter<Value> VALUE = new OutputConverter<>(Function.identity());
|
private static final OutputConverter<Value> VALUE = new OutputConverter<>((v, regs) -> v);
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
// Primitives are handled. Things are boxed in the process anyway, therefore would recommend boxed outputs, so you can use null
|
// Primitives are handled. Things are boxed in the process anyway, therefore would recommend boxed outputs, so you can use null
|
||||||
register(Void.TYPE, v -> Value.NULL);
|
register(Void.TYPE, v -> Value.NULL);
|
||||||
register(Boolean.class, BooleanValue::of);
|
register(Boolean.class, BooleanValue::of);
|
||||||
register(Integer.class, NumericValue::new);
|
register(Integer.class, (v, r) -> new NumericValue(v));
|
||||||
register(Double.class, NumericValue::of);
|
register(Double.class, NumericValue::of);
|
||||||
register(Float.class, NumericValue::of);
|
register(Float.class, NumericValue::of);
|
||||||
register(Long.class, NumericValue::new);
|
register(Long.class, (v, r) -> new NumericValue(v));
|
||||||
register(String.class, StringValue::new);
|
register(String.class, StringValue::new);
|
||||||
register(Entity.class, EntityValue::new);
|
register(Entity.class, EntityValue::new);
|
||||||
register(Component.class, FormattedTextValue::new);
|
register(Component.class, FormattedTextValue::new);
|
||||||
register(Tag.class, NBTSerializableValue::new);
|
register(Tag.class, NBTSerializableValue::new);
|
||||||
register(BlockPos.class, ValueConversions::of);
|
register(BlockPos.class, (v, r) -> ValueConversions.of(v));
|
||||||
register(Vec3.class, ValueConversions::of);
|
register(Vec3.class, (v, r) -> ValueConversions.of(v));
|
||||||
register(ItemStack.class, ValueConversions::of);
|
register(ItemStack.class, (v, r) -> ValueConversions.of(v, r));
|
||||||
register(ResourceLocation.class, ValueConversions::of);
|
register(ResourceLocation.class, (v, r) -> ValueConversions.of(v));
|
||||||
register(GlobalPos.class, ValueConversions::of);
|
register(GlobalPos.class, (v, r) -> ValueConversions.of(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Function<T, Value> converter;
|
private final BiFunction<T, RegistryAccess, Value> converter;
|
||||||
|
|
||||||
private OutputConverter(Function<T, Value> converter)
|
private OutputConverter(BiFunction<T, RegistryAccess, Value> converter)
|
||||||
{
|
{
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
}
|
}
|
||||||
@@ -91,9 +93,9 @@ public final class OutputConverter<T>
|
|||||||
* @param input The value to convert
|
* @param input The value to convert
|
||||||
* @return The converted value
|
* @return The converted value
|
||||||
*/
|
*/
|
||||||
public Value convert(@Nullable T input)
|
public Value convert(@Nullable T input, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return input == null ? Value.NULL : converter.apply(input);
|
return input == null ? Value.NULL : converter.apply(input, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,7 +106,7 @@ public final class OutputConverter<T>
|
|||||||
* @param inputType The class of T
|
* @param inputType The class of T
|
||||||
* @param converter The function that converts the instance of T to a {@link Value}
|
* @param converter The function that converts the instance of T to a {@link Value}
|
||||||
*/
|
*/
|
||||||
public static <T> void register(Class<T> inputType, Function<T, Value> converter)
|
public static <T> void register(Class<T> inputType, BiFunction<T, RegistryAccess, Value> converter)
|
||||||
{
|
{
|
||||||
OutputConverter<T> instance = new OutputConverter<>(converter);
|
OutputConverter<T> instance = new OutputConverter<>(converter);
|
||||||
if (byResult.containsKey(inputType))
|
if (byResult.containsKey(inputType))
|
||||||
@@ -113,15 +115,24 @@ public final class OutputConverter<T>
|
|||||||
}
|
}
|
||||||
byResult.put(inputType, instance);
|
byResult.put(inputType, instance);
|
||||||
}
|
}
|
||||||
|
public static <T> void register(Class<T> inputType, Function<T, Value> converter)
|
||||||
|
{
|
||||||
|
register(inputType, (v, regs) -> converter.apply(v));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #register(Class, Function)
|
* @see #register(Class, BiFunction)
|
||||||
*
|
*
|
||||||
* @deprecated Just use {@link #register(Class, Function)}, it now does the same as this
|
* @deprecated Just use {@link #register(Class, BiFunction)}, it now does the same as this
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static <T> void registerToValue(Class<T> inputType, Function<T, Value> converter)
|
public static <T> void registerToValue(Class<T> inputType, BiFunction<T, RegistryAccess, Value> converter)
|
||||||
{
|
{
|
||||||
register(inputType, converter);
|
register(inputType, converter);
|
||||||
}
|
}
|
||||||
|
@Deprecated
|
||||||
|
public static <T> void registerToValue(Class<T> inputType, Function<T, Value> converter)
|
||||||
|
{
|
||||||
|
register(inputType, (v, regs) -> converter.apply(v));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -14,8 +14,6 @@ import carpet.script.argument.FunctionArgument;
|
|||||||
import carpet.script.argument.Vector3Argument;
|
import carpet.script.argument.Vector3Argument;
|
||||||
import carpet.script.exception.ExitStatement;
|
import carpet.script.exception.ExitStatement;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.exception.ThrowStatement;
|
|
||||||
import carpet.script.exception.Throwables;
|
|
||||||
import carpet.script.external.Carpet;
|
import carpet.script.external.Carpet;
|
||||||
import carpet.script.utils.SnoopyCommandSource;
|
import carpet.script.utils.SnoopyCommandSource;
|
||||||
import carpet.script.utils.SystemInfo;
|
import carpet.script.utils.SystemInfo;
|
||||||
@@ -348,7 +346,7 @@ public class Auxiliary
|
|||||||
|
|
||||||
ShapeDispatcher.sendShape(
|
ShapeDispatcher.sendShape(
|
||||||
(playerTargets.isEmpty()) ? cc.level().players() : playerTargets,
|
(playerTargets.isEmpty()) ? cc.level().players() : playerTargets,
|
||||||
shapes
|
shapes, cc.registryAccess()
|
||||||
);
|
);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
});
|
});
|
||||||
@@ -475,7 +473,7 @@ public class Auxiliary
|
|||||||
return BooleanValue.of(NbtUtils.compareNbt(match, source, numParam == 2 || lv.get(2).getBoolean()));
|
return BooleanValue.of(NbtUtils.compareNbt(match, source, numParam == 2 || lv.get(2).getBoolean()));
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("encode_nbt", lv -> {
|
expression.addContextFunction("encode_nbt", -1, (c, t, lv) -> {
|
||||||
int argSize = lv.size();
|
int argSize = lv.size();
|
||||||
if (argSize == 0 || argSize > 2)
|
if (argSize == 0 || argSize > 2)
|
||||||
{
|
{
|
||||||
@@ -486,7 +484,7 @@ public class Auxiliary
|
|||||||
Tag tag;
|
Tag tag;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
tag = v.toTag(force);
|
tag = v.toTag(force, ((CarpetContext)c).registryAccess());
|
||||||
}
|
}
|
||||||
catch (NBTSerializableValue.IncompatibleTypeException exception)
|
catch (NBTSerializableValue.IncompatibleTypeException exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,16 +19,15 @@ import carpet.script.value.ScreenValue;
|
|||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import carpet.script.value.ValueConversions;
|
import carpet.script.value.ValueConversions;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.OptionalInt;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.minecraft.commands.arguments.item.ItemInput;
|
|
||||||
import net.minecraft.core.HolderSet;
|
import net.minecraft.core.HolderSet;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
@@ -111,7 +110,7 @@ public class Inventories
|
|||||||
type = cc.registry(Registries.RECIPE_TYPE).get(InputValidator.identifierOf(recipeType));
|
type = cc.registry(Registries.RECIPE_TYPE).get(InputValidator.identifierOf(recipeType));
|
||||||
if (type == null)
|
if (type == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown recipe type: "+recipeType);
|
throw new InternalExpressionException("Unknown recipe type: " + recipeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<Recipe<?>> recipes = Vanilla.RecipeManager_getAllMatching(cc.server().getRecipeManager(), type, InputValidator.identifierOf(recipeName), cc.registryAccess());
|
List<Recipe<?>> recipes = Vanilla.RecipeManager_getAllMatching(cc.server().getRecipeManager(), type, InputValidator.identifierOf(recipeName), cc.registryAccess());
|
||||||
@@ -125,7 +124,7 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
ItemStack result = recipe.getResultItem(regs);
|
ItemStack result = recipe.getResultItem(regs);
|
||||||
List<Value> ingredientValue = new ArrayList<>();
|
List<Value> ingredientValue = new ArrayList<>();
|
||||||
recipe.getIngredients().forEach( ingredient -> {
|
recipe.getIngredients().forEach(ingredient -> {
|
||||||
// I am flattening ingredient lists per slot.
|
// I am flattening ingredient lists per slot.
|
||||||
// consider recipe_data('wooden_sword','crafting') and ('iron_nugget', 'blasting') and notice difference
|
// consider recipe_data('wooden_sword','crafting') and ('iron_nugget', 'blasting') and notice difference
|
||||||
// in depths of lists.
|
// in depths of lists.
|
||||||
@@ -142,7 +141,7 @@ public class Inventories
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
Value recipeSpec;
|
Value recipeSpec;
|
||||||
if (recipe instanceof final ShapedRecipe shapedRecipe)
|
if (recipe instanceof ShapedRecipe shapedRecipe)
|
||||||
{
|
{
|
||||||
recipeSpec = ListValue.of(
|
recipeSpec = ListValue.of(
|
||||||
new StringValue("shaped"),
|
new StringValue("shaped"),
|
||||||
@@ -154,7 +153,7 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
recipeSpec = ListValue.of(new StringValue("shapeless"));
|
recipeSpec = ListValue.of(new StringValue("shapeless"));
|
||||||
}
|
}
|
||||||
else if (recipe instanceof final AbstractCookingRecipe abstractCookingRecipe)
|
else if (recipe instanceof AbstractCookingRecipe abstractCookingRecipe)
|
||||||
{
|
{
|
||||||
recipeSpec = ListValue.of(
|
recipeSpec = ListValue.of(
|
||||||
new StringValue("smelting"),
|
new StringValue("smelting"),
|
||||||
@@ -249,9 +248,15 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong();
|
OptionalInt count = OptionalInt.empty();
|
||||||
|
|
||||||
|
Value countVal = lv.get(inventoryLocator.offset() + 1);
|
||||||
|
if (!countVal.isNull())
|
||||||
|
{
|
||||||
|
count = OptionalInt.of((int) NumericValue.asNumber(countVal).getLong());
|
||||||
|
}
|
||||||
RegistryAccess regs = cc.registryAccess();
|
RegistryAccess regs = cc.registryAccess();
|
||||||
if (count == 0)
|
if (count.isPresent() && count.getAsInt() == 0)
|
||||||
{
|
{
|
||||||
// clear slot
|
// clear slot
|
||||||
ItemStack removedStack = inventoryLocator.inventory().removeItemNoUpdate(slot);
|
ItemStack removedStack = inventoryLocator.inventory().removeItemNoUpdate(slot);
|
||||||
@@ -262,16 +267,16 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||||
ItemStack newStack = previousStack.copy();
|
ItemStack newStack = previousStack.copy();
|
||||||
newStack.setCount(count);
|
count.ifPresent(newStack::setCount);
|
||||||
inventoryLocator.inventory().setItem(slot, newStack);
|
inventoryLocator.inventory().setItem(slot, newStack);
|
||||||
syncPlayerInventory(inventoryLocator);
|
syncPlayerInventory(inventoryLocator);
|
||||||
return ValueConversions.of(previousStack, regs);
|
return ValueConversions.of(previousStack, regs);
|
||||||
}
|
}
|
||||||
CompoundTag nbt = null; // skipping one argument
|
CompoundTag nbt = null; // skipping one argument, item name
|
||||||
if (lv.size() > inventoryLocator.offset() + 3)
|
if (lv.size() > inventoryLocator.offset() + 3)
|
||||||
{
|
{
|
||||||
Value nbtValue = lv.get(inventoryLocator.offset() + 3);
|
Value nbtValue = lv.get(inventoryLocator.offset() + 3);
|
||||||
if (nbtValue instanceof final NBTSerializableValue nbtsv)
|
if (nbtValue instanceof NBTSerializableValue nbtsv)
|
||||||
{
|
{
|
||||||
nbt = nbtsv.getCompoundTag();
|
nbt = nbtsv.getCompoundTag();
|
||||||
}
|
}
|
||||||
@@ -280,17 +285,12 @@ public class Inventories
|
|||||||
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
|
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemInput newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset() + 2).getString(), nbt, cc.registryAccess());
|
ItemStack newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset() + 2).getString(), nbt, cc.registryAccess());
|
||||||
|
count.ifPresent(newitem::setCount);
|
||||||
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||||
try
|
inventoryLocator.inventory().setItem(slot, newitem);
|
||||||
{
|
syncPlayerInventory(inventoryLocator);
|
||||||
inventoryLocator.inventory().setItem(slot, newitem.createItemStack(count, false));
|
|
||||||
syncPlayerInventory(inventoryLocator);
|
|
||||||
}
|
|
||||||
catch (CommandSyntaxException e)
|
|
||||||
{
|
|
||||||
throw new InternalExpressionException(e.getMessage());
|
|
||||||
}
|
|
||||||
return ValueConversions.of(previousStack, regs);
|
return ValueConversions.of(previousStack, regs);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
ItemInput itemArg = null;
|
ItemStack itemArg = null;
|
||||||
if (lv.size() > inventoryLocator.offset())
|
if (lv.size() > inventoryLocator.offset())
|
||||||
{
|
{
|
||||||
Value secondArg = lv.get(inventoryLocator.offset());
|
Value secondArg = lv.get(inventoryLocator.offset());
|
||||||
@@ -342,7 +342,7 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'inventory_remove' requires at least an item to be removed");
|
throw new InternalExpressionException("'inventory_remove' requires at least an item to be removed");
|
||||||
}
|
}
|
||||||
ItemInput searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset()).getString(), cc.registryAccess());
|
ItemStack searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset()).getString(), cc.registryAccess());
|
||||||
int amount = 1;
|
int amount = 1;
|
||||||
if (lv.size() > inventoryLocator.offset() + 1)
|
if (lv.size() > inventoryLocator.offset() + 1)
|
||||||
{
|
{
|
||||||
@@ -424,7 +424,7 @@ public class Inventories
|
|||||||
}
|
}
|
||||||
Object owner = inventoryLocator.owner();
|
Object owner = inventoryLocator.owner();
|
||||||
ItemEntity item;
|
ItemEntity item;
|
||||||
if (owner instanceof final Player player)
|
if (owner instanceof Player player)
|
||||||
{
|
{
|
||||||
item = player.drop(droppedStack, false, true);
|
item = player.drop(droppedStack, false, true);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
@@ -478,7 +478,7 @@ public class Inventories
|
|||||||
expression.addContextFunction("close_screen", 1, (c, t, lv) ->
|
expression.addContextFunction("close_screen", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
Value value = lv.get(0);
|
Value value = lv.get(0);
|
||||||
if (!(value instanceof final ScreenValue screenValue))
|
if (!(value instanceof ScreenValue screenValue))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'close_screen' requires a screen value as the first argument.");
|
throw new InternalExpressionException("'close_screen' requires a screen value as the first argument.");
|
||||||
}
|
}
|
||||||
@@ -496,7 +496,7 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'screen_property' requires at least a screen and a property name");
|
throw new InternalExpressionException("'screen_property' requires at least a screen and a property name");
|
||||||
}
|
}
|
||||||
if (!(lv.get(0) instanceof final ScreenValue screenValue))
|
if (!(lv.get(0) instanceof ScreenValue screenValue))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'screen_property' requires a screen value as the first argument");
|
throw new InternalExpressionException("'screen_property' requires a screen value as the first argument");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import net.minecraft.core.Holder;
|
|||||||
import net.minecraft.core.HolderSet;
|
import net.minecraft.core.HolderSet;
|
||||||
import net.minecraft.core.QuartPos;
|
import net.minecraft.core.QuartPos;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
@@ -51,6 +52,7 @@ import net.minecraft.sounds.SoundEvents;
|
|||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||||
import net.minecraft.world.level.levelgen.DensityFunctions;
|
import net.minecraft.world.level.levelgen.DensityFunctions;
|
||||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||||
@@ -121,7 +123,6 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||||
@@ -840,6 +841,7 @@ public class WorldAccess
|
|||||||
expression.addContextFunction("destroy", -1, (c, t, lv) ->
|
expression.addContextFunction("destroy", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
|
RegistryAccess regs = cc.registryAccess();
|
||||||
ServerLevel world = cc.level();
|
ServerLevel world = cc.level();
|
||||||
BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
|
BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
|
||||||
BlockState state = locator.block.getBlockState();
|
BlockState state = locator.block.getBlockState();
|
||||||
@@ -882,11 +884,14 @@ public class WorldAccess
|
|||||||
: NBTSerializableValue.parseStringOrFail(tagValue.getString()).getCompoundTag();
|
: NBTSerializableValue.parseStringOrFail(tagValue.getString()).getCompoundTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ItemStack tool;
|
||||||
ItemStack tool = new ItemStack(item, 1);
|
|
||||||
if (tag != null)
|
if (tag != null)
|
||||||
{
|
{
|
||||||
tool.setTag(tag);
|
tool = ItemStack.parseOptional(regs, tag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tool = new ItemStack(item, 1);
|
||||||
}
|
}
|
||||||
if (playerBreak && state.getDestroySpeed(world, where) < 0.0)
|
if (playerBreak && state.getDestroySpeed(world, where) < 0.0)
|
||||||
{
|
{
|
||||||
@@ -950,8 +955,7 @@ public class WorldAccess
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
Tag outtag = tool.getTag();
|
return new NBTSerializableValue(() -> tool.saveOptional(regs));
|
||||||
return outtag == null ? Value.TRUE : new NBTSerializableValue(() -> outtag);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1106,7 +1110,7 @@ public class WorldAccess
|
|||||||
CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
String itemString = lv.get(0).getString();
|
String itemString = lv.get(0).getString();
|
||||||
Vector3Argument locator = Vector3Argument.findIn(lv, 1);
|
Vector3Argument locator = Vector3Argument.findIn(lv, 1);
|
||||||
ItemInput stackArg = NBTSerializableValue.parseItem(itemString, cc.registryAccess());
|
ItemStack stackArg = NBTSerializableValue.parseItem(itemString, cc.registryAccess());
|
||||||
BlockPos where = BlockPos.containing(locator.vec);
|
BlockPos where = BlockPos.containing(locator.vec);
|
||||||
// Paintings throw an exception if their direction is vertical, therefore we change the default here
|
// Paintings throw an exception if their direction is vertical, therefore we change the default here
|
||||||
String facing = lv.size() > locator.offset
|
String facing = lv.size() > locator.offset
|
||||||
@@ -1118,15 +1122,7 @@ public class WorldAccess
|
|||||||
sneakPlace = lv.get(locator.offset + 1).getBoolean();
|
sneakPlace = lv.get(locator.offset + 1).getBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockValue.PlacementContext ctx;
|
BlockValue.PlacementContext ctx = BlockValue.PlacementContext.from(cc.level(), where, facing, sneakPlace, stackArg);
|
||||||
try
|
|
||||||
{
|
|
||||||
ctx = BlockValue.PlacementContext.from(cc.level(), where, facing, sneakPlace, stackArg.createItemStack(1, false));
|
|
||||||
}
|
|
||||||
catch (CommandSyntaxException e)
|
|
||||||
{
|
|
||||||
throw new InternalExpressionException(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(stackArg.getItem() instanceof final BlockItem blockItem))
|
if (!(stackArg.getItem() instanceof final BlockItem blockItem))
|
||||||
{
|
{
|
||||||
@@ -1160,7 +1156,7 @@ public class WorldAccess
|
|||||||
|
|
||||||
expression.addContextFunction("blocks_movement", -1, (c, t, lv) ->
|
expression.addContextFunction("blocks_movement", -1, (c, t, lv) ->
|
||||||
booleanStateTest(c, "blocks_movement", lv, (s, p) ->
|
booleanStateTest(c, "blocks_movement", lv, (s, p) ->
|
||||||
!s.isPathfindable(((CarpetContext) c).level(), p, PathComputationType.LAND)));
|
!s.isPathfindable(PathComputationType.LAND)));
|
||||||
|
|
||||||
expression.addContextFunction("block_sound", -1, (c, t, lv) ->
|
expression.addContextFunction("block_sound", -1, (c, t, lv) ->
|
||||||
stateStringQuery(c, "block_sound", lv, (s, p) ->
|
stateStringQuery(c, "block_sound", lv, (s, p) ->
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ public class ShapeDispatcher
|
|||||||
return new ShapeWithConfig(ShapeDispatcher.create(server, shapeType, params), params);
|
return new ShapeWithConfig(ShapeDispatcher.create(server, shapeType, params), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendShape(Collection<ServerPlayer> players, List<ShapeWithConfig> shapes)
|
public static void sendShape(Collection<ServerPlayer> players, List<ShapeWithConfig> shapes, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
List<ServerPlayer> clientPlayers = new ArrayList<>();
|
List<ServerPlayer> clientPlayers = new ArrayList<>();
|
||||||
List<ServerPlayer> alternativePlayers = new ArrayList<>();
|
List<ServerPlayer> alternativePlayers = new ArrayList<>();
|
||||||
@@ -158,7 +158,7 @@ public class ShapeDispatcher
|
|||||||
int tagcount = 0;
|
int tagcount = 0;
|
||||||
for (ShapeWithConfig s : shapes)
|
for (ShapeWithConfig s : shapes)
|
||||||
{
|
{
|
||||||
tag.add(ExpiringShape.toTag(s.config())); // 4000 shapes limit boxes
|
tag.add(ExpiringShape.toTag(s.config(), regs)); // 4000 shapes limit boxes
|
||||||
if (tagcount++ > 1000)
|
if (tagcount++ > 1000)
|
||||||
{
|
{
|
||||||
tagcount = 0;
|
tagcount = 0;
|
||||||
@@ -312,11 +312,11 @@ public class ShapeDispatcher
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompoundTag toTag(Map<String, Value> params)
|
public static CompoundTag toTag(Map<String, Value> params, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
params.forEach((k, v) -> {
|
params.forEach((k, v) -> {
|
||||||
Tag valTag = Param.of.get(k).toTag(v);
|
Tag valTag = Param.of.get(k).toTag(v, regs);
|
||||||
if (valTag != null)
|
if (valTag != null)
|
||||||
{
|
{
|
||||||
tag.put(k, valTag);
|
tag.put(k, valTag);
|
||||||
@@ -724,7 +724,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.item = ItemStack.of(((NBTSerializableValue) options.get("item")).getCompoundTag());
|
this.item = ItemStack.parseOptional(regs, ((NBTSerializableValue) options.get("item")).getCompoundTag());
|
||||||
}
|
}
|
||||||
blockLight = NumericValue.asNumber(options.getOrDefault("blocklight", optional.get("blocklight"))).getInt();
|
blockLight = NumericValue.asNumber(options.getOrDefault("blocklight", optional.get("blocklight"))).getInt();
|
||||||
if (blockLight > 15)
|
if (blockLight > 15)
|
||||||
@@ -1532,7 +1532,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public abstract Tag toTag(Value value); //validates value, returning null if not necessary to keep it and serialize
|
public abstract Tag toTag(Value value, final RegistryAccess regs); //validates value, returning null if not necessary to keep it and serialize
|
||||||
|
|
||||||
public abstract Value validate(Map<String, Value> options, MinecraftServer server, Value value); // makes sure the value is proper
|
public abstract Value validate(Map<String, Value> options, MinecraftServer server, Value value); // makes sure the value is proper
|
||||||
|
|
||||||
@@ -1547,9 +1547,9 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return value.toTag(true);
|
return value.toTag(true, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1589,7 +1589,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return StringTag.valueOf(value.getString());
|
return StringTag.valueOf(value.getString());
|
||||||
}
|
}
|
||||||
@@ -1621,7 +1621,7 @@ public class ShapeDispatcher
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (value instanceof final BlockValue blv)
|
if (value instanceof final BlockValue blv)
|
||||||
{
|
{
|
||||||
@@ -1661,11 +1661,11 @@ public class ShapeDispatcher
|
|||||||
public Value validate(Map<String, Value> options, MinecraftServer server, Value value)
|
public Value validate(Map<String, Value> options, MinecraftServer server, Value value)
|
||||||
{
|
{
|
||||||
ItemStack item = ValueConversions.getItemStackFromValue(value, true, server.registryAccess());
|
ItemStack item = ValueConversions.getItemStackFromValue(value, true, server.registryAccess());
|
||||||
return new NBTSerializableValue(item.save(new CompoundTag()));
|
return new NBTSerializableValue(item.save(server.registryAccess()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return ((NBTSerializableValue) value).getTag();
|
return ((NBTSerializableValue) value).getTag();
|
||||||
}
|
}
|
||||||
@@ -1710,19 +1710,19 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!(value instanceof FormattedTextValue))
|
if (!(value instanceof FormattedTextValue))
|
||||||
{
|
{
|
||||||
value = new FormattedTextValue(Component.literal(value.getString()));
|
value = new FormattedTextValue(Component.literal(value.getString()));
|
||||||
}
|
}
|
||||||
return StringTag.valueOf(((FormattedTextValue) value).serialize());
|
return StringTag.valueOf(((FormattedTextValue) value).serialize(regs));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value decode(Tag tag, Level level)
|
public Value decode(Tag tag, Level level)
|
||||||
{
|
{
|
||||||
return FormattedTextValue.deserialize(tag.getAsString());
|
return FormattedTextValue.deserialize(tag.getAsString(), level.registryAccess());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1808,7 +1808,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return ByteTag.valueOf(value.getBoolean());
|
return ByteTag.valueOf(value.getBoolean());
|
||||||
}
|
}
|
||||||
@@ -1834,7 +1834,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
||||||
}
|
}
|
||||||
@@ -1873,7 +1873,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
||||||
}
|
}
|
||||||
@@ -1894,7 +1894,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
||||||
}
|
}
|
||||||
@@ -1915,7 +1915,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
||||||
}
|
}
|
||||||
@@ -1946,7 +1946,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
||||||
}
|
}
|
||||||
@@ -2041,7 +2041,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
List<Value> lv = ((ListValue) value).getItems();
|
List<Value> lv = ((ListValue) value).getItems();
|
||||||
ListTag tag = new ListTag();
|
ListTag tag = new ListTag();
|
||||||
@@ -2092,7 +2092,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value pointsValue)
|
public Tag toTag(Value pointsValue, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
List<Value> lv = ((ListValue) pointsValue).getItems();
|
List<Value> lv = ((ListValue) pointsValue).getItems();
|
||||||
ListTag ltag = new ListTag();
|
ListTag ltag = new ListTag();
|
||||||
@@ -2124,7 +2124,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
||||||
}
|
}
|
||||||
@@ -2139,7 +2139,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value)
|
public Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ import net.minecraft.world.level.biome.BiomeManager;
|
|||||||
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
|
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
|
||||||
import net.minecraft.world.level.border.BorderChangeListener;
|
import net.minecraft.world.level.border.BorderChangeListener;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFile;
|
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||||
import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
|
import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import net.minecraft.core.Direction;
|
|||||||
import net.minecraft.core.Direction.Axis;
|
import net.minecraft.core.Direction.Axis;
|
||||||
import net.minecraft.core.GlobalPos;
|
import net.minecraft.core.GlobalPos;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.StringTag;
|
import net.minecraft.nbt.StringTag;
|
||||||
@@ -41,7 +42,6 @@ import net.minecraft.world.phys.Vec3;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
|
|
||||||
import static carpet.script.value.NBTSerializableValue.nameFromResource;
|
import static carpet.script.value.NBTSerializableValue.nameFromResource;
|
||||||
|
|
||||||
public class BlockValue extends Value
|
public class BlockValue extends Value
|
||||||
@@ -240,7 +240,7 @@ public class BlockValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package carpet.script.value;
|
|||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.ByteTag;
|
import net.minecraft.nbt.ByteTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ public class BooleanValue extends NumericValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return ByteTag.valueOf(boolValue);
|
return ByteTag.valueOf(boolValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
public Entity getEntity()
|
public Entity getEntity()
|
||||||
{
|
{
|
||||||
if (entity instanceof final ServerPlayer serverPlayer && Vanilla.ServerPlayer_isInvalidEntityObject(serverPlayer))
|
if (entity instanceof ServerPlayer serverPlayer && Vanilla.ServerPlayer_isInvalidEntityObject(serverPlayer))
|
||||||
{
|
{
|
||||||
ServerPlayer newPlayer = entity.getServer().getPlayerList().getPlayer(entity.getUUID());
|
ServerPlayer newPlayer = entity.getServer().getPlayerList().getPlayer(entity.getUUID());
|
||||||
if (newPlayer != null)
|
if (newPlayer != null)
|
||||||
@@ -144,7 +144,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
public static ServerPlayer getPlayerByValue(MinecraftServer server, Value value)
|
public static ServerPlayer getPlayerByValue(MinecraftServer server, Value value)
|
||||||
{
|
{
|
||||||
if (value instanceof final EntityValue ev && ev.getEntity() instanceof final ServerPlayer sp)
|
if (value instanceof EntityValue ev && ev.getEntity() instanceof ServerPlayer sp)
|
||||||
{
|
{
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
public static String getPlayerNameByValue(Value value)
|
public static String getPlayerNameByValue(Value value)
|
||||||
{
|
{
|
||||||
if (value instanceof final EntityValue ev && ev.getEntity() instanceof final ServerPlayer sp)
|
if (value instanceof EntityValue ev && ev.getEntity() instanceof ServerPlayer sp)
|
||||||
{
|
{
|
||||||
return sp.getScoreboardName();
|
return sp.getScoreboardName();
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,7 @@ public class EntityValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object v)
|
public boolean equals(Object v)
|
||||||
{
|
{
|
||||||
if (v instanceof final EntityValue ev)
|
if (v instanceof EntityValue ev)
|
||||||
{
|
{
|
||||||
return getEntity().getId() == ev.getEntity().getId();
|
return getEntity().getId() == ev.getEntity().getId();
|
||||||
}
|
}
|
||||||
@@ -194,7 +194,7 @@ public class EntityValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public Value in(Value v)
|
public Value in(Value v)
|
||||||
{
|
{
|
||||||
if (v instanceof final ListValue lv)
|
if (v instanceof ListValue lv)
|
||||||
{
|
{
|
||||||
List<Value> values = lv.getItems();
|
List<Value> values = lv.getItems();
|
||||||
String what = values.get(0).getString();
|
String what = values.get(0).getString();
|
||||||
@@ -478,7 +478,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("yaw", (e, a) -> new NumericValue(e.getYRot()));
|
put("yaw", (e, a) -> new NumericValue(e.getYRot()));
|
||||||
put("head_yaw", (e, a) -> e instanceof LivingEntity ? new NumericValue(e.getYHeadRot()) : Value.NULL);
|
put("head_yaw", (e, a) -> e instanceof LivingEntity ? new NumericValue(e.getYHeadRot()) : Value.NULL);
|
||||||
put("body_yaw", (e, a) -> e instanceof final LivingEntity le ? new NumericValue(le.yBodyRot) : Value.NULL);
|
put("body_yaw", (e, a) -> e instanceof LivingEntity le ? new NumericValue(le.yBodyRot) : Value.NULL);
|
||||||
|
|
||||||
put("pitch", (e, a) -> new NumericValue(e.getXRot()));
|
put("pitch", (e, a) -> new NumericValue(e.getXRot()));
|
||||||
put("look", (e, a) -> {
|
put("look", (e, a) -> {
|
||||||
@@ -500,19 +500,19 @@ public class EntityValue extends Value
|
|||||||
put("width", (e, a) -> new NumericValue(e.getDimensions(Pose.STANDING).width()));
|
put("width", (e, a) -> new NumericValue(e.getDimensions(Pose.STANDING).width()));
|
||||||
put("eye_height", (e, a) -> new NumericValue(e.getEyeHeight()));
|
put("eye_height", (e, a) -> new NumericValue(e.getEyeHeight()));
|
||||||
put("age", (e, a) -> new NumericValue(e.tickCount));
|
put("age", (e, a) -> new NumericValue(e.tickCount));
|
||||||
put("breeding_age", (e, a) -> e instanceof final AgeableMob am ? new NumericValue(am.getAge()) : Value.NULL);
|
put("breeding_age", (e, a) -> e instanceof AgeableMob am ? new NumericValue(am.getAge()) : Value.NULL);
|
||||||
put("despawn_timer", (e, a) -> e instanceof final LivingEntity le ? new NumericValue(le.getNoActionTime()) : Value.NULL);
|
put("despawn_timer", (e, a) -> e instanceof LivingEntity le ? new NumericValue(le.getNoActionTime()) : Value.NULL);
|
||||||
put("blue_skull", (e, a) -> e instanceof final WitherSkull w ? BooleanValue.of(w.isDangerous()) : Value.NULL);
|
put("blue_skull", (e, a) -> e instanceof WitherSkull w ? BooleanValue.of(w.isDangerous()) : Value.NULL);
|
||||||
put("offering_flower", (e, a) -> e instanceof final IronGolem ig ? BooleanValue.of(ig.getOfferFlowerTick() > 0) : Value.NULL);
|
put("offering_flower", (e, a) -> e instanceof IronGolem ig ? BooleanValue.of(ig.getOfferFlowerTick() > 0) : Value.NULL);
|
||||||
put("item", (e, a) -> e instanceof final ItemEntity ie ? ValueConversions.of(ie.getItem(), e.getServer().registryAccess()) : e instanceof final ItemFrame frame ? ValueConversions.of(frame.getItem(), e.getServer().registryAccess()) : Value.NULL);
|
put("item", (e, a) -> e instanceof ItemEntity ie ? ValueConversions.of(ie.getItem(), e.getServer().registryAccess()) : e instanceof ItemFrame frame ? ValueConversions.of(frame.getItem(), e.getServer().registryAccess()) : Value.NULL);
|
||||||
put("count", (e, a) -> (e instanceof final ItemEntity ie) ? new NumericValue(ie.getItem().getCount()) : Value.NULL);
|
put("count", (e, a) -> (e instanceof ItemEntity ie) ? new NumericValue(ie.getItem().getCount()) : Value.NULL);
|
||||||
put("pickup_delay", (e, a) -> (e instanceof final ItemEntity ie) ? new NumericValue(Vanilla.ItemEntity_getPickupDelay(ie)) : Value.NULL);
|
put("pickup_delay", (e, a) -> (e instanceof ItemEntity ie) ? new NumericValue(Vanilla.ItemEntity_getPickupDelay(ie)) : Value.NULL);
|
||||||
put("portal_cooldown", (e, a) -> new NumericValue(Vanilla.Entity_getPublicNetherPortalCooldown(e)));
|
put("portal_cooldown", (e, a) -> new NumericValue(Vanilla.Entity_getPublicNetherPortalCooldown(e)));
|
||||||
put("portal_timer", (e, a) -> new NumericValue(Vanilla.Entity_getPortalTimer(e)));
|
put("portal_timer", (e, a) -> new NumericValue(Vanilla.Entity_getPortalTimer(e)));
|
||||||
// ItemEntity -> despawn timer via ssGetAge
|
// ItemEntity -> despawn timer via ssGetAge
|
||||||
put("is_baby", (e, a) -> (e instanceof final LivingEntity le) ? BooleanValue.of(le.isBaby()) : Value.NULL);
|
put("is_baby", (e, a) -> (e instanceof LivingEntity le) ? BooleanValue.of(le.isBaby()) : Value.NULL);
|
||||||
put("target", (e, a) -> {
|
put("target", (e, a) -> {
|
||||||
if (e instanceof final Mob mob)
|
if (e instanceof Mob mob)
|
||||||
{
|
{
|
||||||
LivingEntity target = mob.getTarget(); // there is also getAttacking in living....
|
LivingEntity target = mob.getTarget(); // there is also getAttacking in living....
|
||||||
if (target != null)
|
if (target != null)
|
||||||
@@ -522,9 +522,9 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
});
|
});
|
||||||
put("home", (e, a) -> e instanceof final Mob mob ? (mob.getRestrictRadius() > 0) ? new BlockValue(null, (ServerLevel) e.level(), mob.getRestrictCenter()) : Value.FALSE : Value.NULL);
|
put("home", (e, a) -> e instanceof Mob mob ? (mob.getRestrictRadius() > 0) ? new BlockValue(null, (ServerLevel) e.level(), mob.getRestrictCenter()) : Value.FALSE : Value.NULL);
|
||||||
put("spawn_point", (e, a) -> {
|
put("spawn_point", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer spe)
|
if (e instanceof ServerPlayer spe)
|
||||||
{
|
{
|
||||||
if (spe.getRespawnPosition() == null)
|
if (spe.getRespawnPosition() == null)
|
||||||
{
|
{
|
||||||
@@ -543,22 +543,22 @@ public class EntityValue extends Value
|
|||||||
put("sneaking", (e, a) -> e.isShiftKeyDown() ? Value.TRUE : Value.FALSE);
|
put("sneaking", (e, a) -> e.isShiftKeyDown() ? Value.TRUE : Value.FALSE);
|
||||||
put("sprinting", (e, a) -> e.isSprinting() ? Value.TRUE : Value.FALSE);
|
put("sprinting", (e, a) -> e.isSprinting() ? Value.TRUE : Value.FALSE);
|
||||||
put("swimming", (e, a) -> e.isSwimming() ? Value.TRUE : Value.FALSE);
|
put("swimming", (e, a) -> e.isSwimming() ? Value.TRUE : Value.FALSE);
|
||||||
put("swinging", (e, a) -> e instanceof final LivingEntity le ? BooleanValue.of(le.swinging) : Value.NULL);
|
put("swinging", (e, a) -> e instanceof LivingEntity le ? BooleanValue.of(le.swinging) : Value.NULL);
|
||||||
put("air", (e, a) -> new NumericValue(e.getAirSupply()));
|
put("air", (e, a) -> new NumericValue(e.getAirSupply()));
|
||||||
put("language", (e, a) -> !(e instanceof final ServerPlayer p) ? NULL : StringValue.of(Vanilla.ServerPlayer_getLanguage(p)));
|
put("language", (e, a) -> !(e instanceof ServerPlayer p) ? NULL : StringValue.of(Vanilla.ServerPlayer_getLanguage(p)));
|
||||||
put("persistence", (e, a) -> e instanceof final Mob mob ? BooleanValue.of(mob.isPersistenceRequired()) : Value.NULL);
|
put("persistence", (e, a) -> e instanceof Mob mob ? BooleanValue.of(mob.isPersistenceRequired()) : Value.NULL);
|
||||||
put("hunger", (e, a) -> e instanceof final Player player ? new NumericValue(player.getFoodData().getFoodLevel()) : Value.NULL);
|
put("hunger", (e, a) -> e instanceof Player player ? new NumericValue(player.getFoodData().getFoodLevel()) : Value.NULL);
|
||||||
put("saturation", (e, a) -> e instanceof final Player player ? new NumericValue(player.getFoodData().getSaturationLevel()) : Value.NULL);
|
put("saturation", (e, a) -> e instanceof Player player ? new NumericValue(player.getFoodData().getSaturationLevel()) : Value.NULL);
|
||||||
put("exhaustion", (e, a) -> e instanceof final Player player ? new NumericValue(player.getFoodData().getExhaustionLevel()) : Value.NULL);
|
put("exhaustion", (e, a) -> e instanceof Player player ? new NumericValue(player.getFoodData().getExhaustionLevel()) : Value.NULL);
|
||||||
put("absorption", (e, a) -> e instanceof final Player player ? new NumericValue(player.getAbsorptionAmount()) : Value.NULL);
|
put("absorption", (e, a) -> e instanceof Player player ? new NumericValue(player.getAbsorptionAmount()) : Value.NULL);
|
||||||
put("xp", (e, a) -> e instanceof final Player player ? new NumericValue(player.totalExperience) : Value.NULL);
|
put("xp", (e, a) -> e instanceof Player player ? new NumericValue(player.totalExperience) : Value.NULL);
|
||||||
put("xp_level", (e, a) -> e instanceof final Player player ? new NumericValue(player.experienceLevel) : Value.NULL);
|
put("xp_level", (e, a) -> e instanceof Player player ? new NumericValue(player.experienceLevel) : Value.NULL);
|
||||||
put("xp_progress", (e, a) -> e instanceof final Player player ? new NumericValue(player.experienceProgress) : Value.NULL);
|
put("xp_progress", (e, a) -> e instanceof Player player ? new NumericValue(player.experienceProgress) : Value.NULL);
|
||||||
put("score", (e, a) -> e instanceof final Player player ? new NumericValue(player.getScore()) : Value.NULL);
|
put("score", (e, a) -> e instanceof Player player ? new NumericValue(player.getScore()) : Value.NULL);
|
||||||
put("jumping", (e, a) -> e instanceof final LivingEntity le ? Vanilla.LivingEntity_isJumping(le) ? Value.TRUE : Value.FALSE : Value.NULL);
|
put("jumping", (e, a) -> e instanceof LivingEntity le ? Vanilla.LivingEntity_isJumping(le) ? Value.TRUE : Value.FALSE : Value.NULL);
|
||||||
put("gamemode", (e, a) -> e instanceof final ServerPlayer sp ? new StringValue(sp.gameMode.getGameModeForPlayer().getName()) : Value.NULL);
|
put("gamemode", (e, a) -> e instanceof ServerPlayer sp ? new StringValue(sp.gameMode.getGameModeForPlayer().getName()) : Value.NULL);
|
||||||
put("path", (e, a) -> {
|
put("path", (e, a) -> {
|
||||||
if (e instanceof final Mob mob)
|
if (e instanceof Mob mob)
|
||||||
{
|
{
|
||||||
Path path = mob.getNavigation().getPath();
|
Path path = mob.getNavigation().getPath();
|
||||||
if (path == null)
|
if (path == null)
|
||||||
@@ -577,7 +577,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
if (e instanceof final LivingEntity livingEntity)
|
if (e instanceof LivingEntity livingEntity)
|
||||||
{
|
{
|
||||||
Brain<?> brain = livingEntity.getBrain();
|
Brain<?> brain = livingEntity.getBrain();
|
||||||
Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = brain.getMemories();
|
Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = brain.getMemories();
|
||||||
@@ -591,9 +591,9 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
});
|
});
|
||||||
put("gamemode_id", (e, a) -> e instanceof final ServerPlayer sp ? new NumericValue(sp.gameMode.getGameModeForPlayer().getId()) : Value.NULL);
|
put("gamemode_id", (e, a) -> e instanceof ServerPlayer sp ? new NumericValue(sp.gameMode.getGameModeForPlayer().getId()) : Value.NULL);
|
||||||
put("permission_level", (e, a) -> {
|
put("permission_level", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer spe)
|
if (e instanceof ServerPlayer spe)
|
||||||
{
|
{
|
||||||
for (int i = 4; i >= 0; i--)
|
for (int i = 4; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -609,7 +609,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("player_type", (e, a) -> {
|
put("player_type", (e, a) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
String moddedType = Carpet.isModdedPlayer(p);
|
String moddedType = Carpet.isModdedPlayer(p);
|
||||||
if (moddedType != null)
|
if (moddedType != null)
|
||||||
@@ -637,15 +637,15 @@ public class EntityValue extends Value
|
|||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
});
|
});
|
||||||
|
|
||||||
put("client_brand", (e, a) -> e instanceof final ServerPlayer sp ? StringValue.of(Carpet.getPlayerStatus(sp)) : Value.NULL);
|
put("client_brand", (e, a) -> e instanceof ServerPlayer sp ? StringValue.of(Carpet.getPlayerStatus(sp)) : Value.NULL);
|
||||||
put("team", (e, a) -> e.getTeam() == null ? Value.NULL : new StringValue(e.getTeam().getName()));
|
put("team", (e, a) -> e.getTeam() == null ? Value.NULL : new StringValue(e.getTeam().getName()));
|
||||||
put("ping", (e, a) -> e instanceof final ServerPlayer sp ? new NumericValue(sp.connection.latency()) : Value.NULL);
|
put("ping", (e, a) -> e instanceof ServerPlayer sp ? new NumericValue(sp.connection.latency()) : Value.NULL);
|
||||||
|
|
||||||
//spectating_entity
|
//spectating_entity
|
||||||
// isGlowing
|
// isGlowing
|
||||||
put("effect", (e, a) ->
|
put("effect", (e, a) ->
|
||||||
{
|
{
|
||||||
if (!(e instanceof final LivingEntity le))
|
if (!(e instanceof LivingEntity le))
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
@@ -663,7 +663,7 @@ public class EntityValue extends Value
|
|||||||
return ListValue.wrap(effects);
|
return ListValue.wrap(effects);
|
||||||
}
|
}
|
||||||
String effectName = a.getString();
|
String effectName = a.getString();
|
||||||
Holder<MobEffect> potion = BuiltInRegistries.MOB_EFFECT.getHolder(ResourceKey.create(Registries.MOB_EFFECT, InputValidator.identifierOf(effectName))).orElseThrow( () -> new InternalExpressionException("No such an effect: " + effectName));
|
Holder<MobEffect> potion = BuiltInRegistries.MOB_EFFECT.getHolder(ResourceKey.create(Registries.MOB_EFFECT, InputValidator.identifierOf(effectName))).orElseThrow(() -> new InternalExpressionException("No such an effect: " + effectName));
|
||||||
if (!le.hasEffect(potion))
|
if (!le.hasEffect(potion))
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -672,13 +672,13 @@ public class EntityValue extends Value
|
|||||||
return ListValue.of(new NumericValue(pe.getAmplifier()), new NumericValue(pe.getDuration()));
|
return ListValue.of(new NumericValue(pe.getAmplifier()), new NumericValue(pe.getDuration()));
|
||||||
});
|
});
|
||||||
|
|
||||||
put("health", (e, a) -> e instanceof final LivingEntity le ? new NumericValue(le.getHealth()) : Value.NULL);
|
put("health", (e, a) -> e instanceof LivingEntity le ? new NumericValue(le.getHealth()) : Value.NULL);
|
||||||
put("may_fly", (e, a) -> e instanceof final ServerPlayer player ? BooleanValue.of(player.getAbilities().mayfly) : Value.NULL);
|
put("may_fly", (e, a) -> e instanceof ServerPlayer player ? BooleanValue.of(player.getAbilities().mayfly) : Value.NULL);
|
||||||
put("flying", (e, v) -> e instanceof final ServerPlayer player ? BooleanValue.of(player.getAbilities().flying) : Value.NULL);
|
put("flying", (e, v) -> e instanceof ServerPlayer player ? BooleanValue.of(player.getAbilities().flying) : Value.NULL);
|
||||||
put("may_build", (e, v) -> e instanceof final ServerPlayer player ? BooleanValue.of(player.getAbilities().mayBuild) : Value.NULL);
|
put("may_build", (e, v) -> e instanceof ServerPlayer player ? BooleanValue.of(player.getAbilities().mayBuild) : Value.NULL);
|
||||||
put("insta_build", (e, v) -> e instanceof final ServerPlayer player ? BooleanValue.of(player.getAbilities().instabuild) : Value.NULL);
|
put("insta_build", (e, v) -> e instanceof ServerPlayer player ? BooleanValue.of(player.getAbilities().instabuild) : Value.NULL);
|
||||||
put("fly_speed", (e, v) -> e instanceof final ServerPlayer player ? NumericValue.of(player.getAbilities().getFlyingSpeed()) : Value.NULL);
|
put("fly_speed", (e, v) -> e instanceof ServerPlayer player ? NumericValue.of(player.getAbilities().getFlyingSpeed()) : Value.NULL);
|
||||||
put("walk_speed", (e, v) -> e instanceof final ServerPlayer player ? NumericValue.of(player.getAbilities().getWalkingSpeed()) : Value.NULL);
|
put("walk_speed", (e, v) -> e instanceof ServerPlayer player ? NumericValue.of(player.getAbilities().getWalkingSpeed()) : Value.NULL);
|
||||||
put("holds", (e, a) -> {
|
put("holds", (e, a) -> {
|
||||||
EquipmentSlot where = EquipmentSlot.MAINHAND;
|
EquipmentSlot where = EquipmentSlot.MAINHAND;
|
||||||
if (a != null)
|
if (a != null)
|
||||||
@@ -689,17 +689,17 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown inventory slot: " + a.getString());
|
throw new InternalExpressionException("Unknown inventory slot: " + a.getString());
|
||||||
}
|
}
|
||||||
if (e instanceof final LivingEntity le)
|
if (e instanceof LivingEntity le)
|
||||||
{
|
{
|
||||||
return ValueConversions.of(le.getItemBySlot(where), e.getServer().registryAccess());
|
return ValueConversions.of(le.getItemBySlot(where), e.getServer().registryAccess());
|
||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
});
|
});
|
||||||
|
|
||||||
put("selected_slot", (e, a) -> e instanceof final Player p ? new NumericValue(p.getInventory().selected) : Value.NULL);
|
put("selected_slot", (e, a) -> e instanceof Player p ? new NumericValue(p.getInventory().selected) : Value.NULL);
|
||||||
|
|
||||||
put("active_block", (e, a) -> {
|
put("active_block", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer sp)
|
if (e instanceof ServerPlayer sp)
|
||||||
{
|
{
|
||||||
BlockPos pos = Vanilla.ServerPlayerGameMode_getCurrentBlockPosition(sp.gameMode);
|
BlockPos pos = Vanilla.ServerPlayerGameMode_getCurrentBlockPosition(sp.gameMode);
|
||||||
if (pos == null)
|
if (pos == null)
|
||||||
@@ -712,9 +712,9 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("breaking_progress", (e, a) -> {
|
put("breaking_progress", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer sp)
|
if (e instanceof ServerPlayer sp)
|
||||||
{
|
{
|
||||||
int progress = Vanilla.ServerPlayerGameMode_getCurrentBlockBreakingProgress (sp.gameMode);
|
int progress = Vanilla.ServerPlayerGameMode_getCurrentBlockBreakingProgress(sp.gameMode);
|
||||||
return progress < 0 ? Value.NULL : new NumericValue(progress);
|
return progress < 0 ? Value.NULL : new NumericValue(progress);
|
||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -745,7 +745,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
if (a != null)
|
if (a != null)
|
||||||
{
|
{
|
||||||
if (!(a instanceof final ListValue lv))
|
if (!(a instanceof ListValue lv))
|
||||||
{
|
{
|
||||||
reach = (float) NumericValue.asNumber(a).getDouble();
|
reach = (float) NumericValue.asNumber(a).getDouble();
|
||||||
}
|
}
|
||||||
@@ -789,7 +789,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (e instanceof final ServerPlayer sp && sp.gameMode.isCreative())
|
else if (e instanceof ServerPlayer sp && sp.gameMode.isCreative())
|
||||||
{
|
{
|
||||||
reach = 5.0f;
|
reach = 5.0f;
|
||||||
}
|
}
|
||||||
@@ -829,7 +829,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("attribute", (e, a) -> {
|
put("attribute", (e, a) -> {
|
||||||
if (!(e instanceof final LivingEntity el))
|
if (!(e instanceof LivingEntity el))
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
@@ -896,7 +896,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e instanceof final ServerPlayer sp)
|
if (e instanceof ServerPlayer sp)
|
||||||
{
|
{
|
||||||
// this forces position but doesn't angles for some reason. Need both in the API in the future.
|
// this forces position but doesn't angles for some reason. Need both in the API in the future.
|
||||||
EnumSet<RelativeMovement> set = EnumSet.noneOf(RelativeMovement.class);
|
EnumSet<RelativeMovement> set = EnumSet.noneOf(RelativeMovement.class);
|
||||||
@@ -909,7 +909,7 @@ public class EntityValue extends Value
|
|||||||
e.moveTo(x, y, z, yaw, pitch);
|
e.moveTo(x, y, z, yaw, pitch);
|
||||||
// we were sending to players for not-living entites, that were untracked. Living entities should be tracked.
|
// we were sending to players for not-living entites, that were untracked. Living entities should be tracked.
|
||||||
//((ServerWorld) e.getEntityWorld()).getChunkManager().sendToNearbyPlayers(e, new EntityS2CPacket.(e));
|
//((ServerWorld) e.getEntityWorld()).getChunkManager().sendToNearbyPlayers(e, new EntityS2CPacket.(e));
|
||||||
if (e instanceof final LivingEntity le)
|
if (e instanceof LivingEntity le)
|
||||||
{
|
{
|
||||||
le.yBodyRotO = le.yRotO = yaw;
|
le.yBodyRotO = le.yRotO = yaw;
|
||||||
le.yHeadRotO = le.yHeadRot = yaw;
|
le.yHeadRotO = le.yHeadRot = yaw;
|
||||||
@@ -939,7 +939,7 @@ public class EntityValue extends Value
|
|||||||
put("age", (e, v) -> e.tickCount = Math.abs((int) NumericValue.asNumber(v).getLong()));
|
put("age", (e, v) -> e.tickCount = Math.abs((int) NumericValue.asNumber(v).getLong()));
|
||||||
put("health", (e, v) -> {
|
put("health", (e, v) -> {
|
||||||
float health = (float) NumericValue.asNumber(v).getDouble();
|
float health = (float) NumericValue.asNumber(v).getDouble();
|
||||||
if (health <= 0f && e instanceof final ServerPlayer player)
|
if (health <= 0f && e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
if (player.containerMenu != null)
|
if (player.containerMenu != null)
|
||||||
{
|
{
|
||||||
@@ -950,7 +950,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
((LivingEntity) e).setHealth(health);
|
((LivingEntity) e).setHealth(health);
|
||||||
}
|
}
|
||||||
if (e instanceof final LivingEntity le)
|
if (e instanceof LivingEntity le)
|
||||||
{
|
{
|
||||||
le.setHealth(health);
|
le.setHealth(health);
|
||||||
}
|
}
|
||||||
@@ -958,7 +958,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("may_fly", (e, v) -> {
|
put("may_fly", (e, v) -> {
|
||||||
boolean mayFly = v.getBoolean();
|
boolean mayFly = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().mayfly = mayFly;
|
player.getAbilities().mayfly = mayFly;
|
||||||
if (!mayFly && player.getAbilities().flying)
|
if (!mayFly && player.getAbilities().flying)
|
||||||
@@ -971,7 +971,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("flying", (e, v) -> {
|
put("flying", (e, v) -> {
|
||||||
boolean flying = v.getBoolean();
|
boolean flying = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().flying = flying;
|
player.getAbilities().flying = flying;
|
||||||
player.onUpdateAbilities();
|
player.onUpdateAbilities();
|
||||||
@@ -980,7 +980,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("may_build", (e, v) -> {
|
put("may_build", (e, v) -> {
|
||||||
boolean mayBuild = v.getBoolean();
|
boolean mayBuild = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().mayBuild = mayBuild;
|
player.getAbilities().mayBuild = mayBuild;
|
||||||
player.onUpdateAbilities();
|
player.onUpdateAbilities();
|
||||||
@@ -989,7 +989,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("insta_build", (e, v) -> {
|
put("insta_build", (e, v) -> {
|
||||||
boolean instaBuild = v.getBoolean();
|
boolean instaBuild = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().instabuild = instaBuild;
|
player.getAbilities().instabuild = instaBuild;
|
||||||
player.onUpdateAbilities();
|
player.onUpdateAbilities();
|
||||||
@@ -998,7 +998,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("fly_speed", (e, v) -> {
|
put("fly_speed", (e, v) -> {
|
||||||
float flySpeed = NumericValue.asNumber(v).getFloat();
|
float flySpeed = NumericValue.asNumber(v).getFloat();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().setFlyingSpeed(flySpeed);
|
player.getAbilities().setFlyingSpeed(flySpeed);
|
||||||
player.onUpdateAbilities();
|
player.onUpdateAbilities();
|
||||||
@@ -1007,7 +1007,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("walk_speed", (e, v) -> {
|
put("walk_speed", (e, v) -> {
|
||||||
float walkSpeed = NumericValue.asNumber(v).getFloat();
|
float walkSpeed = NumericValue.asNumber(v).getFloat();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().setWalkingSpeed(walkSpeed);
|
player.getAbilities().setWalkingSpeed(walkSpeed);
|
||||||
player.onUpdateAbilities();
|
player.onUpdateAbilities();
|
||||||
@@ -1016,7 +1016,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("selected_slot", (e, v) ->
|
put("selected_slot", (e, v) ->
|
||||||
{
|
{
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
int slot = NumericValue.asNumber(v).getInt();
|
int slot = NumericValue.asNumber(v).getInt();
|
||||||
player.connection.send(new ClientboundSetCarriedItemPacket(slot));
|
player.connection.send(new ClientboundSetCarriedItemPacket(slot));
|
||||||
@@ -1041,7 +1041,7 @@ public class EntityValue extends Value
|
|||||||
put("kill", (e, v) -> e.kill());
|
put("kill", (e, v) -> e.kill());
|
||||||
put("location", (e, v) ->
|
put("location", (e, v) ->
|
||||||
{
|
{
|
||||||
if (!(v instanceof final ListValue lv))
|
if (!(v instanceof ListValue lv))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Expected a list of 5 parameters as a second argument");
|
throw new InternalExpressionException("Expected a list of 5 parameters as a second argument");
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1056,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
put("pos", (e, v) ->
|
put("pos", (e, v) ->
|
||||||
{
|
{
|
||||||
if (!(v instanceof final ListValue lv))
|
if (!(v instanceof ListValue lv))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||||
}
|
}
|
||||||
@@ -1091,7 +1091,7 @@ public class EntityValue extends Value
|
|||||||
put("pitch", (e, v) -> updatePosition(e, e.getX(), e.getY(), e.getZ(), e.getYRot(), Mth.clamp((float) NumericValue.asNumber(v).getDouble(), -90, 90)));
|
put("pitch", (e, v) -> updatePosition(e, e.getX(), e.getY(), e.getZ(), e.getYRot(), Mth.clamp((float) NumericValue.asNumber(v).getDouble(), -90, 90)));
|
||||||
|
|
||||||
put("look", (e, v) -> {
|
put("look", (e, v) -> {
|
||||||
if (!(v instanceof final ListValue lv))
|
if (!(v instanceof ListValue lv))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||||
}
|
}
|
||||||
@@ -1117,7 +1117,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("move", (e, v) ->
|
put("move", (e, v) ->
|
||||||
{
|
{
|
||||||
if (!(v instanceof final ListValue lv))
|
if (!(v instanceof ListValue lv))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||||
}
|
}
|
||||||
@@ -1133,7 +1133,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("motion", (e, v) ->
|
put("motion", (e, v) ->
|
||||||
{
|
{
|
||||||
if (!(v instanceof final ListValue lv))
|
if (!(v instanceof ListValue lv))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||||
}
|
}
|
||||||
@@ -1168,7 +1168,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("accelerate", (e, v) ->
|
put("accelerate", (e, v) ->
|
||||||
{
|
{
|
||||||
if (!(v instanceof final ListValue lv))
|
if (!(v instanceof ListValue lv))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||||
}
|
}
|
||||||
@@ -1189,7 +1189,7 @@ public class EntityValue extends Value
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean showName = false;
|
boolean showName = false;
|
||||||
if (v instanceof final ListValue lv)
|
if (v instanceof ListValue lv)
|
||||||
{
|
{
|
||||||
showName = lv.getItems().get(1).getBoolean();
|
showName = lv.getItems().get(1).getBoolean();
|
||||||
v = lv.getItems().get(0);
|
v = lv.getItems().get(0);
|
||||||
@@ -1200,7 +1200,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("persistence", (e, v) ->
|
put("persistence", (e, v) ->
|
||||||
{
|
{
|
||||||
if (!(e instanceof final Mob mob))
|
if (!(e instanceof Mob mob))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1213,11 +1213,11 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("dismount", (e, v) -> e.stopRiding());
|
put("dismount", (e, v) -> e.stopRiding());
|
||||||
put("mount", (e, v) -> {
|
put("mount", (e, v) -> {
|
||||||
if (v instanceof final EntityValue ev)
|
if (v instanceof EntityValue ev)
|
||||||
{
|
{
|
||||||
e.startRiding(ev.getEntity(), true);
|
e.startRiding(ev.getEntity(), true);
|
||||||
}
|
}
|
||||||
if (e instanceof final ServerPlayer sp)
|
if (e instanceof ServerPlayer sp)
|
||||||
{
|
{
|
||||||
sp.connection.send(new ClientboundSetPassengersPacket(e));
|
sp.connection.send(new ClientboundSetPassengersPacket(e));
|
||||||
}
|
}
|
||||||
@@ -1229,15 +1229,15 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'mount_passengers' needs entities to ride");
|
throw new InternalExpressionException("'mount_passengers' needs entities to ride");
|
||||||
}
|
}
|
||||||
if (v instanceof final EntityValue ev)
|
if (v instanceof EntityValue ev)
|
||||||
{
|
{
|
||||||
ev.getEntity().startRiding(e);
|
ev.getEntity().startRiding(e);
|
||||||
}
|
}
|
||||||
else if (v instanceof final ListValue lv)
|
else if (v instanceof ListValue lv)
|
||||||
{
|
{
|
||||||
for (Value element : lv.getItems())
|
for (Value element : lv.getItems())
|
||||||
{
|
{
|
||||||
if (element instanceof final EntityValue ev)
|
if (element instanceof EntityValue ev)
|
||||||
{
|
{
|
||||||
ev.getEntity().startRiding(e);
|
ev.getEntity().startRiding(e);
|
||||||
}
|
}
|
||||||
@@ -1249,7 +1249,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'tag' requires parameters");
|
throw new InternalExpressionException("'tag' requires parameters");
|
||||||
}
|
}
|
||||||
if (v instanceof final ListValue lv)
|
if (v instanceof ListValue lv)
|
||||||
{
|
{
|
||||||
for (Value element : lv.getItems())
|
for (Value element : lv.getItems())
|
||||||
{
|
{
|
||||||
@@ -1266,7 +1266,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'clear_tag' requires parameters");
|
throw new InternalExpressionException("'clear_tag' requires parameters");
|
||||||
}
|
}
|
||||||
if (v instanceof final ListValue lv)
|
if (v instanceof ListValue lv)
|
||||||
{
|
{
|
||||||
for (Value element : lv.getItems())
|
for (Value element : lv.getItems())
|
||||||
{
|
{
|
||||||
@@ -1288,20 +1288,20 @@ public class EntityValue extends Value
|
|||||||
//});
|
//});
|
||||||
put("breeding_age", (e, v) ->
|
put("breeding_age", (e, v) ->
|
||||||
{
|
{
|
||||||
if (e instanceof final AgeableMob am)
|
if (e instanceof AgeableMob am)
|
||||||
{
|
{
|
||||||
am.setAge((int) NumericValue.asNumber(v).getLong());
|
am.setAge((int) NumericValue.asNumber(v).getLong());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
put("talk", (e, v) -> {
|
put("talk", (e, v) -> {
|
||||||
// attacks indefinitely
|
// attacks indefinitely
|
||||||
if (e instanceof final Mob mob)
|
if (e instanceof Mob mob)
|
||||||
{
|
{
|
||||||
mob.playAmbientSound();
|
mob.playAmbientSound();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
put("home", (e, v) -> {
|
put("home", (e, v) -> {
|
||||||
if (!(e instanceof final PathfinderMob ec))
|
if (!(e instanceof PathfinderMob ec))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1321,7 +1321,7 @@ public class EntityValue extends Value
|
|||||||
BlockPos pos;
|
BlockPos pos;
|
||||||
int distance = 16;
|
int distance = 16;
|
||||||
|
|
||||||
if (v instanceof final BlockValue bv)
|
if (v instanceof BlockValue bv)
|
||||||
{
|
{
|
||||||
pos = bv.getPos();
|
pos = bv.getPos();
|
||||||
if (pos == null)
|
if (pos == null)
|
||||||
@@ -1329,7 +1329,7 @@ public class EntityValue extends Value
|
|||||||
throw new InternalExpressionException("Block is not positioned in the world");
|
throw new InternalExpressionException("Block is not positioned in the world");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (v instanceof final ListValue lv)
|
else if (v instanceof ListValue lv)
|
||||||
{
|
{
|
||||||
List<Value> list = lv.getItems();
|
List<Value> list = lv.getItems();
|
||||||
Vector3Argument locator = Vector3Argument.findIn(list, 0, false, false);
|
Vector3Argument locator = Vector3Argument.findIn(list, 0, false, false);
|
||||||
@@ -1355,7 +1355,7 @@ public class EntityValue extends Value
|
|||||||
}); //requires mixing
|
}); //requires mixing
|
||||||
|
|
||||||
put("spawn_point", (e, a) -> {
|
put("spawn_point", (e, a) -> {
|
||||||
if (!(e instanceof final ServerPlayer spe))
|
if (!(e instanceof ServerPlayer spe))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1363,7 +1363,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
spe.setRespawnPosition(null, null, 0, false, false);
|
spe.setRespawnPosition(null, null, 0, false, false);
|
||||||
}
|
}
|
||||||
else if (a instanceof final ListValue lv)
|
else if (a instanceof ListValue lv)
|
||||||
{
|
{
|
||||||
List<Value> params = lv.getItems();
|
List<Value> params = lv.getItems();
|
||||||
Vector3Argument blockLocator = Vector3Argument.findIn(params, 0, false, false);
|
Vector3Argument blockLocator = Vector3Argument.findIn(params, 0, false, false);
|
||||||
@@ -1373,7 +1373,7 @@ public class EntityValue extends Value
|
|||||||
boolean forced = false;
|
boolean forced = false;
|
||||||
if (params.size() > blockLocator.offset)
|
if (params.size() > blockLocator.offset)
|
||||||
{
|
{
|
||||||
Value worldValue = params.get(blockLocator.offset + 0);
|
Value worldValue = params.get(blockLocator.offset);
|
||||||
world = ValueConversions.dimFromValue(worldValue, spe.getServer()).dimension();
|
world = ValueConversions.dimFromValue(worldValue, spe.getServer()).dimension();
|
||||||
if (params.size() > blockLocator.offset + 1)
|
if (params.size() > blockLocator.offset + 1)
|
||||||
{
|
{
|
||||||
@@ -1386,7 +1386,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
spe.setRespawnPosition(world, pos, angle, forced, false);
|
spe.setRespawnPosition(world, pos, angle, forced, false);
|
||||||
}
|
}
|
||||||
else if (a instanceof final BlockValue bv)
|
else if (a instanceof BlockValue bv)
|
||||||
{
|
{
|
||||||
if (bv.getPos() == null || bv.getWorld() == null)
|
if (bv.getPos() == null || bv.getWorld() == null)
|
||||||
{
|
{
|
||||||
@@ -1406,7 +1406,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("pickup_delay", (e, v) ->
|
put("pickup_delay", (e, v) ->
|
||||||
{
|
{
|
||||||
if (e instanceof final ItemEntity ie)
|
if (e instanceof ItemEntity ie)
|
||||||
{
|
{
|
||||||
ie.setPickUpDelay((int) NumericValue.asNumber(v).getLong());
|
ie.setPickUpDelay((int) NumericValue.asNumber(v).getLong());
|
||||||
}
|
}
|
||||||
@@ -1414,7 +1414,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("despawn_timer", (e, v) ->
|
put("despawn_timer", (e, v) ->
|
||||||
{
|
{
|
||||||
if (e instanceof final LivingEntity le)
|
if (e instanceof LivingEntity le)
|
||||||
{
|
{
|
||||||
le.setNoActionTime((int) NumericValue.asNumber(v).getLong());
|
le.setNoActionTime((int) NumericValue.asNumber(v).getLong());
|
||||||
}
|
}
|
||||||
@@ -1440,7 +1440,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("ai", (e, v) ->
|
put("ai", (e, v) ->
|
||||||
{
|
{
|
||||||
if (e instanceof final Mob mob)
|
if (e instanceof Mob mob)
|
||||||
{
|
{
|
||||||
mob.setNoAi(!v.getBoolean());
|
mob.setNoAi(!v.getBoolean());
|
||||||
}
|
}
|
||||||
@@ -1459,7 +1459,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
put("effect", (e, v) ->
|
put("effect", (e, v) ->
|
||||||
{
|
{
|
||||||
if (!(e instanceof final LivingEntity le))
|
if (!(e instanceof LivingEntity le))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1468,13 +1468,13 @@ public class EntityValue extends Value
|
|||||||
le.removeAllEffects();
|
le.removeAllEffects();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (v instanceof final ListValue lv)
|
else if (v instanceof ListValue lv)
|
||||||
{
|
{
|
||||||
List<Value> list = lv.getItems();
|
List<Value> list = lv.getItems();
|
||||||
if (list.size() >= 1 && list.size() <= 6)
|
if (list.size() >= 1 && list.size() <= 6)
|
||||||
{
|
{
|
||||||
String effectName = list.get(0).getString();
|
String effectName = list.get(0).getString();
|
||||||
Holder<MobEffect> effect = BuiltInRegistries.MOB_EFFECT.getHolder(InputValidator.identifierOf(effectName)).orElseThrow( () -> new InternalExpressionException("No such an effect: " + effectName));
|
Holder<MobEffect> effect = BuiltInRegistries.MOB_EFFECT.getHolder(InputValidator.identifierOf(effectName)).orElseThrow(() -> new InternalExpressionException("No such an effect: " + effectName));
|
||||||
if (list.size() == 1)
|
if (list.size() == 1)
|
||||||
{
|
{
|
||||||
le.removeEffect(effect);
|
le.removeEffect(effect);
|
||||||
@@ -1486,7 +1486,8 @@ public class EntityValue extends Value
|
|||||||
le.removeEffect(effect);
|
le.removeEffect(effect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (duration < 0){
|
if (duration < 0)
|
||||||
|
{
|
||||||
duration = -1;
|
duration = -1;
|
||||||
}
|
}
|
||||||
int amplifier = 0;
|
int amplifier = 0;
|
||||||
@@ -1516,7 +1517,7 @@ public class EntityValue extends Value
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
String effectName = v.getString();
|
String effectName = v.getString();
|
||||||
Holder<MobEffect> effect = BuiltInRegistries.MOB_EFFECT.getHolder(InputValidator.identifierOf(effectName)).orElseThrow( () -> new InternalExpressionException("No such an effect: " + effectName));
|
Holder<MobEffect> effect = BuiltInRegistries.MOB_EFFECT.getHolder(InputValidator.identifierOf(effectName)).orElseThrow(() -> new InternalExpressionException("No such an effect: " + effectName));
|
||||||
le.removeEffect(effect);
|
le.removeEffect(effect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1524,7 +1525,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("gamemode", (e, v) -> {
|
put("gamemode", (e, v) -> {
|
||||||
if (!(e instanceof final ServerPlayer sp))
|
if (!(e instanceof ServerPlayer sp))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1538,7 +1539,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("jumping", (e, v) -> {
|
put("jumping", (e, v) -> {
|
||||||
if (!(e instanceof final LivingEntity le))
|
if (!(e instanceof LivingEntity le))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1546,7 +1547,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("jump", (e, v) -> {
|
put("jump", (e, v) -> {
|
||||||
if (e instanceof final LivingEntity le)
|
if (e instanceof LivingEntity le)
|
||||||
{
|
{
|
||||||
Vanilla.LivingEntity_setJumping(le);
|
Vanilla.LivingEntity_setJumping(le);
|
||||||
}
|
}
|
||||||
@@ -1557,7 +1558,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("swing", (e, v) -> {
|
put("swing", (e, v) -> {
|
||||||
if (e instanceof final LivingEntity le)
|
if (e instanceof LivingEntity le)
|
||||||
{
|
{
|
||||||
InteractionHand hand = InteractionHand.MAIN_HAND;
|
InteractionHand hand = InteractionHand.MAIN_HAND;
|
||||||
if (v != null)
|
if (v != null)
|
||||||
@@ -1578,7 +1579,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
put("invulnerable", (e, v) -> {
|
put("invulnerable", (e, v) -> {
|
||||||
boolean invulnerable = v.getBoolean();
|
boolean invulnerable = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().invulnerable = invulnerable;
|
player.getAbilities().invulnerable = invulnerable;
|
||||||
player.onUpdateAbilities();
|
player.onUpdateAbilities();
|
||||||
@@ -1593,49 +1594,49 @@ public class EntityValue extends Value
|
|||||||
put("frost", (e, v) -> e.setTicksFrozen((int) NumericValue.asNumber(v).getLong()));
|
put("frost", (e, v) -> e.setTicksFrozen((int) NumericValue.asNumber(v).getLong()));
|
||||||
|
|
||||||
put("hunger", (e, v) -> {
|
put("hunger", (e, v) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
p.getFoodData().setFoodLevel((int) NumericValue.asNumber(v).getLong());
|
p.getFoodData().setFoodLevel((int) NumericValue.asNumber(v).getLong());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
put("exhaustion", (e, v) -> {
|
put("exhaustion", (e, v) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
p.getFoodData().setExhaustion(NumericValue.asNumber(v).getFloat());
|
p.getFoodData().setExhaustion(NumericValue.asNumber(v).getFloat());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
put("add_exhaustion", (e, v) -> {
|
put("add_exhaustion", (e, v) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
p.getFoodData().addExhaustion(NumericValue.asNumber(v).getFloat());
|
p.getFoodData().addExhaustion(NumericValue.asNumber(v).getFloat());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
put("absorption", (e, v) -> {
|
put("absorption", (e, v) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
p.setAbsorptionAmount(NumericValue.asNumber(v, "absorbtion").getFloat());
|
p.setAbsorptionAmount(NumericValue.asNumber(v, "absorbtion").getFloat());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
put("add_xp", (e, v) -> {
|
put("add_xp", (e, v) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
p.giveExperiencePoints(NumericValue.asNumber(v, "add_xp").getInt());
|
p.giveExperiencePoints(NumericValue.asNumber(v, "add_xp").getInt());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
put("xp_level", (e, v) -> {
|
put("xp_level", (e, v) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
p.giveExperienceLevels(NumericValue.asNumber(v, "xp_level").getInt() - p.experienceLevel);
|
p.giveExperienceLevels(NumericValue.asNumber(v, "xp_level").getInt() - p.experienceLevel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
put("xp_progress", (e, v) -> {
|
put("xp_progress", (e, v) -> {
|
||||||
if (e instanceof final ServerPlayer p)
|
if (e instanceof ServerPlayer p)
|
||||||
{
|
{
|
||||||
p.experienceProgress = NumericValue.asNumber(v, "xp_progress").getFloat();
|
p.experienceProgress = NumericValue.asNumber(v, "xp_progress").getFloat();
|
||||||
p.connection.send(new ClientboundSetExperiencePacket(p.experienceProgress, p.totalExperience, p.experienceLevel));
|
p.connection.send(new ClientboundSetExperiencePacket(p.experienceProgress, p.totalExperience, p.experienceLevel));
|
||||||
@@ -1643,14 +1644,14 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("xp_score", (e, v) -> {
|
put("xp_score", (e, v) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
p.setScore(NumericValue.asNumber(v, "xp_score").getInt());
|
p.setScore(NumericValue.asNumber(v, "xp_score").getInt());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
put("saturation", (e, v) -> {
|
put("saturation", (e, v) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof Player p)
|
||||||
{
|
{
|
||||||
p.getFoodData().setSaturation(NumericValue.asNumber(v, "saturation").getFloat());
|
p.getFoodData().setSaturation(NumericValue.asNumber(v, "saturation").getFloat());
|
||||||
}
|
}
|
||||||
@@ -1659,7 +1660,7 @@ public class EntityValue extends Value
|
|||||||
put("air", (e, v) -> e.setAirSupply(NumericValue.asNumber(v, "air").getInt()));
|
put("air", (e, v) -> e.setAirSupply(NumericValue.asNumber(v, "air").getInt()));
|
||||||
|
|
||||||
put("breaking_progress", (e, a) -> {
|
put("breaking_progress", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer sp)
|
if (e instanceof ServerPlayer sp)
|
||||||
{
|
{
|
||||||
int progress = (a == null || a.isNull()) ? -1 : NumericValue.asNumber(a).getInt();
|
int progress = (a == null || a.isNull()) ? -1 : NumericValue.asNumber(a).getInt();
|
||||||
Vanilla.ServerPlayerGameMode_setBlockBreakingProgress(sp.gameMode, progress);
|
Vanilla.ServerPlayerGameMode_setBlockBreakingProgress(sp.gameMode, progress);
|
||||||
@@ -1671,7 +1672,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
UUID uUID = e.getUUID();
|
UUID uUID = e.getUUID();
|
||||||
Value tagValue = NBTSerializableValue.fromValue(v);
|
Value tagValue = NBTSerializableValue.fromValue(v);
|
||||||
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
if (tagValue instanceof NBTSerializableValue nbtsv)
|
||||||
{
|
{
|
||||||
e.load(nbtsv.getCompoundTag());
|
e.load(nbtsv.getCompoundTag());
|
||||||
e.setUUID(uUID);
|
e.setUUID(uUID);
|
||||||
@@ -1683,7 +1684,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
UUID uUID = e.getUUID();
|
UUID uUID = e.getUUID();
|
||||||
Value tagValue = NBTSerializableValue.fromValue(v);
|
Value tagValue = NBTSerializableValue.fromValue(v);
|
||||||
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
if (tagValue instanceof NBTSerializableValue nbtsv)
|
||||||
{
|
{
|
||||||
CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
||||||
nbttagcompound.merge(nbtsv.getCompoundTag());
|
nbttagcompound.merge(nbtsv.getCompoundTag());
|
||||||
@@ -1694,14 +1695,14 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("blue_skull", (e, v) -> {
|
put("blue_skull", (e, v) -> {
|
||||||
if (e instanceof final WitherSkull w)
|
if (e instanceof WitherSkull w)
|
||||||
{
|
{
|
||||||
w.setDangerous(v.getBoolean());
|
w.setDangerous(v.getBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
put("offering_flower", (e, v) -> {
|
put("offering_flower", (e, v) -> {
|
||||||
if (e instanceof final IronGolem ig)
|
if (e instanceof IronGolem ig)
|
||||||
{
|
{
|
||||||
ig.offerFlower(v.getBoolean());
|
ig.offerFlower(v.getBoolean());
|
||||||
}
|
}
|
||||||
@@ -1709,11 +1710,11 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
put("item", (e, v) -> {
|
put("item", (e, v) -> {
|
||||||
ItemStack item = ValueConversions.getItemStackFromValue(v, true, e.level().registryAccess());
|
ItemStack item = ValueConversions.getItemStackFromValue(v, true, e.level().registryAccess());
|
||||||
if (e instanceof final ItemEntity itementity)
|
if (e instanceof ItemEntity itementity)
|
||||||
{
|
{
|
||||||
itementity.setItem(item);
|
itementity.setItem(item);
|
||||||
}
|
}
|
||||||
if (e instanceof final ItemFrame itemframe)
|
if (e instanceof ItemFrame itemframe)
|
||||||
{
|
{
|
||||||
itemframe.setItem(item);
|
itemframe.setItem(item);
|
||||||
}
|
}
|
||||||
@@ -1734,7 +1735,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public net.minecraft.nbt.Tag toTag(boolean force)
|
public net.minecraft.nbt.Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.StringTag;
|
import net.minecraft.nbt.StringTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
@@ -19,7 +19,7 @@ public class FormattedTextValue extends StringValue
|
|||||||
public static Value combine(Value left, Value right)
|
public static Value combine(Value left, Value right)
|
||||||
{
|
{
|
||||||
MutableComponent text;
|
MutableComponent text;
|
||||||
if (left instanceof final FormattedTextValue ftv)
|
if (left instanceof FormattedTextValue ftv)
|
||||||
{
|
{
|
||||||
text = ftv.getText().copy();
|
text = ftv.getText().copy();
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ public class FormattedTextValue extends StringValue
|
|||||||
text = Component.literal(left.getString());
|
text = Component.literal(left.getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right instanceof final FormattedTextValue ftv)
|
if (right instanceof FormattedTextValue ftv)
|
||||||
{
|
{
|
||||||
text.append(ftv.getText().copy());
|
text.append(ftv.getText().copy());
|
||||||
return new FormattedTextValue(text);
|
return new FormattedTextValue(text);
|
||||||
@@ -80,19 +80,13 @@ public class FormattedTextValue extends StringValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||||
}
|
}
|
||||||
return StringTag.valueOf(Component.Serializer.toJson(text));
|
return StringTag.valueOf(Component.Serializer.toJson(text, regs));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement toJson()
|
|
||||||
{
|
|
||||||
return Component.Serializer.toJsonTree(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -101,19 +95,19 @@ public class FormattedTextValue extends StringValue
|
|||||||
return combine(this, o);
|
return combine(this, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String serialize()
|
public String serialize(RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return Component.Serializer.toJson(text);
|
return Component.Serializer.toJson(text, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FormattedTextValue deserialize(String serialized)
|
public static FormattedTextValue deserialize(String serialized, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return new FormattedTextValue(Component.Serializer.fromJson(serialized));
|
return new FormattedTextValue(Component.Serializer.fromJson(serialized, regs));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Component getTextByValue(Value value)
|
public static Component getTextByValue(Value value)
|
||||||
{
|
{
|
||||||
return (value instanceof final FormattedTextValue ftv) ? ftv.getText() : Component.literal(value.getString());
|
return (value instanceof FormattedTextValue ftv) ? ftv.getText() : Component.literal(value.getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
public abstract class FrameworkValue extends Value
|
public abstract class FrameworkValue extends Value
|
||||||
@@ -29,7 +30,7 @@ public abstract class FrameworkValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("Scarpet language component cannot be serialized to the tag");
|
throw new UnsupportedOperationException("Scarpet language component cannot be serialized to the tag");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
public class FunctionAnnotationValue extends Value
|
public class FunctionAnnotationValue extends Value
|
||||||
@@ -41,7 +42,7 @@ public class FunctionAnnotationValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("Global value cannot be serialized to the tag");
|
throw new UnsupportedOperationException("Global value cannot be serialized to the tag");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.StringTag;
|
import net.minecraft.nbt.StringTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
@@ -112,13 +113,13 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
return o instanceof final FunctionValue fv && name.equals(fv.name) && variant == fv.variant;
|
return o instanceof FunctionValue fv && name.equals(fv.name) && variant == fv.variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Value o)
|
public int compareTo(Value o)
|
||||||
{
|
{
|
||||||
if (o instanceof final FunctionValue fv)
|
if (o instanceof FunctionValue fv)
|
||||||
{
|
{
|
||||||
int nameSame = this.name.compareTo(fv.name);
|
int nameSame = this.name.compareTo(fv.name);
|
||||||
return nameSame != 0 ? nameSame : (int) (variant - fv.variant);
|
return nameSame != 0 ? nameSame : (int) (variant - fv.variant);
|
||||||
@@ -303,7 +304,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.StringTag;
|
import net.minecraft.nbt.StringTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
@@ -238,7 +239,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import java.util.stream.Collectors;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.DoubleTag;
|
import net.minecraft.nbt.DoubleTag;
|
||||||
import net.minecraft.nbt.IntTag;
|
import net.minecraft.nbt.IntTag;
|
||||||
@@ -129,7 +130,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
public Value add(Value other)
|
public Value add(Value other)
|
||||||
{
|
{
|
||||||
ListValue output = new ListValue();
|
ListValue output = new ListValue();
|
||||||
if (other instanceof final ListValue list)
|
if (other instanceof ListValue list)
|
||||||
{
|
{
|
||||||
List<Value> otherItems = list.items;
|
List<Value> otherItems = list.items;
|
||||||
if (otherItems.size() == items.size())
|
if (otherItems.size() == items.size())
|
||||||
@@ -164,7 +165,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
public Value subtract(Value other)
|
public Value subtract(Value other)
|
||||||
{
|
{
|
||||||
ListValue output = new ListValue();
|
ListValue output = new ListValue();
|
||||||
if (other instanceof final ListValue list)
|
if (other instanceof ListValue list)
|
||||||
{
|
{
|
||||||
List<Value> otherItems = list.items;
|
List<Value> otherItems = list.items;
|
||||||
if (otherItems.size() == items.size())
|
if (otherItems.size() == items.size())
|
||||||
@@ -199,7 +200,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
public Value multiply(Value other)
|
public Value multiply(Value other)
|
||||||
{
|
{
|
||||||
ListValue output = new ListValue();
|
ListValue output = new ListValue();
|
||||||
if (other instanceof final ListValue list)
|
if (other instanceof ListValue list)
|
||||||
{
|
{
|
||||||
List<Value> otherItems = list.items;
|
List<Value> otherItems = list.items;
|
||||||
if (otherItems.size() == items.size())
|
if (otherItems.size() == items.size())
|
||||||
@@ -228,7 +229,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
public Value divide(Value other)
|
public Value divide(Value other)
|
||||||
{
|
{
|
||||||
ListValue output = new ListValue();
|
ListValue output = new ListValue();
|
||||||
if (other instanceof final ListValue list)
|
if (other instanceof ListValue list)
|
||||||
{
|
{
|
||||||
List<Value> otherItems = list.items;
|
List<Value> otherItems = list.items;
|
||||||
if (otherItems.size() == items.size())
|
if (otherItems.size() == items.size())
|
||||||
@@ -256,7 +257,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
@Override
|
@Override
|
||||||
public int compareTo(Value o)
|
public int compareTo(Value o)
|
||||||
{
|
{
|
||||||
if (o instanceof final ListValue ol)
|
if (o instanceof ListValue ol)
|
||||||
{
|
{
|
||||||
int size = this.getItems().size();
|
int size = this.getItems().size();
|
||||||
int otherSize = ol.getItems().size();
|
int otherSize = ol.getItems().size();
|
||||||
@@ -284,7 +285,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
return o instanceof final ListValue list && getItems().equals(list.getItems());
|
return o instanceof ListValue list && getItems().equals(list.getItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Value> getItems()
|
public List<Value> getItems()
|
||||||
@@ -555,7 +556,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
int argSize = items.size();
|
int argSize = items.size();
|
||||||
if (argSize == 0)
|
if (argSize == 0)
|
||||||
@@ -565,12 +566,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
ListTag tag = new ListTag();
|
ListTag tag = new ListTag();
|
||||||
if (argSize == 1)
|
if (argSize == 1)
|
||||||
{
|
{
|
||||||
tag.add(items.get(0).toTag(force));
|
tag.add(items.get(0).toTag(force, regs));
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
// figuring out the types
|
// figuring out the types
|
||||||
List<Tag> tags = new ArrayList<>();
|
List<Tag> tags = new ArrayList<>();
|
||||||
items.forEach(v -> tags.add(v.toTag(force)));
|
items.forEach(v -> tags.add(v.toTag(force, regs)));
|
||||||
Set<TagTypeCompat> cases = EnumSet.noneOf(TagTypeCompat.class);
|
Set<TagTypeCompat> cases = EnumSet.noneOf(TagTypeCompat.class);
|
||||||
tags.forEach(t -> cases.add(TagTypeCompat.getType(t)));
|
tags.forEach(t -> cases.add(TagTypeCompat.getType(t)));
|
||||||
if (cases.size() == 1) // well, one type of items
|
if (cases.size() == 1) // well, one type of items
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
@@ -104,11 +105,11 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
public Value add(Value o)
|
public Value add(Value o)
|
||||||
{
|
{
|
||||||
Map<Value, Value> newItems = new HashMap<>(map);
|
Map<Value, Value> newItems = new HashMap<>(map);
|
||||||
if (o instanceof final MapValue mapValue)
|
if (o instanceof MapValue mapValue)
|
||||||
{
|
{
|
||||||
newItems.putAll(mapValue.map);
|
newItems.putAll(mapValue.map);
|
||||||
}
|
}
|
||||||
else if (o instanceof final AbstractListValue alv)
|
else if (o instanceof AbstractListValue alv)
|
||||||
{
|
{
|
||||||
for (Value value : alv)
|
for (Value value : alv)
|
||||||
{
|
{
|
||||||
@@ -142,7 +143,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
|
|
||||||
public void put(Value v)
|
public void put(Value v)
|
||||||
{
|
{
|
||||||
if (!(v instanceof final ListValue pair))
|
if (!(v instanceof ListValue pair))
|
||||||
{
|
{
|
||||||
map.put(v, Value.NULL);
|
map.put(v, Value.NULL);
|
||||||
return;
|
return;
|
||||||
@@ -169,7 +170,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
return o instanceof final MapValue mapValue && map.equals(mapValue.map);
|
return o instanceof MapValue mapValue && map.equals(mapValue.map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Value, Value> getMap()
|
public Map<Value, Value> getMap()
|
||||||
@@ -249,7 +250,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
map.forEach((k, v) ->
|
map.forEach((k, v) ->
|
||||||
@@ -258,7 +259,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
{
|
{
|
||||||
throw new NBTSerializableValue.IncompatibleTypeException(k);
|
throw new NBTSerializableValue.IncompatibleTypeException(k);
|
||||||
}
|
}
|
||||||
tag.put(k.getString(), v.toTag(force));
|
tag.put(k.getString(), v.toTag(force, regs));
|
||||||
});
|
});
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import net.minecraft.commands.arguments.item.ItemParser;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.particles.ItemParticleOption;
|
||||||
import net.minecraft.nbt.CollectionTag;
|
import net.minecraft.nbt.CollectionTag;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.EndTag;
|
import net.minecraft.nbt.EndTag;
|
||||||
@@ -104,15 +104,11 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
nbtSupplier = tagSupplier;
|
nbtSupplier = tagSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Value fromStack(ItemStack stack)
|
public static Value fromStack(ItemStack stack, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (stack.hasTag())
|
NBTSerializableValue value = new NBTSerializableValue();
|
||||||
{
|
value.nbtSupplier = () -> stack.saveOptional(regs);
|
||||||
NBTSerializableValue value = new NBTSerializableValue();
|
return value;
|
||||||
value.nbtSupplier = stack::getTag;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return Value.NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Value nameFromRegistryId(@Nullable ResourceLocation id)
|
public static Value nameFromRegistryId(@Nullable ResourceLocation id)
|
||||||
@@ -341,29 +337,32 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
|
|
||||||
private static final Map<String, ItemInput> itemCache = new HashMap<>();
|
private static final Map<String, ItemInput> itemCache = new HashMap<>();
|
||||||
|
|
||||||
public static ItemInput parseItem(String itemString, RegistryAccess regs)
|
public static ItemStack parseItem(String itemString, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return parseItem(itemString, null, regs);
|
return parseItem(itemString, null, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ItemInput parseItem(String itemString, @Nullable CompoundTag customTag, RegistryAccess regs)
|
public static ItemStack parseItem(String itemString, @Nullable CompoundTag customTag, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
|
if (customTag != null) {
|
||||||
|
return ItemStack.parseOptional(regs, customTag);
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ItemInput res = itemCache.get(itemString); // [SCARY SHIT] persistent caches over server reloads
|
ItemInput res = itemCache.get(itemString); // [SCARY SHIT] persistent caches over server reloads
|
||||||
if (res != null)
|
if (res != null)
|
||||||
{
|
{
|
||||||
return customTag == null ? res : new ItemInput(Holder.direct(res.getItem()), customTag);
|
return res.createItemStack(1, false);
|
||||||
}
|
}
|
||||||
ItemParser.ItemResult parser = (new ItemParser(regs)).parse(new StringReader(itemString));
|
ItemParser.ItemResult parser = (new ItemParser(regs)).parse(new StringReader(itemString));
|
||||||
res = new ItemInput(parser.item(), parser.nbt());
|
res = new ItemInput(parser.item(), parser.components());
|
||||||
|
|
||||||
itemCache.put(itemString, res);
|
itemCache.put(itemString, res);
|
||||||
if (itemCache.size() > 64000)
|
if (itemCache.size() > 64000)
|
||||||
{
|
{
|
||||||
itemCache.clear();
|
itemCache.clear();
|
||||||
}
|
}
|
||||||
return customTag == null ? res : new ItemInput(Holder.direct(res.getItem()), customTag);
|
return res.createItemStack(1, false);
|
||||||
}
|
}
|
||||||
catch (CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
@@ -764,7 +763,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package carpet.script.value;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.StringTag;
|
import net.minecraft.nbt.StringTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
@@ -89,7 +90,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package carpet.script.value;
|
|||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -27,7 +28,7 @@ public class NumericValue extends Value
|
|||||||
|
|
||||||
public static NumericValue asNumber(Value v1, String id)
|
public static NumericValue asNumber(Value v1, String id)
|
||||||
{
|
{
|
||||||
if (v1 instanceof final NumericValue nv)
|
if (v1 instanceof NumericValue nv)
|
||||||
{
|
{
|
||||||
return nv;
|
return nv;
|
||||||
}
|
}
|
||||||
@@ -36,7 +37,7 @@ public class NumericValue extends Value
|
|||||||
|
|
||||||
public static NumericValue asNumber(Value v1)
|
public static NumericValue asNumber(Value v1)
|
||||||
{
|
{
|
||||||
if (v1 instanceof final NumericValue nv)
|
if (v1 instanceof NumericValue nv)
|
||||||
{
|
{
|
||||||
return nv;
|
return nv;
|
||||||
}
|
}
|
||||||
@@ -129,7 +130,7 @@ public class NumericValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public Value add(Value v)
|
public Value add(Value v)
|
||||||
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
||||||
if (v instanceof final NumericValue nv)
|
if (v instanceof NumericValue nv)
|
||||||
{
|
{
|
||||||
return longValue != null && nv.longValue != null ? new NumericValue(longValue + nv.longValue) : new NumericValue(value + nv.value);
|
return longValue != null && nv.longValue != null ? new NumericValue(longValue + nv.longValue) : new NumericValue(value + nv.value);
|
||||||
}
|
}
|
||||||
@@ -139,7 +140,7 @@ public class NumericValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public Value subtract(Value v)
|
public Value subtract(Value v)
|
||||||
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
||||||
if (v instanceof final NumericValue nv)
|
if (v instanceof NumericValue nv)
|
||||||
{
|
{
|
||||||
return longValue != null && nv.longValue != null ? new NumericValue(longValue - nv.longValue) : new NumericValue(value - nv.value);
|
return longValue != null && nv.longValue != null ? new NumericValue(longValue - nv.longValue) : new NumericValue(value - nv.value);
|
||||||
}
|
}
|
||||||
@@ -149,7 +150,7 @@ public class NumericValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public Value multiply(Value v)
|
public Value multiply(Value v)
|
||||||
{
|
{
|
||||||
if (v instanceof final NumericValue nv)
|
if (v instanceof NumericValue nv)
|
||||||
{
|
{
|
||||||
return longValue != null && nv.longValue != null ? new NumericValue(longValue * nv.longValue) : new NumericValue(value * nv.value);
|
return longValue != null && nv.longValue != null ? new NumericValue(longValue * nv.longValue) : new NumericValue(value * nv.value);
|
||||||
}
|
}
|
||||||
@@ -159,7 +160,7 @@ public class NumericValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public Value divide(Value v)
|
public Value divide(Value v)
|
||||||
{
|
{
|
||||||
return v instanceof final NumericValue nv ? new NumericValue(getDouble() / nv.getDouble()) : super.divide(v);
|
return v instanceof NumericValue nv ? new NumericValue(getDouble() / nv.getDouble()) : super.divide(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -175,7 +176,7 @@ public class NumericValue extends Value
|
|||||||
{
|
{
|
||||||
return -o.compareTo(this);
|
return -o.compareTo(this);
|
||||||
}
|
}
|
||||||
if (o instanceof final NumericValue no)
|
if (o instanceof NumericValue no)
|
||||||
{
|
{
|
||||||
return longValue != null && no.longValue != null ? longValue.compareTo(no.longValue) : Double.compare(value, no.value);
|
return longValue != null && no.longValue != null ? longValue.compareTo(no.longValue) : Double.compare(value, no.value);
|
||||||
}
|
}
|
||||||
@@ -185,13 +186,13 @@ public class NumericValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
if (o instanceof final Value otherValue)
|
if (o instanceof Value otherValue)
|
||||||
{
|
{
|
||||||
if (otherValue.isNull())
|
if (otherValue.isNull())
|
||||||
{
|
{
|
||||||
return o.equals(this);
|
return o.equals(this);
|
||||||
}
|
}
|
||||||
if (o instanceof final NumericValue no)
|
if (o instanceof NumericValue no)
|
||||||
{
|
{
|
||||||
if (longValue != null && no.longValue != null)
|
if (longValue != null && no.longValue != null)
|
||||||
{
|
{
|
||||||
@@ -279,7 +280,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (longValue != null)
|
if (longValue != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import java.util.Map;
|
|||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
@@ -373,18 +374,25 @@ public class ScreenValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (this.screenHandler == null)
|
if (this.screenHandler == null)
|
||||||
{
|
{
|
||||||
return Value.NULL.toTag(true);
|
return Value.NULL.toTag(true, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ListTag nbtList = new ListTag();
|
ListTag nbtList = new ListTag();
|
||||||
for (int i = 0; i < this.screenHandler.slots.size(); i++)
|
for (int i = 0; i < this.screenHandler.slots.size(); i++)
|
||||||
{
|
{
|
||||||
ItemStack itemStack = this.screenHandler.getSlot(i).getItem();
|
ItemStack itemStack = this.screenHandler.getSlot(i).getItem();
|
||||||
nbtList.add(itemStack.save(new CompoundTag()));
|
if (itemStack.isEmpty())
|
||||||
|
{
|
||||||
|
nbtList.add(new CompoundTag());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nbtList.add(itemStack.save(regs));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nbtList;
|
return nbtList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.StringTag;
|
import net.minecraft.nbt.StringTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ public class StringValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return StringTag.valueOf(str);
|
return StringTag.valueOf(str);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
public class ThreadValue extends LazyListValue
|
public class ThreadValue extends LazyListValue
|
||||||
@@ -108,13 +109,13 @@ public class ThreadValue extends LazyListValue
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
return o instanceof final ThreadValue tv && tv.id == this.id;
|
return o instanceof ThreadValue tv && tv.id == this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Value o)
|
public int compareTo(Value o)
|
||||||
{
|
{
|
||||||
if (!(o instanceof final ThreadValue tv))
|
if (!(o instanceof ThreadValue tv))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot compare tasks to other types");
|
throw new InternalExpressionException("Cannot compare tasks to other types");
|
||||||
}
|
}
|
||||||
@@ -128,13 +129,13 @@ public class ThreadValue extends LazyListValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||||
}
|
}
|
||||||
return getValue().toTag(true);
|
return getValue().toTag(true, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package carpet.script.value;
|
|||||||
|
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
public class UndefValue extends NullValue
|
public class UndefValue extends NullValue
|
||||||
@@ -87,7 +88,7 @@ public class UndefValue extends NullValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
throw getError();
|
throw getError();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.regex.PatternSyntaxException;
|
import java.util.regex.PatternSyntaxException;
|
||||||
|
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -97,7 +98,7 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
|||||||
|
|
||||||
public Value divide(Value v)
|
public Value divide(Value v)
|
||||||
{
|
{
|
||||||
if (v instanceof final NumericValue number)
|
if (v instanceof NumericValue number)
|
||||||
{
|
{
|
||||||
String lstr = getString();
|
String lstr = getString();
|
||||||
return new StringValue(lstr.substring(0, (int) (lstr.length() / number.getDouble())));
|
return new StringValue(lstr.substring(0, (int) (lstr.length() / number.getDouble())));
|
||||||
@@ -121,7 +122,7 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
|||||||
@Override // for hashmap key access, and == operator
|
@Override // for hashmap key access, and == operator
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
if (o instanceof final Value v)
|
if (o instanceof Value v)
|
||||||
{
|
{
|
||||||
return this.compareTo(v) == 0;
|
return this.compareTo(v) == 0;
|
||||||
}
|
}
|
||||||
@@ -254,7 +255,7 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Tag toTag(boolean force);
|
public abstract Tag toTag(boolean force, RegistryAccess regs);
|
||||||
|
|
||||||
public JsonElement toJson()
|
public JsonElement toJson()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,14 +8,12 @@ import carpet.script.utils.Colors;
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import net.minecraft.advancements.critereon.MinMaxBounds;
|
import net.minecraft.advancements.critereon.MinMaxBounds;
|
||||||
import net.minecraft.commands.arguments.item.ItemInput;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.GlobalPos;
|
import net.minecraft.core.GlobalPos;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
import net.minecraft.core.particles.ParticleOptions;
|
import net.minecraft.core.particles.ParticleOptions;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
@@ -58,8 +56,6 @@ import java.util.UUID;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class ValueConversions
|
public class ValueConversions
|
||||||
@@ -97,22 +93,12 @@ public class ValueConversions
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static Value of(ItemStack stack)
|
|
||||||
{
|
|
||||||
return stack == null || stack.isEmpty() ? Value.NULL : ListValue.of(
|
|
||||||
of(BuiltInRegistries.ITEM.getKey(stack.getItem())),
|
|
||||||
new NumericValue(stack.getCount()),
|
|
||||||
NBTSerializableValue.fromStack(stack)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Value of(ItemStack stack, RegistryAccess regs)
|
public static Value of(ItemStack stack, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return stack == null || stack.isEmpty() ? Value.NULL : ListValue.of(
|
return stack == null || stack.isEmpty() ? Value.NULL : ListValue.of(
|
||||||
of(regs.registryOrThrow(Registries.ITEM).getKey(stack.getItem())),
|
of(regs.registryOrThrow(Registries.ITEM).getKey(stack.getItem())),
|
||||||
new NumericValue(stack.getCount()),
|
new NumericValue(stack.getCount()),
|
||||||
NBTSerializableValue.fromStack(stack)
|
NBTSerializableValue.fromStack(stack, regs)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,22 +489,9 @@ public class ValueConversions
|
|||||||
{
|
{
|
||||||
name = value.getString();
|
name = value.getString();
|
||||||
}
|
}
|
||||||
ItemInput itemInput = NBTSerializableValue.parseItem(name, nbtTag, regs);
|
ItemStack itemInput = NBTSerializableValue.parseItem(name, nbtTag, regs);
|
||||||
try
|
itemInput.setCount(count);
|
||||||
{
|
return itemInput;
|
||||||
return itemInput.createItemStack(count, false);
|
|
||||||
}
|
|
||||||
catch (CommandSyntaxException cse)
|
|
||||||
{
|
|
||||||
if (!withCount)
|
|
||||||
{
|
|
||||||
throw new IllegalStateException("Unexpected exception while creating item stack of " + name + ". All items should be able to stack to one", cse);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ThrowStatement(count + " stack size of " + name, Throwables.UNKNOWN_ITEM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Value guess(ServerLevel serverWorld, Object o)
|
public static Value guess(ServerLevel serverWorld, Object o)
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ public class BlockInfo
|
|||||||
//lst.add(Messenger.s(String.format(" - Picks neighbour light value: %s", state.useNeighborBrightness(world, pos))));
|
//lst.add(Messenger.s(String.format(" - Picks neighbour light value: %s", state.useNeighborBrightness(world, pos))));
|
||||||
lst.add(Messenger.s(""));
|
lst.add(Messenger.s(""));
|
||||||
lst.add(Messenger.s(String.format(" - Causes suffocation: %s", state.isSuffocating(world, pos)))); //canSuffocate
|
lst.add(Messenger.s(String.format(" - Causes suffocation: %s", state.isSuffocating(world, pos)))); //canSuffocate
|
||||||
lst.add(Messenger.s(String.format(" - Blocks movement on land: %s", !state.isPathfindable(world,pos, PathComputationType.LAND))));
|
lst.add(Messenger.s(String.format(" - Blocks movement on land: %s", !state.isPathfindable(PathComputationType.LAND))));
|
||||||
lst.add(Messenger.s(String.format(" - Blocks movement in air: %s", !state.isPathfindable(world,pos, PathComputationType.AIR))));
|
lst.add(Messenger.s(String.format(" - Blocks movement in air: %s", !state.isPathfindable(PathComputationType.AIR))));
|
||||||
lst.add(Messenger.s(String.format(" - Blocks movement in liquids: %s", !state.isPathfindable(world,pos, PathComputationType.WATER))));
|
lst.add(Messenger.s(String.format(" - Blocks movement in liquids: %s", !state.isPathfindable(PathComputationType.WATER))));
|
||||||
lst.add(Messenger.s(String.format(" - Can burn: %s", state.ignitedByLava())));
|
lst.add(Messenger.s(String.format(" - Can burn: %s", state.ignitedByLava())));
|
||||||
lst.add(Messenger.s(String.format(" - Hardness: %.2f", state.getDestroySpeed(world, pos))));
|
lst.add(Messenger.s(String.format(" - Hardness: %.2f", state.getDestroySpeed(world, pos))));
|
||||||
lst.add(Messenger.s(String.format(" - Blast resistance: %.2f", block.getExplosionResistance())));
|
lst.add(Messenger.s(String.format(" - Blast resistance: %.2f", block.getExplosionResistance())));
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import net.minecraft.world.entity.EntityType;
|
|||||||
import net.minecraft.world.entity.MobCategory;
|
import net.minecraft.world.entity.MobCategory;
|
||||||
import net.minecraft.world.level.StructureManager;
|
import net.minecraft.world.level.StructureManager;
|
||||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
|
import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
|
||||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride;
|
import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride;
|
||||||
|
|||||||
Reference in new issue
Block a user