24w09a
This commit is contained in:
1 parent
2dd8674ea6
commit
4e57eecf2d
37 files changed
+490
-437
No files matched your search
+2
-2
@@ -3,8 +3,8 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check https://fabricmc.net/develop/
|
||||
minecraft_version=24w07a
|
||||
loader_version=0.15.6
|
||||
minecraft_version=24w09a
|
||||
loader_version=0.15.7
|
||||
jsr305_version=3.0.2
|
||||
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.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.commands.CommandBuildContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.DimensionArgument;
|
||||
@@ -304,7 +305,7 @@ public class PlayerCommand
|
||||
|
||||
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)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
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.util.thread.BlockableEventLoop;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
@@ -10,5 +9,5 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
|
||||
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;
|
||||
|
||||
import carpet.fakes.ChunkHolderInterface;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
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.Mixin;
|
||||
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.world.level.ChunkPos;
|
||||
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.UpgradeData;
|
||||
|
||||
@Mixin(ChunkHolder.class)
|
||||
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
|
||||
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();
|
||||
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> 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..?
|
||||
CompletableFuture<ChunkResult<ChunkAccess>> completableFuture2 = CompletableFuture.supplyAsync(
|
||||
() -> 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
|
||||
);
|
||||
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.TickTask;
|
||||
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.DistanceManager;
|
||||
import net.minecraft.server.level.ChunkResult;
|
||||
import net.minecraft.server.level.ChunkTaskPriorityQueueSorter;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
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.level.ChunkPos;
|
||||
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.status.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
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.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
|
||||
import carpet.fakes.ChunkHolderInterface;
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
import carpet.fakes.ServerLightingProviderInterface;
|
||||
@@ -104,7 +102,8 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
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);
|
||||
|
||||
@@ -112,8 +111,8 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
|
||||
// in protoChunkToFullChunk
|
||||
// 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)
|
||||
private void onChunkGeneratedStart(ChunkHolder chunkHolder, Either<ChunkAccess, ChunkLoadingFailure> chunk, CallbackInfoReturnable<CompletableFuture<Either<ChunkAccess, ChunkLoadingFailure>>> cir)
|
||||
@Inject(method = "method_17227", at = @At("HEAD"), remap = false)
|
||||
private void onChunkGeneratedStart(ChunkHolder chunkHolder, ChunkAccess chunkAccess, CallbackInfoReturnable<ChunkAccess> cir)
|
||||
{
|
||||
if (CHUNK_GENERATED.isNeeded() || CHUNK_LOADED.isNeeded())
|
||||
{
|
||||
@@ -125,10 +124,10 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "method_20460", at = @At("RETURN"), remap = false)
|
||||
private void onChunkGeneratedEnd(ChunkHolder chunkHolder, Either<ChunkAccess, ChunkLoadingFailure> chunk, CallbackInfoReturnable<CompletableFuture<Either<ChunkAccess, ChunkLoadingFailure>>> cir)
|
||||
@Inject(method = "method_17227", at = @At("RETURN"), remap = false)
|
||||
private void onChunkGeneratedEnd(ChunkHolder chunkHolder, ChunkAccess chunk, CallbackInfoReturnable<CompletableFuture<ChunkResult<ChunkAccess>>> cir)
|
||||
{
|
||||
Boolean localGenerated= generated.get();
|
||||
Boolean localGenerated = generated.get();
|
||||
if (localGenerated != null)
|
||||
{
|
||||
MinecraftServer server = this.level.getServer();
|
||||
@@ -137,15 +136,19 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
// 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
|
||||
if (CHUNK_GENERATED.isNeeded() && localGenerated)
|
||||
{
|
||||
server.tell(new TickTask(ticks, () -> CHUNK_GENERATED.onChunkEvent(this.level, chpos, true)));
|
||||
}
|
||||
if (CHUNK_LOADED.isNeeded())
|
||||
{
|
||||
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
|
||||
@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)
|
||||
{
|
||||
@@ -162,25 +165,25 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
*/
|
||||
|
||||
@Unique
|
||||
private void addTicket(final ChunkPos pos, final ChunkStatus status)
|
||||
private void addTicket(ChunkPos pos, ChunkStatus status)
|
||||
{ // UNKNOWN
|
||||
this.distanceManager.addTicket(TicketType.UNKNOWN, pos, 33 + ChunkStatus.getDistance(status), pos);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void addTicket(final ChunkPos pos)
|
||||
private void addTicket(ChunkPos pos)
|
||||
{
|
||||
this.addTicket(pos, ChunkStatus.EMPTY);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void addRelightTicket(final ChunkPos pos)
|
||||
private void addRelightTicket(ChunkPos pos)
|
||||
{
|
||||
this.distanceManager.addRegionTicket(TicketType.LIGHT, pos, 1, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseRelightTicket(final ChunkPos pos)
|
||||
public void releaseRelightTicket(ChunkPos pos)
|
||||
{
|
||||
this.mainThreadExecutor.tell(Util.name(
|
||||
() -> this.distanceManager.removeRegionTicket(TicketType.LIGHT, pos, 1, pos),
|
||||
@@ -195,57 +198,69 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
|
||||
@Unique
|
||||
private Set<ChunkPos> getExistingChunks(final Set<ChunkPos> requestedChunks)
|
||||
private Set<ChunkPos> getExistingChunks(Set<ChunkPos> requestedChunks)
|
||||
{
|
||||
final Map<String, RegionFile> regionCache = new HashMap<>();
|
||||
final Set<ChunkPos> ret = new HashSet<>();
|
||||
Map<String, RegionFile> regionCache = new HashMap<>();
|
||||
Set<ChunkPos> ret = new HashSet<>();
|
||||
|
||||
for (final ChunkPos pos : requestedChunks)
|
||||
for (ChunkPos pos : requestedChunks)
|
||||
{
|
||||
if (WorldTools.canHasChunk(this.level, pos, regionCache, true))
|
||||
{
|
||||
ret.add(pos);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private Set<ChunkPos> loadExistingChunksFromDisk(final Set<ChunkPos> requestedChunks)
|
||||
private Set<ChunkPos> loadExistingChunksFromDisk(Set<ChunkPos> requestedChunks)
|
||||
{
|
||||
Set<ChunkPos> existingChunks = this.getExistingChunks(requestedChunks);
|
||||
for (ChunkPos pos : existingChunks)
|
||||
{
|
||||
final Set<ChunkPos> existingChunks = this.getExistingChunks(requestedChunks);
|
||||
for (final ChunkPos pos : existingChunks)
|
||||
this.updatingChunkMap.get(pos.toLong()).getOrScheduleFuture(ChunkStatus.EMPTY, (ChunkMap) (Object) this);
|
||||
}
|
||||
|
||||
return existingChunks;
|
||||
}
|
||||
|
||||
@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)
|
||||
{
|
||||
report.put("requested_chunks", requestedChunks.size());
|
||||
}
|
||||
|
||||
// Load all relevant ChunkHolders into this.currentChunkHolders
|
||||
// This will not trigger loading from disk yet
|
||||
|
||||
for (final ChunkPos pos : requestedChunks)
|
||||
for (ChunkPos pos : requestedChunks)
|
||||
{
|
||||
this.addTicket(pos);
|
||||
}
|
||||
|
||||
this.tickTicketManager();
|
||||
|
||||
// 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
|
||||
).collect(Collectors.toSet());
|
||||
|
||||
if (report != null)
|
||||
{
|
||||
report.put("loaded_chunks", loadedChunks.size());
|
||||
}
|
||||
|
||||
// Load remaining chunks from disk
|
||||
|
||||
final Set<ChunkPos> unloadedChunks = new HashSet<>(requestedChunks);
|
||||
Set<ChunkPos> unloadedChunks = new HashSet<>(requestedChunks);
|
||||
unloadedChunks.removeAll(loadedChunks);
|
||||
|
||||
final Set<ChunkPos> existingChunks = this.loadExistingChunksFromDisk(unloadedChunks);
|
||||
Set<ChunkPos> existingChunks = this.loadExistingChunksFromDisk(unloadedChunks);
|
||||
|
||||
existingChunks.addAll(loadedChunks);
|
||||
|
||||
@@ -253,27 +268,27 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
|
||||
@Unique
|
||||
private Set<ChunkPos> loadExistingChunks(final Set<ChunkPos> requestedChunks)
|
||||
private Set<ChunkPos> loadExistingChunks(Set<ChunkPos> requestedChunks)
|
||||
{
|
||||
return this.loadExistingChunks(requestedChunks, null);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void waitFor(final Future<?> future)
|
||||
private void waitFor(Future<?> future)
|
||||
{
|
||||
this.mainThreadExecutor.managedBlock(future::isDone);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void waitFor(final List<? extends CompletableFuture<?>> futures)
|
||||
private void waitFor(List<? extends CompletableFuture<?>> futures)
|
||||
{
|
||||
this.waitFor(Util.sequenceFailFast(futures));
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
return future.join();
|
||||
@@ -285,95 +300,125 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
this.addTicket(pos);
|
||||
this.tickTicketManager();
|
||||
if (this.updatingChunkMap.get(pos.toLong()).getLastAvailable() == null) // chunk unloaded
|
||||
{
|
||||
if (WorldTools.canHasChunk(this.level, pos, null, true))
|
||||
{
|
||||
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);
|
||||
this.addRelightTicket(pos);
|
||||
ChunkHolder chunkHolder = this.updatingChunkMap.get(pos.toLong());
|
||||
final CompletableFuture<?> lightFuture = this.getChunkRangeFuture(chunkHolder, 1, (pos_) -> ChunkStatus.LIGHT)
|
||||
.thenCompose(
|
||||
either -> either.map(
|
||||
list -> ((ServerLightingProviderInterface) this.lightEngine).relight(chunk),
|
||||
unloaded -> {
|
||||
CompletableFuture<?> lightFuture = this.getChunkRangeFuture(chunkHolder, 1, (pos_) -> ChunkStatus.LIGHT)
|
||||
.thenCompose(results -> {
|
||||
List<ChunkAccess> depList = results.orElse(null);
|
||||
if (depList == null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Integer> regenerateChunkRegion(final List<ChunkPos> requestedChunksList)
|
||||
public Map<String, Integer> regenerateChunkRegion(List<ChunkPos> requestedChunksList)
|
||||
{
|
||||
final Object2IntMap<String> report = new Object2IntOpenHashMap<>();
|
||||
final Set<ChunkPos> requestedChunks = new HashSet<>(requestedChunksList);
|
||||
Object2IntMap<String> report = new Object2IntOpenHashMap<>();
|
||||
Set<ChunkPos> requestedChunks = new HashSet<>(requestedChunksList);
|
||||
|
||||
// Load requested chunks
|
||||
|
||||
final Set<ChunkPos> existingChunks = this.loadExistingChunks(requestedChunks, report);
|
||||
Set<ChunkPos> existingChunks = this.loadExistingChunks(requestedChunks, report);
|
||||
|
||||
// Finish pending generation stages
|
||||
// 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));
|
||||
}
|
||||
|
||||
report.put("affected_chunks", affectedChunks.size());
|
||||
|
||||
// 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 z = -1; z <= 1; ++z)
|
||||
{
|
||||
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))
|
||||
{
|
||||
neighbors.add(nPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.loadExistingChunks(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()))
|
||||
{
|
||||
affectedNeighbors.add(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
// Unload affected chunks
|
||||
|
||||
for (final ChunkAccess chunk : affectedChunks)
|
||||
for (ChunkAccess chunk : affectedChunks)
|
||||
{
|
||||
final ChunkPos pos = chunk.getPos();
|
||||
ChunkPos pos = chunk.getPos();
|
||||
|
||||
// remove entities
|
||||
long longPos = pos.toLong();
|
||||
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)
|
||||
{
|
||||
((LevelChunk) chunk).setLoaded(false);
|
||||
}
|
||||
|
||||
if (this.entitiesInLevel.remove(pos.toLong()) && chunk instanceof LevelChunk)
|
||||
{
|
||||
this.level.unload((LevelChunk) chunk); // block entities only
|
||||
}
|
||||
|
||||
((ServerLightingProviderInterface) this.lightEngine).invokeUpdateChunkStatus(pos);
|
||||
((ServerLightingProviderInterface) this.lightEngine).removeLightData(chunk);
|
||||
@@ -383,13 +428,13 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
|
||||
// Replace ChunkHolders
|
||||
|
||||
for (final ChunkAccess chunk : affectedChunks)
|
||||
for (ChunkAccess chunk : affectedChunks)
|
||||
{
|
||||
final ChunkPos cPos = chunk.getPos();
|
||||
final long pos = cPos.toLong();
|
||||
ChunkPos cPos = chunk.getPos();
|
||||
long pos = cPos.toLong();
|
||||
|
||||
final ChunkHolder oldHolder = this.updatingChunkMap.remove(pos);
|
||||
final ChunkHolder newHolder = new ChunkHolder(cPos, oldHolder.getTicketLevel(), level, this.lightEngine, this.queueSorter, (ChunkHolder.PlayerProvider) this);
|
||||
ChunkHolder oldHolder = this.updatingChunkMap.remove(pos);
|
||||
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?
|
||||
this.updatingChunkMap.put(pos, newHolder);
|
||||
|
||||
@@ -400,30 +445,32 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
this.promoteChunkMap();
|
||||
|
||||
|
||||
|
||||
|
||||
// Force generation to previous states
|
||||
// This ensures that the world is in a consistent state after this method
|
||||
// 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)
|
||||
);
|
||||
|
||||
for (final Entry<ChunkPos, ChunkStatus> entry : targetGenerationStatus.entrySet())
|
||||
for (Entry<ChunkPos, ChunkStatus> entry : targetGenerationStatus.entrySet())
|
||||
{
|
||||
this.addTicket(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
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(
|
||||
entry.getValue(),
|
||||
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(
|
||||
Pair::getKey,
|
||||
Collectors.mapping(
|
||||
@@ -433,17 +480,19 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
)
|
||||
);
|
||||
|
||||
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)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String statusName = BuiltInRegistries.CHUNK_STATUS.getKey(status).getPath();
|
||||
|
||||
report.put("layer_count_" + statusName, futures.size());
|
||||
final long start = System.currentTimeMillis();
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
this.waitFor(futures);
|
||||
|
||||
@@ -451,42 +500,46 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
report.put("relight_count", affectedNeighbors.size());
|
||||
|
||||
// Remove light for affected neighbors
|
||||
|
||||
for (final ChunkAccess chunk : affectedNeighbors)
|
||||
for (ChunkAccess chunk : affectedNeighbors)
|
||||
{
|
||||
((ServerLightingProviderInterface) this.lightEngine).removeLightData(chunk);
|
||||
}
|
||||
|
||||
// Schedule relighting of neighbors
|
||||
|
||||
for (final ChunkAccess chunk : affectedNeighbors)
|
||||
for (ChunkAccess chunk : affectedNeighbors)
|
||||
{
|
||||
this.addRelightTicket(chunk.getPos());
|
||||
}
|
||||
|
||||
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(
|
||||
either -> either.map(
|
||||
list -> ((ServerLightingProviderInterface) this.lightEngine).relight(chunk),
|
||||
unloaded -> {
|
||||
lightFutures.add(this.getChunkRangeFuture(this.updatingChunkMap.get(pos.toLong()), 1, (pos_) -> ChunkStatus.LIGHT).thenCompose(
|
||||
results -> {
|
||||
List<ChunkAccess> depList = results.orElse(null);
|
||||
if (depList == null)
|
||||
{
|
||||
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));
|
||||
}
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
final long relightStart = System.currentTimeMillis();
|
||||
long relightStart = System.currentTimeMillis();
|
||||
|
||||
this.waitFor(lightFutures);
|
||||
|
||||
@@ -496,7 +549,8 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ChunkHolder> getChunksCM() {
|
||||
public Iterable<ChunkHolder> getChunksCM()
|
||||
{
|
||||
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.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
@Mixin(Inventory.class)
|
||||
@@ -27,13 +26,11 @@ public abstract class Inventory_scarpetEventMixin
|
||||
{
|
||||
if (!PLAYER_PICKS_UP_ITEM.isNeeded() || !(player instanceof ServerPlayer))
|
||||
return playerInventory.add(-1, stack);
|
||||
Item item = stack.getItem();
|
||||
int count = stack.getCount();
|
||||
boolean res = playerInventory.add(-1, stack);
|
||||
if (count != stack.getCount()) // res returns false for larger item adding to a almost full ineventory
|
||||
{
|
||||
ItemStack diffStack = new ItemStack(item, count - stack.getCount());
|
||||
diffStack.setTag(stack.getTag());
|
||||
ItemStack diffStack = stack.copyWithCount(count - stack.getCount());
|
||||
PLAYER_PICKS_UP_ITEM.onItemAction((ServerPlayer) player, null, diffStack);
|
||||
}
|
||||
return res;
|
||||
|
||||
@@ -15,8 +15,8 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
public class PickaxeItem_missingToolsMixin extends DiggerItem
|
||||
{
|
||||
|
||||
protected PickaxeItem_missingToolsMixin(float attackDamage, float attackSpeed, Tier material, TagKey<Block> tag, Properties settings) {
|
||||
super(attackDamage, attackSpeed, material, tag, settings);
|
||||
protected PickaxeItem_missingToolsMixin(Tier material, TagKey<Block> tag, Properties settings) {
|
||||
super(material, tag, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -106,7 +106,7 @@ public class CarpetClient
|
||||
ListTag outputTag = (ListTag) tag.get("output");
|
||||
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();
|
||||
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())
|
||||
{
|
||||
|
||||
@@ -15,6 +15,8 @@ import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
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.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
|
||||
* to instantiate it.</p>
|
||||
*
|
||||
* @see ScarpetFunction
|
||||
* @param clazz The class to parse
|
||||
* @see ScarpetFunction
|
||||
*/
|
||||
public static void parseFunctionClass(Class<?> clazz)
|
||||
{
|
||||
@@ -132,7 +134,7 @@ public final class AnnotationParser
|
||||
|
||||
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);
|
||||
@@ -233,7 +235,8 @@ public final class AnnotationParser
|
||||
MethodHandle tempHandle = MethodHandles.publicLookup().unreflect(method).asFixedArity().asSpreader(Object[].class, this.methodParamCount);
|
||||
tempHandle = tempHandle.asType(tempHandle.type().changeReturnType(Object.class));
|
||||
this.handle = Modifier.isStatic(method.getModifiers()) ? tempHandle : tempHandle.bindTo(instance.get());
|
||||
} catch (IllegalAccessException e)
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
@@ -245,6 +248,8 @@ public final class AnnotationParser
|
||||
@Override
|
||||
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);
|
||||
if (isEffectivelyVarArgs)
|
||||
{
|
||||
@@ -262,7 +267,7 @@ public final class AnnotationParser
|
||||
Object[] params = getMethodParams(lv, context, t);
|
||||
try
|
||||
{
|
||||
Value result = outputConverter.convert(handle.invokeExact(params));
|
||||
Value result = outputConverter.convert(handle.invokeExact(params), regs);
|
||||
return (cc, tt) -> result;
|
||||
}
|
||||
catch (Throwable e)
|
||||
@@ -306,8 +311,9 @@ public final class AnnotationParser
|
||||
}
|
||||
varArgsList.add(obj);
|
||||
}
|
||||
varArgs = varArgsList.toArray((Object[])Array.newInstance(varArgsType, 0));
|
||||
} else
|
||||
varArgs = varArgsList.toArray((Object[]) Array.newInstance(varArgsType, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
varArgs = (Object[]) Array.newInstance(varArgsType, remaining / varArgsConverter.valueConsumption());
|
||||
for (int i = 0; lvIterator.hasNext(); i++)
|
||||
@@ -337,7 +343,8 @@ public final class AnnotationParser
|
||||
builder.append(", ");
|
||||
builder.append(varArgsConverter.getTypeName());
|
||||
builder.append("s...)");
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
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.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.GlobalPos;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
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
|
||||
* values.</p>
|
||||
*
|
||||
* @see #register(Class, Function)
|
||||
* @see #register(Class, BiFunction)
|
||||
* @param <T> The type to convert from into a {@link Value}
|
||||
*/
|
||||
public final class OutputConverter<T>
|
||||
{
|
||||
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
|
||||
{
|
||||
// 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(Boolean.class, BooleanValue::of);
|
||||
register(Integer.class, NumericValue::new);
|
||||
register(Integer.class, (v, r) -> new NumericValue(v));
|
||||
register(Double.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(Entity.class, EntityValue::new);
|
||||
register(Component.class, FormattedTextValue::new);
|
||||
register(Tag.class, NBTSerializableValue::new);
|
||||
register(BlockPos.class, ValueConversions::of);
|
||||
register(Vec3.class, ValueConversions::of);
|
||||
register(ItemStack.class, ValueConversions::of);
|
||||
register(ResourceLocation.class, ValueConversions::of);
|
||||
register(GlobalPos.class, ValueConversions::of);
|
||||
register(BlockPos.class, (v, r) -> ValueConversions.of(v));
|
||||
register(Vec3.class, (v, r) -> ValueConversions.of(v));
|
||||
register(ItemStack.class, (v, r) -> ValueConversions.of(v, r));
|
||||
register(ResourceLocation.class, (v, r) -> ValueConversions.of(v));
|
||||
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;
|
||||
}
|
||||
@@ -91,9 +93,9 @@ public final class OutputConverter<T>
|
||||
* @param input The value to convert
|
||||
* @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 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);
|
||||
if (byResult.containsKey(inputType))
|
||||
@@ -113,15 +115,24 @@ public final class OutputConverter<T>
|
||||
}
|
||||
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
|
||||
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);
|
||||
}
|
||||
@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.exception.ExitStatement;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.exception.ThrowStatement;
|
||||
import carpet.script.exception.Throwables;
|
||||
import carpet.script.external.Carpet;
|
||||
import carpet.script.utils.SnoopyCommandSource;
|
||||
import carpet.script.utils.SystemInfo;
|
||||
@@ -348,7 +346,7 @@ public class Auxiliary
|
||||
|
||||
ShapeDispatcher.sendShape(
|
||||
(playerTargets.isEmpty()) ? cc.level().players() : playerTargets,
|
||||
shapes
|
||||
shapes, cc.registryAccess()
|
||||
);
|
||||
return Value.TRUE;
|
||||
});
|
||||
@@ -475,7 +473,7 @@ public class Auxiliary
|
||||
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();
|
||||
if (argSize == 0 || argSize > 2)
|
||||
{
|
||||
@@ -486,7 +484,7 @@ public class Auxiliary
|
||||
Tag tag;
|
||||
try
|
||||
{
|
||||
tag = v.toTag(force);
|
||||
tag = v.toTag(force, ((CarpetContext)c).registryAccess());
|
||||
}
|
||||
catch (NBTSerializableValue.IncompatibleTypeException exception)
|
||||
{
|
||||
|
||||
@@ -19,16 +19,15 @@ import carpet.script.value.ScreenValue;
|
||||
import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.commands.arguments.item.ItemInput;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
@@ -111,7 +110,7 @@ public class Inventories
|
||||
type = cc.registry(Registries.RECIPE_TYPE).get(InputValidator.identifierOf(recipeType));
|
||||
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());
|
||||
@@ -125,7 +124,7 @@ public class Inventories
|
||||
{
|
||||
ItemStack result = recipe.getResultItem(regs);
|
||||
List<Value> ingredientValue = new ArrayList<>();
|
||||
recipe.getIngredients().forEach( ingredient -> {
|
||||
recipe.getIngredients().forEach(ingredient -> {
|
||||
// I am flattening ingredient lists per slot.
|
||||
// consider recipe_data('wooden_sword','crafting') and ('iron_nugget', 'blasting') and notice difference
|
||||
// in depths of lists.
|
||||
@@ -142,7 +141,7 @@ public class Inventories
|
||||
}
|
||||
});
|
||||
Value recipeSpec;
|
||||
if (recipe instanceof final ShapedRecipe shapedRecipe)
|
||||
if (recipe instanceof ShapedRecipe shapedRecipe)
|
||||
{
|
||||
recipeSpec = ListValue.of(
|
||||
new StringValue("shaped"),
|
||||
@@ -154,7 +153,7 @@ public class Inventories
|
||||
{
|
||||
recipeSpec = ListValue.of(new StringValue("shapeless"));
|
||||
}
|
||||
else if (recipe instanceof final AbstractCookingRecipe abstractCookingRecipe)
|
||||
else if (recipe instanceof AbstractCookingRecipe abstractCookingRecipe)
|
||||
{
|
||||
recipeSpec = ListValue.of(
|
||||
new StringValue("smelting"),
|
||||
@@ -249,9 +248,15 @@ public class Inventories
|
||||
{
|
||||
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();
|
||||
if (count == 0)
|
||||
if (count.isPresent() && count.getAsInt() == 0)
|
||||
{
|
||||
// clear slot
|
||||
ItemStack removedStack = inventoryLocator.inventory().removeItemNoUpdate(slot);
|
||||
@@ -262,16 +267,16 @@ public class Inventories
|
||||
{
|
||||
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||
ItemStack newStack = previousStack.copy();
|
||||
newStack.setCount(count);
|
||||
count.ifPresent(newStack::setCount);
|
||||
inventoryLocator.inventory().setItem(slot, newStack);
|
||||
syncPlayerInventory(inventoryLocator);
|
||||
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)
|
||||
{
|
||||
Value nbtValue = lv.get(inventoryLocator.offset() + 3);
|
||||
if (nbtValue instanceof final NBTSerializableValue nbtsv)
|
||||
if (nbtValue instanceof NBTSerializableValue nbtsv)
|
||||
{
|
||||
nbt = nbtsv.getCompoundTag();
|
||||
}
|
||||
@@ -280,17 +285,12 @@ public class Inventories
|
||||
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);
|
||||
try
|
||||
{
|
||||
inventoryLocator.inventory().setItem(slot, newitem.createItemStack(count, false));
|
||||
inventoryLocator.inventory().setItem(slot, newitem);
|
||||
syncPlayerInventory(inventoryLocator);
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
throw new InternalExpressionException(e.getMessage());
|
||||
}
|
||||
|
||||
return ValueConversions.of(previousStack, regs);
|
||||
});
|
||||
|
||||
@@ -303,7 +303,7 @@ public class Inventories
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
ItemInput itemArg = null;
|
||||
ItemStack itemArg = null;
|
||||
if (lv.size() > 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");
|
||||
}
|
||||
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;
|
||||
if (lv.size() > inventoryLocator.offset() + 1)
|
||||
{
|
||||
@@ -424,7 +424,7 @@ public class Inventories
|
||||
}
|
||||
Object owner = inventoryLocator.owner();
|
||||
ItemEntity item;
|
||||
if (owner instanceof final Player player)
|
||||
if (owner instanceof Player player)
|
||||
{
|
||||
item = player.drop(droppedStack, false, true);
|
||||
if (item == null)
|
||||
@@ -478,7 +478,7 @@ public class Inventories
|
||||
expression.addContextFunction("close_screen", 1, (c, t, lv) ->
|
||||
{
|
||||
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.");
|
||||
}
|
||||
@@ -496,7 +496,7 @@ public class Inventories
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.QuartPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
@@ -51,6 +52,7 @@ import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
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.DensityFunctions;
|
||||
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.properties.Property;
|
||||
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.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
@@ -840,6 +841,7 @@ public class WorldAccess
|
||||
expression.addContextFunction("destroy", -1, (c, t, lv) ->
|
||||
{
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
RegistryAccess regs = cc.registryAccess();
|
||||
ServerLevel world = cc.level();
|
||||
BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
|
||||
BlockState state = locator.block.getBlockState();
|
||||
@@ -882,11 +884,14 @@ public class WorldAccess
|
||||
: NBTSerializableValue.parseStringOrFail(tagValue.getString()).getCompoundTag();
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack tool = new ItemStack(item, 1);
|
||||
ItemStack tool;
|
||||
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)
|
||||
{
|
||||
@@ -950,8 +955,7 @@ public class WorldAccess
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
Tag outtag = tool.getTag();
|
||||
return outtag == null ? Value.TRUE : new NBTSerializableValue(() -> outtag);
|
||||
return new NBTSerializableValue(() -> tool.saveOptional(regs));
|
||||
|
||||
});
|
||||
|
||||
@@ -1106,7 +1110,7 @@ public class WorldAccess
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
String itemString = lv.get(0).getString();
|
||||
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);
|
||||
// Paintings throw an exception if their direction is vertical, therefore we change the default here
|
||||
String facing = lv.size() > locator.offset
|
||||
@@ -1118,15 +1122,7 @@ public class WorldAccess
|
||||
sneakPlace = lv.get(locator.offset + 1).getBoolean();
|
||||
}
|
||||
|
||||
BlockValue.PlacementContext ctx;
|
||||
try
|
||||
{
|
||||
ctx = BlockValue.PlacementContext.from(cc.level(), where, facing, sneakPlace, stackArg.createItemStack(1, false));
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
throw new InternalExpressionException(e.getMessage());
|
||||
}
|
||||
BlockValue.PlacementContext ctx = BlockValue.PlacementContext.from(cc.level(), where, facing, sneakPlace, stackArg);
|
||||
|
||||
if (!(stackArg.getItem() instanceof final BlockItem blockItem))
|
||||
{
|
||||
@@ -1160,7 +1156,7 @@ public class WorldAccess
|
||||
|
||||
expression.addContextFunction("blocks_movement", -1, (c, t, lv) ->
|
||||
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) ->
|
||||
stateStringQuery(c, "block_sound", lv, (s, p) ->
|
||||
|
||||
@@ -144,7 +144,7 @@ public class ShapeDispatcher
|
||||
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> alternativePlayers = new ArrayList<>();
|
||||
@@ -158,7 +158,7 @@ public class ShapeDispatcher
|
||||
int tagcount = 0;
|
||||
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)
|
||||
{
|
||||
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();
|
||||
params.forEach((k, v) -> {
|
||||
Tag valTag = Param.of.get(k).toTag(v);
|
||||
Tag valTag = Param.of.get(k).toTag(v, regs);
|
||||
if (valTag != null)
|
||||
{
|
||||
tag.put(k, valTag);
|
||||
@@ -724,7 +724,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
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();
|
||||
if (blockLight > 15)
|
||||
@@ -1532,7 +1532,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -1547,9 +1547,9 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return value.toTag(true);
|
||||
return value.toTag(true, regs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1589,7 +1589,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return StringTag.valueOf(value.getString());
|
||||
}
|
||||
@@ -1621,7 +1621,7 @@ public class ShapeDispatcher
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
if (value instanceof final BlockValue blv)
|
||||
{
|
||||
@@ -1661,11 +1661,11 @@ public class ShapeDispatcher
|
||||
public Value validate(Map<String, Value> options, MinecraftServer server, Value value)
|
||||
{
|
||||
ItemStack item = ValueConversions.getItemStackFromValue(value, true, server.registryAccess());
|
||||
return new NBTSerializableValue(item.save(new CompoundTag()));
|
||||
return new NBTSerializableValue(item.save(server.registryAccess()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return ((NBTSerializableValue) value).getTag();
|
||||
}
|
||||
@@ -1710,19 +1710,19 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
if (!(value instanceof FormattedTextValue))
|
||||
{
|
||||
value = new FormattedTextValue(Component.literal(value.getString()));
|
||||
}
|
||||
return StringTag.valueOf(((FormattedTextValue) value).serialize());
|
||||
return StringTag.valueOf(((FormattedTextValue) value).serialize(regs));
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return ByteTag.valueOf(value.getBoolean());
|
||||
}
|
||||
@@ -1834,7 +1834,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
||||
}
|
||||
@@ -1873,7 +1873,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
||||
}
|
||||
@@ -1894,7 +1894,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
||||
}
|
||||
@@ -1915,7 +1915,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
||||
}
|
||||
@@ -1946,7 +1946,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return FloatTag.valueOf(NumericValue.asNumber(value, id).getFloat());
|
||||
}
|
||||
@@ -2041,7 +2041,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
List<Value> lv = ((ListValue) value).getItems();
|
||||
ListTag tag = new ListTag();
|
||||
@@ -2092,7 +2092,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value pointsValue)
|
||||
public Tag toTag(Value pointsValue, final RegistryAccess regs)
|
||||
{
|
||||
List<Value> lv = ((ListValue) pointsValue).getItems();
|
||||
ListTag ltag = new ListTag();
|
||||
@@ -2124,7 +2124,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
return IntTag.valueOf(NumericValue.asNumber(value, id).getInt());
|
||||
}
|
||||
@@ -2139,7 +2139,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
public Tag toTag(Value value, final RegistryAccess regs)
|
||||
{
|
||||
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.border.BorderChangeListener;
|
||||
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.status.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||
import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
|
||||
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.GlobalPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
@@ -41,7 +42,6 @@ import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
|
||||
import static carpet.script.value.NBTSerializableValue.nameFromResource;
|
||||
|
||||
public class BlockValue extends Value
|
||||
@@ -240,7 +240,7 @@ public class BlockValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ package carpet.script.value;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.ByteTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
@@ -54,7 +55,7 @@ public class BooleanValue extends NumericValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
return ByteTag.valueOf(boolValue);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ public class EntityValue extends Value
|
||||
|
||||
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());
|
||||
if (newPlayer != null)
|
||||
@@ -144,7 +144,7 @@ public class EntityValue extends 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;
|
||||
}
|
||||
@@ -158,7 +158,7 @@ public class EntityValue extends 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();
|
||||
}
|
||||
@@ -184,7 +184,7 @@ public class EntityValue extends Value
|
||||
@Override
|
||||
public boolean equals(Object v)
|
||||
{
|
||||
if (v instanceof final EntityValue ev)
|
||||
if (v instanceof EntityValue ev)
|
||||
{
|
||||
return getEntity().getId() == ev.getEntity().getId();
|
||||
}
|
||||
@@ -194,7 +194,7 @@ public class EntityValue extends Value
|
||||
@Override
|
||||
public Value in(Value v)
|
||||
{
|
||||
if (v instanceof final ListValue lv)
|
||||
if (v instanceof ListValue lv)
|
||||
{
|
||||
List<Value> values = lv.getItems();
|
||||
String what = values.get(0).getString();
|
||||
@@ -478,7 +478,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("yaw", (e, a) -> new NumericValue(e.getYRot()));
|
||||
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("look", (e, a) -> {
|
||||
@@ -500,19 +500,19 @@ public class EntityValue extends Value
|
||||
put("width", (e, a) -> new NumericValue(e.getDimensions(Pose.STANDING).width()));
|
||||
put("eye_height", (e, a) -> new NumericValue(e.getEyeHeight()));
|
||||
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("despawn_timer", (e, a) -> e instanceof final 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("offering_flower", (e, a) -> e instanceof final 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("count", (e, a) -> (e instanceof final 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("breeding_age", (e, a) -> e instanceof AgeableMob am ? new NumericValue(am.getAge()) : Value.NULL);
|
||||
put("despawn_timer", (e, a) -> e instanceof LivingEntity le ? new NumericValue(le.getNoActionTime()) : Value.NULL);
|
||||
put("blue_skull", (e, a) -> e instanceof WitherSkull w ? BooleanValue.of(w.isDangerous()) : Value.NULL);
|
||||
put("offering_flower", (e, a) -> e instanceof IronGolem ig ? BooleanValue.of(ig.getOfferFlowerTick() > 0) : 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 ItemEntity ie) ? new NumericValue(ie.getItem().getCount()) : 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_timer", (e, a) -> new NumericValue(Vanilla.Entity_getPortalTimer(e)));
|
||||
// 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) -> {
|
||||
if (e instanceof final Mob mob)
|
||||
if (e instanceof Mob mob)
|
||||
{
|
||||
LivingEntity target = mob.getTarget(); // there is also getAttacking in living....
|
||||
if (target != null)
|
||||
@@ -522,9 +522,9 @@ public class EntityValue extends Value
|
||||
}
|
||||
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) -> {
|
||||
if (e instanceof final ServerPlayer spe)
|
||||
if (e instanceof ServerPlayer spe)
|
||||
{
|
||||
if (spe.getRespawnPosition() == null)
|
||||
{
|
||||
@@ -543,22 +543,22 @@ public class EntityValue extends Value
|
||||
put("sneaking", (e, a) -> e.isShiftKeyDown() ? 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("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("language", (e, a) -> !(e instanceof final 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("hunger", (e, a) -> e instanceof final 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("exhaustion", (e, a) -> e instanceof final 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("xp", (e, a) -> e instanceof final 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_progress", (e, a) -> e instanceof final Player player ? new NumericValue(player.experienceProgress) : Value.NULL);
|
||||
put("score", (e, a) -> e instanceof final 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("gamemode", (e, a) -> e instanceof final ServerPlayer sp ? new StringValue(sp.gameMode.getGameModeForPlayer().getName()) : Value.NULL);
|
||||
put("language", (e, a) -> !(e instanceof ServerPlayer p) ? NULL : StringValue.of(Vanilla.ServerPlayer_getLanguage(p)));
|
||||
put("persistence", (e, a) -> e instanceof Mob mob ? BooleanValue.of(mob.isPersistenceRequired()) : Value.NULL);
|
||||
put("hunger", (e, a) -> e instanceof Player player ? new NumericValue(player.getFoodData().getFoodLevel()) : Value.NULL);
|
||||
put("saturation", (e, a) -> e instanceof Player player ? new NumericValue(player.getFoodData().getSaturationLevel()) : Value.NULL);
|
||||
put("exhaustion", (e, a) -> e instanceof Player player ? new NumericValue(player.getFoodData().getExhaustionLevel()) : Value.NULL);
|
||||
put("absorption", (e, a) -> e instanceof Player player ? new NumericValue(player.getAbsorptionAmount()) : Value.NULL);
|
||||
put("xp", (e, a) -> e instanceof Player player ? new NumericValue(player.totalExperience) : Value.NULL);
|
||||
put("xp_level", (e, a) -> e instanceof Player player ? new NumericValue(player.experienceLevel) : Value.NULL);
|
||||
put("xp_progress", (e, a) -> e instanceof Player player ? new NumericValue(player.experienceProgress) : Value.NULL);
|
||||
put("score", (e, a) -> e instanceof Player player ? new NumericValue(player.getScore()) : 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 ServerPlayer sp ? new StringValue(sp.gameMode.getGameModeForPlayer().getName()) : Value.NULL);
|
||||
put("path", (e, a) -> {
|
||||
if (e instanceof final Mob mob)
|
||||
if (e instanceof Mob mob)
|
||||
{
|
||||
Path path = mob.getNavigation().getPath();
|
||||
if (path == null)
|
||||
@@ -577,7 +577,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
if (e instanceof final LivingEntity livingEntity)
|
||||
if (e instanceof LivingEntity livingEntity)
|
||||
{
|
||||
Brain<?> brain = livingEntity.getBrain();
|
||||
Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = brain.getMemories();
|
||||
@@ -591,9 +591,9 @@ public class EntityValue extends Value
|
||||
}
|
||||
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) -> {
|
||||
if (e instanceof final ServerPlayer spe)
|
||||
if (e instanceof ServerPlayer spe)
|
||||
{
|
||||
for (int i = 4; i >= 0; i--)
|
||||
{
|
||||
@@ -609,7 +609,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("player_type", (e, a) -> {
|
||||
if (e instanceof final Player p)
|
||||
if (e instanceof Player p)
|
||||
{
|
||||
String moddedType = Carpet.isModdedPlayer(p);
|
||||
if (moddedType != null)
|
||||
@@ -637,15 +637,15 @@ public class EntityValue extends Value
|
||||
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("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
|
||||
// isGlowing
|
||||
put("effect", (e, a) ->
|
||||
{
|
||||
if (!(e instanceof final LivingEntity le))
|
||||
if (!(e instanceof LivingEntity le))
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
@@ -663,7 +663,7 @@ public class EntityValue extends Value
|
||||
return ListValue.wrap(effects);
|
||||
}
|
||||
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))
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -672,13 +672,13 @@ public class EntityValue extends Value
|
||||
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("may_fly", (e, a) -> e instanceof final 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("may_build", (e, v) -> e instanceof final 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("fly_speed", (e, v) -> e instanceof final 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("health", (e, a) -> e instanceof LivingEntity le ? new NumericValue(le.getHealth()) : Value.NULL);
|
||||
put("may_fly", (e, a) -> e instanceof ServerPlayer player ? BooleanValue.of(player.getAbilities().mayfly) : Value.NULL);
|
||||
put("flying", (e, v) -> e instanceof ServerPlayer player ? BooleanValue.of(player.getAbilities().flying) : 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 ServerPlayer player ? BooleanValue.of(player.getAbilities().instabuild) : 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 ServerPlayer player ? NumericValue.of(player.getAbilities().getWalkingSpeed()) : Value.NULL);
|
||||
put("holds", (e, a) -> {
|
||||
EquipmentSlot where = EquipmentSlot.MAINHAND;
|
||||
if (a != null)
|
||||
@@ -689,17 +689,17 @@ public class EntityValue extends Value
|
||||
{
|
||||
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 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) -> {
|
||||
if (e instanceof final ServerPlayer sp)
|
||||
if (e instanceof ServerPlayer sp)
|
||||
{
|
||||
BlockPos pos = Vanilla.ServerPlayerGameMode_getCurrentBlockPosition(sp.gameMode);
|
||||
if (pos == null)
|
||||
@@ -712,9 +712,9 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
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 Value.NULL;
|
||||
@@ -745,7 +745,7 @@ public class EntityValue extends Value
|
||||
|
||||
if (a != null)
|
||||
{
|
||||
if (!(a instanceof final ListValue lv))
|
||||
if (!(a instanceof ListValue lv))
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -829,7 +829,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("attribute", (e, a) -> {
|
||||
if (!(e instanceof final LivingEntity el))
|
||||
if (!(e instanceof LivingEntity el))
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
@@ -896,7 +896,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
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.
|
||||
EnumSet<RelativeMovement> set = EnumSet.noneOf(RelativeMovement.class);
|
||||
@@ -909,7 +909,7 @@ public class EntityValue extends Value
|
||||
e.moveTo(x, y, z, yaw, pitch);
|
||||
// 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));
|
||||
if (e instanceof final LivingEntity le)
|
||||
if (e instanceof LivingEntity le)
|
||||
{
|
||||
le.yBodyRotO = le.yRotO = 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("health", (e, v) -> {
|
||||
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)
|
||||
{
|
||||
@@ -950,7 +950,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
((LivingEntity) e).setHealth(health);
|
||||
}
|
||||
if (e instanceof final LivingEntity le)
|
||||
if (e instanceof LivingEntity le)
|
||||
{
|
||||
le.setHealth(health);
|
||||
}
|
||||
@@ -958,7 +958,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("may_fly", (e, v) -> {
|
||||
boolean mayFly = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
if (e instanceof ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().mayfly = mayFly;
|
||||
if (!mayFly && player.getAbilities().flying)
|
||||
@@ -971,7 +971,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("flying", (e, v) -> {
|
||||
boolean flying = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
if (e instanceof ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().flying = flying;
|
||||
player.onUpdateAbilities();
|
||||
@@ -980,7 +980,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("may_build", (e, v) -> {
|
||||
boolean mayBuild = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
if (e instanceof ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().mayBuild = mayBuild;
|
||||
player.onUpdateAbilities();
|
||||
@@ -989,7 +989,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("insta_build", (e, v) -> {
|
||||
boolean instaBuild = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
if (e instanceof ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().instabuild = instaBuild;
|
||||
player.onUpdateAbilities();
|
||||
@@ -998,7 +998,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("fly_speed", (e, v) -> {
|
||||
float flySpeed = NumericValue.asNumber(v).getFloat();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
if (e instanceof ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().setFlyingSpeed(flySpeed);
|
||||
player.onUpdateAbilities();
|
||||
@@ -1007,7 +1007,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("walk_speed", (e, v) -> {
|
||||
float walkSpeed = NumericValue.asNumber(v).getFloat();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
if (e instanceof ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().setWalkingSpeed(walkSpeed);
|
||||
player.onUpdateAbilities();
|
||||
@@ -1016,7 +1016,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("selected_slot", (e, v) ->
|
||||
{
|
||||
if (e instanceof final ServerPlayer player)
|
||||
if (e instanceof ServerPlayer player)
|
||||
{
|
||||
int slot = NumericValue.asNumber(v).getInt();
|
||||
player.connection.send(new ClientboundSetCarriedItemPacket(slot));
|
||||
@@ -1041,7 +1041,7 @@ public class EntityValue extends Value
|
||||
put("kill", (e, v) -> e.kill());
|
||||
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");
|
||||
}
|
||||
@@ -1056,7 +1056,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
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");
|
||||
}
|
||||
@@ -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("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");
|
||||
}
|
||||
@@ -1117,7 +1117,7 @@ public class EntityValue extends Value
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -1133,7 +1133,7 @@ public class EntityValue extends Value
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -1168,7 +1168,7 @@ public class EntityValue extends Value
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -1189,7 +1189,7 @@ public class EntityValue extends Value
|
||||
return;
|
||||
}
|
||||
boolean showName = false;
|
||||
if (v instanceof final ListValue lv)
|
||||
if (v instanceof ListValue lv)
|
||||
{
|
||||
showName = lv.getItems().get(1).getBoolean();
|
||||
v = lv.getItems().get(0);
|
||||
@@ -1200,7 +1200,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("persistence", (e, v) ->
|
||||
{
|
||||
if (!(e instanceof final Mob mob))
|
||||
if (!(e instanceof Mob mob))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1213,11 +1213,11 @@ public class EntityValue extends Value
|
||||
|
||||
put("dismount", (e, v) -> e.stopRiding());
|
||||
put("mount", (e, v) -> {
|
||||
if (v instanceof final EntityValue ev)
|
||||
if (v instanceof EntityValue ev)
|
||||
{
|
||||
e.startRiding(ev.getEntity(), true);
|
||||
}
|
||||
if (e instanceof final ServerPlayer sp)
|
||||
if (e instanceof ServerPlayer sp)
|
||||
{
|
||||
sp.connection.send(new ClientboundSetPassengersPacket(e));
|
||||
}
|
||||
@@ -1229,15 +1229,15 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("'mount_passengers' needs entities to ride");
|
||||
}
|
||||
if (v instanceof final EntityValue ev)
|
||||
if (v instanceof EntityValue ev)
|
||||
{
|
||||
ev.getEntity().startRiding(e);
|
||||
}
|
||||
else if (v instanceof final ListValue lv)
|
||||
else if (v instanceof ListValue lv)
|
||||
{
|
||||
for (Value element : lv.getItems())
|
||||
{
|
||||
if (element instanceof final EntityValue ev)
|
||||
if (element instanceof EntityValue ev)
|
||||
{
|
||||
ev.getEntity().startRiding(e);
|
||||
}
|
||||
@@ -1249,7 +1249,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("'tag' requires parameters");
|
||||
}
|
||||
if (v instanceof final ListValue lv)
|
||||
if (v instanceof ListValue lv)
|
||||
{
|
||||
for (Value element : lv.getItems())
|
||||
{
|
||||
@@ -1266,7 +1266,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("'clear_tag' requires parameters");
|
||||
}
|
||||
if (v instanceof final ListValue lv)
|
||||
if (v instanceof ListValue lv)
|
||||
{
|
||||
for (Value element : lv.getItems())
|
||||
{
|
||||
@@ -1288,20 +1288,20 @@ public class EntityValue extends Value
|
||||
//});
|
||||
put("breeding_age", (e, v) ->
|
||||
{
|
||||
if (e instanceof final AgeableMob am)
|
||||
if (e instanceof AgeableMob am)
|
||||
{
|
||||
am.setAge((int) NumericValue.asNumber(v).getLong());
|
||||
}
|
||||
});
|
||||
put("talk", (e, v) -> {
|
||||
// attacks indefinitely
|
||||
if (e instanceof final Mob mob)
|
||||
if (e instanceof Mob mob)
|
||||
{
|
||||
mob.playAmbientSound();
|
||||
}
|
||||
});
|
||||
put("home", (e, v) -> {
|
||||
if (!(e instanceof final PathfinderMob ec))
|
||||
if (!(e instanceof PathfinderMob ec))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1321,7 +1321,7 @@ public class EntityValue extends Value
|
||||
BlockPos pos;
|
||||
int distance = 16;
|
||||
|
||||
if (v instanceof final BlockValue bv)
|
||||
if (v instanceof BlockValue bv)
|
||||
{
|
||||
pos = bv.getPos();
|
||||
if (pos == null)
|
||||
@@ -1329,7 +1329,7 @@ public class EntityValue extends Value
|
||||
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();
|
||||
Vector3Argument locator = Vector3Argument.findIn(list, 0, false, false);
|
||||
@@ -1355,7 +1355,7 @@ public class EntityValue extends Value
|
||||
}); //requires mixing
|
||||
|
||||
put("spawn_point", (e, a) -> {
|
||||
if (!(e instanceof final ServerPlayer spe))
|
||||
if (!(e instanceof ServerPlayer spe))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1363,7 +1363,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
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();
|
||||
Vector3Argument blockLocator = Vector3Argument.findIn(params, 0, false, false);
|
||||
@@ -1373,7 +1373,7 @@ public class EntityValue extends Value
|
||||
boolean forced = false;
|
||||
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();
|
||||
if (params.size() > blockLocator.offset + 1)
|
||||
{
|
||||
@@ -1386,7 +1386,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -1406,7 +1406,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("pickup_delay", (e, v) ->
|
||||
{
|
||||
if (e instanceof final ItemEntity ie)
|
||||
if (e instanceof ItemEntity ie)
|
||||
{
|
||||
ie.setPickUpDelay((int) NumericValue.asNumber(v).getLong());
|
||||
}
|
||||
@@ -1414,7 +1414,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("despawn_timer", (e, v) ->
|
||||
{
|
||||
if (e instanceof final LivingEntity le)
|
||||
if (e instanceof LivingEntity le)
|
||||
{
|
||||
le.setNoActionTime((int) NumericValue.asNumber(v).getLong());
|
||||
}
|
||||
@@ -1440,7 +1440,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("ai", (e, v) ->
|
||||
{
|
||||
if (e instanceof final Mob mob)
|
||||
if (e instanceof Mob mob)
|
||||
{
|
||||
mob.setNoAi(!v.getBoolean());
|
||||
}
|
||||
@@ -1459,7 +1459,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
put("effect", (e, v) ->
|
||||
{
|
||||
if (!(e instanceof final LivingEntity le))
|
||||
if (!(e instanceof LivingEntity le))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1468,13 +1468,13 @@ public class EntityValue extends Value
|
||||
le.removeAllEffects();
|
||||
return;
|
||||
}
|
||||
else if (v instanceof final ListValue lv)
|
||||
else if (v instanceof ListValue lv)
|
||||
{
|
||||
List<Value> list = lv.getItems();
|
||||
if (list.size() >= 1 && list.size() <= 6)
|
||||
{
|
||||
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)
|
||||
{
|
||||
le.removeEffect(effect);
|
||||
@@ -1486,7 +1486,8 @@ public class EntityValue extends Value
|
||||
le.removeEffect(effect);
|
||||
return;
|
||||
}
|
||||
if (duration < 0){
|
||||
if (duration < 0)
|
||||
{
|
||||
duration = -1;
|
||||
}
|
||||
int amplifier = 0;
|
||||
@@ -1516,7 +1517,7 @@ public class EntityValue extends Value
|
||||
else
|
||||
{
|
||||
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);
|
||||
return;
|
||||
}
|
||||
@@ -1524,7 +1525,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("gamemode", (e, v) -> {
|
||||
if (!(e instanceof final ServerPlayer sp))
|
||||
if (!(e instanceof ServerPlayer sp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1538,7 +1539,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("jumping", (e, v) -> {
|
||||
if (!(e instanceof final LivingEntity le))
|
||||
if (!(e instanceof LivingEntity le))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1546,7 +1547,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("jump", (e, v) -> {
|
||||
if (e instanceof final LivingEntity le)
|
||||
if (e instanceof LivingEntity le)
|
||||
{
|
||||
Vanilla.LivingEntity_setJumping(le);
|
||||
}
|
||||
@@ -1557,7 +1558,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("swing", (e, v) -> {
|
||||
if (e instanceof final LivingEntity le)
|
||||
if (e instanceof LivingEntity le)
|
||||
{
|
||||
InteractionHand hand = InteractionHand.MAIN_HAND;
|
||||
if (v != null)
|
||||
@@ -1578,7 +1579,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("invulnerable", (e, v) -> {
|
||||
boolean invulnerable = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
if (e instanceof ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().invulnerable = invulnerable;
|
||||
player.onUpdateAbilities();
|
||||
@@ -1593,49 +1594,49 @@ public class EntityValue extends Value
|
||||
put("frost", (e, v) -> e.setTicksFrozen((int) NumericValue.asNumber(v).getLong()));
|
||||
|
||||
put("hunger", (e, v) -> {
|
||||
if (e instanceof final Player p)
|
||||
if (e instanceof Player p)
|
||||
{
|
||||
p.getFoodData().setFoodLevel((int) NumericValue.asNumber(v).getLong());
|
||||
}
|
||||
});
|
||||
|
||||
put("exhaustion", (e, v) -> {
|
||||
if (e instanceof final Player p)
|
||||
if (e instanceof Player p)
|
||||
{
|
||||
p.getFoodData().setExhaustion(NumericValue.asNumber(v).getFloat());
|
||||
}
|
||||
});
|
||||
|
||||
put("add_exhaustion", (e, v) -> {
|
||||
if (e instanceof final Player p)
|
||||
if (e instanceof Player p)
|
||||
{
|
||||
p.getFoodData().addExhaustion(NumericValue.asNumber(v).getFloat());
|
||||
}
|
||||
});
|
||||
|
||||
put("absorption", (e, v) -> {
|
||||
if (e instanceof final Player p)
|
||||
if (e instanceof Player p)
|
||||
{
|
||||
p.setAbsorptionAmount(NumericValue.asNumber(v, "absorbtion").getFloat());
|
||||
}
|
||||
});
|
||||
|
||||
put("add_xp", (e, v) -> {
|
||||
if (e instanceof final Player p)
|
||||
if (e instanceof Player p)
|
||||
{
|
||||
p.giveExperiencePoints(NumericValue.asNumber(v, "add_xp").getInt());
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
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.connection.send(new ClientboundSetExperiencePacket(p.experienceProgress, p.totalExperience, p.experienceLevel));
|
||||
@@ -1643,14 +1644,14 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("xp_score", (e, v) -> {
|
||||
if (e instanceof final Player p)
|
||||
if (e instanceof Player p)
|
||||
{
|
||||
p.setScore(NumericValue.asNumber(v, "xp_score").getInt());
|
||||
}
|
||||
});
|
||||
|
||||
put("saturation", (e, v) -> {
|
||||
if (e instanceof final Player p)
|
||||
if (e instanceof Player p)
|
||||
{
|
||||
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("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();
|
||||
Vanilla.ServerPlayerGameMode_setBlockBreakingProgress(sp.gameMode, progress);
|
||||
@@ -1671,7 +1672,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
UUID uUID = e.getUUID();
|
||||
Value tagValue = NBTSerializableValue.fromValue(v);
|
||||
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
||||
if (tagValue instanceof NBTSerializableValue nbtsv)
|
||||
{
|
||||
e.load(nbtsv.getCompoundTag());
|
||||
e.setUUID(uUID);
|
||||
@@ -1683,7 +1684,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
UUID uUID = e.getUUID();
|
||||
Value tagValue = NBTSerializableValue.fromValue(v);
|
||||
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
||||
if (tagValue instanceof NBTSerializableValue nbtsv)
|
||||
{
|
||||
CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
||||
nbttagcompound.merge(nbtsv.getCompoundTag());
|
||||
@@ -1694,14 +1695,14 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("blue_skull", (e, v) -> {
|
||||
if (e instanceof final WitherSkull w)
|
||||
if (e instanceof WitherSkull w)
|
||||
{
|
||||
w.setDangerous(v.getBoolean());
|
||||
}
|
||||
|
||||
});
|
||||
put("offering_flower", (e, v) -> {
|
||||
if (e instanceof final IronGolem ig)
|
||||
if (e instanceof IronGolem ig)
|
||||
{
|
||||
ig.offerFlower(v.getBoolean());
|
||||
}
|
||||
@@ -1709,11 +1710,11 @@ public class EntityValue extends Value
|
||||
});
|
||||
put("item", (e, v) -> {
|
||||
ItemStack item = ValueConversions.getItemStackFromValue(v, true, e.level().registryAccess());
|
||||
if (e instanceof final ItemEntity itementity)
|
||||
if (e instanceof ItemEntity itementity)
|
||||
{
|
||||
itementity.setItem(item);
|
||||
}
|
||||
if (e instanceof final ItemFrame itemframe)
|
||||
if (e instanceof ItemFrame itemframe)
|
||||
{
|
||||
itemframe.setItem(item);
|
||||
}
|
||||
@@ -1734,7 +1735,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.nbt.Tag toTag(boolean force)
|
||||
public net.minecraft.nbt.Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -19,7 +19,7 @@ public class FormattedTextValue extends StringValue
|
||||
public static Value combine(Value left, Value right)
|
||||
{
|
||||
MutableComponent text;
|
||||
if (left instanceof final FormattedTextValue ftv)
|
||||
if (left instanceof FormattedTextValue ftv)
|
||||
{
|
||||
text = ftv.getText().copy();
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public class FormattedTextValue extends StringValue
|
||||
text = Component.literal(left.getString());
|
||||
}
|
||||
|
||||
if (right instanceof final FormattedTextValue ftv)
|
||||
if (right instanceof FormattedTextValue ftv)
|
||||
{
|
||||
text.append(ftv.getText().copy());
|
||||
return new FormattedTextValue(text);
|
||||
@@ -80,19 +80,13 @@ public class FormattedTextValue extends StringValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||
}
|
||||
return StringTag.valueOf(Component.Serializer.toJson(text));
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJson()
|
||||
{
|
||||
return Component.Serializer.toJsonTree(text);
|
||||
return StringTag.valueOf(Component.Serializer.toJson(text, regs));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,19 +95,19 @@ public class FormattedTextValue extends StringValue
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
public abstract class FrameworkValue extends Value
|
||||
@@ -29,7 +30,7 @@ public abstract class FrameworkValue extends Value
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
public class FunctionAnnotationValue extends Value
|
||||
@@ -41,7 +42,7 @@ public class FunctionAnnotationValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
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.function.Consumer;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
@@ -112,13 +113,13 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
@Override
|
||||
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
|
||||
public int compareTo(Value o)
|
||||
{
|
||||
if (o instanceof final FunctionValue fv)
|
||||
if (o instanceof FunctionValue fv)
|
||||
{
|
||||
int nameSame = this.name.compareTo(fv.name);
|
||||
return nameSame != 0 ? nameSame : (int) (variant - fv.variant);
|
||||
@@ -303,7 +304,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
@@ -238,7 +239,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.DoubleTag;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
@@ -129,7 +130,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
public Value add(Value other)
|
||||
{
|
||||
ListValue output = new ListValue();
|
||||
if (other instanceof final ListValue list)
|
||||
if (other instanceof ListValue list)
|
||||
{
|
||||
List<Value> otherItems = list.items;
|
||||
if (otherItems.size() == items.size())
|
||||
@@ -164,7 +165,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
public Value subtract(Value other)
|
||||
{
|
||||
ListValue output = new ListValue();
|
||||
if (other instanceof final ListValue list)
|
||||
if (other instanceof ListValue list)
|
||||
{
|
||||
List<Value> otherItems = list.items;
|
||||
if (otherItems.size() == items.size())
|
||||
@@ -199,7 +200,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
public Value multiply(Value other)
|
||||
{
|
||||
ListValue output = new ListValue();
|
||||
if (other instanceof final ListValue list)
|
||||
if (other instanceof ListValue list)
|
||||
{
|
||||
List<Value> otherItems = list.items;
|
||||
if (otherItems.size() == items.size())
|
||||
@@ -228,7 +229,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
public Value divide(Value other)
|
||||
{
|
||||
ListValue output = new ListValue();
|
||||
if (other instanceof final ListValue list)
|
||||
if (other instanceof ListValue list)
|
||||
{
|
||||
List<Value> otherItems = list.items;
|
||||
if (otherItems.size() == items.size())
|
||||
@@ -256,7 +257,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
@Override
|
||||
public int compareTo(Value o)
|
||||
{
|
||||
if (o instanceof final ListValue ol)
|
||||
if (o instanceof ListValue ol)
|
||||
{
|
||||
int size = this.getItems().size();
|
||||
int otherSize = ol.getItems().size();
|
||||
@@ -284,7 +285,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
@Override
|
||||
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()
|
||||
@@ -555,7 +556,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
int argSize = items.size();
|
||||
if (argSize == 0)
|
||||
@@ -565,12 +566,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
ListTag tag = new ListTag();
|
||||
if (argSize == 1)
|
||||
{
|
||||
tag.add(items.get(0).toTag(force));
|
||||
tag.add(items.get(0).toTag(force, regs));
|
||||
return tag;
|
||||
}
|
||||
// figuring out the types
|
||||
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);
|
||||
tags.forEach(t -> cases.add(TagTypeCompat.getType(t)));
|
||||
if (cases.size() == 1) // well, one type of items
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
@@ -104,11 +105,11 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
public Value add(Value o)
|
||||
{
|
||||
Map<Value, Value> newItems = new HashMap<>(map);
|
||||
if (o instanceof final MapValue mapValue)
|
||||
if (o instanceof MapValue mapValue)
|
||||
{
|
||||
newItems.putAll(mapValue.map);
|
||||
}
|
||||
else if (o instanceof final AbstractListValue alv)
|
||||
else if (o instanceof AbstractListValue alv)
|
||||
{
|
||||
for (Value value : alv)
|
||||
{
|
||||
@@ -142,7 +143,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
|
||||
public void put(Value v)
|
||||
{
|
||||
if (!(v instanceof final ListValue pair))
|
||||
if (!(v instanceof ListValue pair))
|
||||
{
|
||||
map.put(v, Value.NULL);
|
||||
return;
|
||||
@@ -169,7 +170,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
@Override
|
||||
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()
|
||||
@@ -249,7 +250,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
CompoundTag tag = new CompoundTag();
|
||||
map.forEach((k, v) ->
|
||||
@@ -258,7 +259,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
{
|
||||
throw new NBTSerializableValue.IncompatibleTypeException(k);
|
||||
}
|
||||
tag.put(k.getString(), v.toTag(force));
|
||||
tag.put(k.getString(), v.toTag(force, regs));
|
||||
});
|
||||
return tag;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import net.minecraft.commands.arguments.item.ItemParser;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
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.CompoundTag;
|
||||
import net.minecraft.nbt.EndTag;
|
||||
@@ -104,16 +104,12 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
nbtSupplier = tagSupplier;
|
||||
}
|
||||
|
||||
public static Value fromStack(ItemStack stack)
|
||||
{
|
||||
if (stack.hasTag())
|
||||
public static Value fromStack(ItemStack stack, RegistryAccess regs)
|
||||
{
|
||||
NBTSerializableValue value = new NBTSerializableValue();
|
||||
value.nbtSupplier = stack::getTag;
|
||||
value.nbtSupplier = () -> stack.saveOptional(regs);
|
||||
return value;
|
||||
}
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
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<>();
|
||||
|
||||
public static ItemInput parseItem(String itemString, RegistryAccess regs)
|
||||
public static ItemStack parseItem(String itemString, RegistryAccess 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
|
||||
{
|
||||
ItemInput res = itemCache.get(itemString); // [SCARY SHIT] persistent caches over server reloads
|
||||
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));
|
||||
res = new ItemInput(parser.item(), parser.nbt());
|
||||
res = new ItemInput(parser.item(), parser.components());
|
||||
|
||||
itemCache.put(itemString, res);
|
||||
if (itemCache.size() > 64000)
|
||||
{
|
||||
itemCache.clear();
|
||||
}
|
||||
return customTag == null ? res : new ItemInput(Holder.direct(res.getItem()), customTag);
|
||||
return res.createItemStack(1, false);
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
@@ -764,7 +763,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ package carpet.script.value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import com.google.gson.JsonElement;
|
||||
@@ -89,7 +90,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ package carpet.script.value;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -27,7 +28,7 @@ public class NumericValue extends Value
|
||||
|
||||
public static NumericValue asNumber(Value v1, String id)
|
||||
{
|
||||
if (v1 instanceof final NumericValue nv)
|
||||
if (v1 instanceof NumericValue nv)
|
||||
{
|
||||
return nv;
|
||||
}
|
||||
@@ -36,7 +37,7 @@ public class NumericValue extends Value
|
||||
|
||||
public static NumericValue asNumber(Value v1)
|
||||
{
|
||||
if (v1 instanceof final NumericValue nv)
|
||||
if (v1 instanceof NumericValue nv)
|
||||
{
|
||||
return nv;
|
||||
}
|
||||
@@ -129,7 +130,7 @@ public class NumericValue extends Value
|
||||
@Override
|
||||
public Value add(Value v)
|
||||
{ // 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);
|
||||
}
|
||||
@@ -139,7 +140,7 @@ public class NumericValue extends Value
|
||||
@Override
|
||||
public Value subtract(Value v)
|
||||
{ // 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);
|
||||
}
|
||||
@@ -149,7 +150,7 @@ public class NumericValue extends Value
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
@@ -159,7 +160,7 @@ public class NumericValue extends Value
|
||||
@Override
|
||||
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
|
||||
@@ -175,7 +176,7 @@ public class NumericValue extends Value
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -185,13 +186,13 @@ public class NumericValue extends Value
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o instanceof final Value otherValue)
|
||||
if (o instanceof Value otherValue)
|
||||
{
|
||||
if (otherValue.isNull())
|
||||
{
|
||||
return o.equals(this);
|
||||
}
|
||||
if (o instanceof final NumericValue no)
|
||||
if (o instanceof NumericValue no)
|
||||
{
|
||||
if (longValue != null && no.longValue != null)
|
||||
{
|
||||
@@ -279,7 +280,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (longValue != null)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.Map;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
@@ -373,18 +374,25 @@ public class ScreenValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (this.screenHandler == null)
|
||||
{
|
||||
return Value.NULL.toTag(true);
|
||||
return Value.NULL.toTag(true, regs);
|
||||
}
|
||||
|
||||
ListTag nbtList = new ListTag();
|
||||
for (int i = 0; i < this.screenHandler.slots.size(); i++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
@@ -46,7 +47,7 @@ public class StringValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
return StringTag.valueOf(str);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
public class ThreadValue extends LazyListValue
|
||||
@@ -108,13 +109,13 @@ public class ThreadValue extends LazyListValue
|
||||
@Override
|
||||
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
|
||||
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");
|
||||
}
|
||||
@@ -128,13 +129,13 @@ public class ThreadValue extends LazyListValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||
}
|
||||
return getValue().toTag(true);
|
||||
return getValue().toTag(true, regs);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,7 @@ package carpet.script.value;
|
||||
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import com.google.gson.JsonElement;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
public class UndefValue extends NullValue
|
||||
@@ -87,7 +88,7 @@ public class UndefValue extends NullValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
public Tag toTag(boolean force, RegistryAccess regs)
|
||||
{
|
||||
throw getError();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -97,7 +98,7 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
||||
|
||||
public Value divide(Value v)
|
||||
{
|
||||
if (v instanceof final NumericValue number)
|
||||
if (v instanceof NumericValue number)
|
||||
{
|
||||
String lstr = getString();
|
||||
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
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o instanceof final Value v)
|
||||
if (o instanceof Value v)
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -8,14 +8,12 @@ import carpet.script.utils.Colors;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraft.advancements.critereon.MinMaxBounds;
|
||||
import net.minecraft.commands.arguments.item.ItemInput;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.GlobalPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
@@ -58,8 +56,6 @@ import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
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)
|
||||
{
|
||||
return stack == null || stack.isEmpty() ? Value.NULL : ListValue.of(
|
||||
of(regs.registryOrThrow(Registries.ITEM).getKey(stack.getItem())),
|
||||
new NumericValue(stack.getCount()),
|
||||
NBTSerializableValue.fromStack(stack)
|
||||
NBTSerializableValue.fromStack(stack, regs)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -503,22 +489,9 @@ public class ValueConversions
|
||||
{
|
||||
name = value.getString();
|
||||
}
|
||||
ItemInput itemInput = NBTSerializableValue.parseItem(name, nbtTag, regs);
|
||||
try
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
ItemStack itemInput = NBTSerializableValue.parseItem(name, nbtTag, regs);
|
||||
itemInput.setCount(count);
|
||||
return itemInput;
|
||||
}
|
||||
|
||||
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(""));
|
||||
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 in air: %s", !state.isPathfindable(world,pos, 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 on land: %s", !state.isPathfindable(PathComputationType.LAND))));
|
||||
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(PathComputationType.WATER))));
|
||||
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(" - 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.level.StructureManager;
|
||||
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.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride;
|
||||
|
||||
Reference in new issue
Block a user