Merge remote-tracking branch 'upstream/master' into 26.3
Development Builds / Build (push) Canceled after 0s
Development Builds / Build (push) Canceled after 0s
This commit is contained in:
commit
3729e96e81
62 files changed
+649
-833
No files matched your search
+4
-4
@@ -7,12 +7,12 @@ org.gradle.configuration-cache=false
|
|||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check https://fabricmc.net/develop/
|
# check https://fabricmc.net/develop/
|
||||||
minecraft_version=26.3-snapshot-9
|
minecraft_version=26.3
|
||||||
loader_version=0.19.3
|
loader_version=0.19.5
|
||||||
loom_version=1.17-SNAPSHOT
|
loom_version=1.17-SNAPSHOT
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 26.3-beta-3
|
mod_version = 26.3
|
||||||
maven_group = carpet
|
maven_group = carpet
|
||||||
archives_base_name = fabric-carpet
|
archives_base_name = fabric-carpet
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ org.gradle.configuration-cache=false
|
|||||||
# The Curseforge versions "names" or ids for the main branch (comma separated: 1.16.4,1.16.5)
|
# The Curseforge versions "names" or ids for the main branch (comma separated: 1.16.4,1.16.5)
|
||||||
# This is needed because CF uses too vague names for prereleases and release candidates
|
# This is needed because CF uses too vague names for prereleases and release candidates
|
||||||
# Can also be the version ID directly coming from https://minecraft.curseforge.com/api/game/versions?token=[API_TOKEN]
|
# Can also be the version ID directly coming from https://minecraft.curseforge.com/api/game/versions?token=[API_TOKEN]
|
||||||
release-curse-versions = Minecraft 26.3:26.3-Snapshot
|
release-curse-versions = Minecraft 26.3:26.3
|
||||||
# Whether or not to build another branch on release
|
# Whether or not to build another branch on release
|
||||||
release-extra-branch = false
|
release-extra-branch = false
|
||||||
# The name of the second branch to release
|
# The name of the second branch to release
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package carpet.fakes;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
|
|
||||||
|
|
||||||
public interface RandomStateVisitorAccessor {
|
|
||||||
DensityFunction.Visitor getVisitor();
|
|
||||||
}
|
|
||||||
@@ -49,11 +49,11 @@ public abstract class Explosion_scarpetEventMixin
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "explode", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerExplosion;hurtEntities()V", shift = At.Shift.AFTER))
|
@Inject(method = "explode", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerExplosion;hurtEntities()V", shift = At.Shift.AFTER))
|
||||||
private void onExplosionDone(CallbackInfoReturnable<Integer> cir, List list)
|
private void onExplosionDone(CallbackInfoReturnable<Integer> cir, List toBlow)
|
||||||
{
|
{
|
||||||
if (EXPLOSION_OUTCOME.isNeeded() && !level.isClientSide())
|
if (EXPLOSION_OUTCOME.isNeeded() && !level.isClientSide())
|
||||||
{
|
{
|
||||||
EXPLOSION_OUTCOME.onExplosion((ServerLevel) level, source, this::getIndirectSourceEntity, center, radius, fire, list, affectedEntities, blockInteraction);
|
EXPLOSION_OUTCOME.onExplosion((ServerLevel) level, source, this::getIndirectSourceEntity, center, radius, fire, toBlow, affectedEntities, blockInteraction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,21 +18,28 @@ public abstract class Inventory_scarpetEventMixin
|
|||||||
{
|
{
|
||||||
@Shadow @Final public Player player;
|
@Shadow @Final public Player player;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
public static int NOT_FOUND_INDEX;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract boolean add(int slot, ItemStack itemStack);
|
||||||
|
|
||||||
@Redirect(method = "add(Lnet/minecraft/world/item/ItemStack;)Z", at = @At(
|
@Redirect(method = "add(Lnet/minecraft/world/item/ItemStack;)Z", at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/world/entity/player/Inventory;add(ILnet/minecraft/world/item/ItemStack;)Z"
|
target = "Lnet/minecraft/world/entity/player/Inventory;add(ILnet/minecraft/world/item/ItemStack;)Z"
|
||||||
))
|
))
|
||||||
private boolean onItemAcquired(Inventory playerInventory, int slot, ItemStack stack)
|
private boolean onItemAcquired(Inventory playerInventory, int slot, ItemStack itemStack)
|
||||||
{
|
{
|
||||||
if (!PLAYER_PICKS_UP_ITEM.isNeeded() || !(player instanceof ServerPlayer))
|
if (!PLAYER_PICKS_UP_ITEM.isNeeded() || !(player instanceof final ServerPlayer serverPlayer))
|
||||||
return playerInventory.add(-1, stack);
|
return add(NOT_FOUND_INDEX, itemStack);
|
||||||
int count = stack.getCount();
|
int count = itemStack.getCount();
|
||||||
ItemStack previous = stack.copy();
|
ItemStack prevStack = itemStack.copy();
|
||||||
boolean res = playerInventory.add(-1, stack);
|
boolean res = add(NOT_FOUND_INDEX, itemStack);
|
||||||
if (count != stack.getCount()) // res returns false for larger item adding to a almost full ineventory
|
if (count != itemStack.getCount()) // res returns false for larger item adding to a almost full ineventory
|
||||||
{
|
{
|
||||||
ItemStack diffStack = previous.copyWithCount(count - stack.getCount());
|
ItemStack diffStack = prevStack.copyWithCount(count - itemStack.getCount());
|
||||||
PLAYER_PICKS_UP_ITEM.onItemAction((ServerPlayer) player, null, diffStack);
|
PLAYER_PICKS_UP_ITEM.onItemAction(serverPlayer, null, diffStack);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class PersistentEntitySectionManager_scarpetMixin
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.error("Failed to handle entity type " + entity.getType().getDescriptionId());
|
CarpetScriptServer.LOG.error("Failed to handle entity type {}", entity.getType().getDescriptionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
event = CarpetEventServer.Event.ENTITY_LOAD.get(entity.getType());
|
event = CarpetEventServer.Event.ENTITY_LOAD.get(entity.getType());
|
||||||
@@ -43,7 +43,7 @@ public class PersistentEntitySectionManager_scarpetMixin
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.error("Failed to handle entity type " + entity.getType().getDescriptionId());
|
CarpetScriptServer.LOG.error("Failed to handle entity type {}", entity.getType().getDescriptionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
package carpet.mixins;
|
|
||||||
|
|
||||||
import carpet.fakes.RandomStateVisitorAccessor;
|
|
||||||
import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
|
|
||||||
import net.minecraft.world.level.levelgen.RandomState;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|
||||||
|
|
||||||
@Mixin(RandomState.class)
|
|
||||||
public class RandomState_ScarpetMixin implements RandomStateVisitorAccessor {
|
|
||||||
@Unique
|
|
||||||
private DensityFunction.Visitor visitor;
|
|
||||||
|
|
||||||
@ModifyArg(
|
|
||||||
method = "<init>",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/world/level/levelgen/NoiseRouter;mapAll(Lnet/minecraft/world/level/levelgen/densityfunction/DensityFunction$Visitor;)Lnet/minecraft/world/level/levelgen/NoiseRouter;"
|
|
||||||
),
|
|
||||||
index = 0
|
|
||||||
)
|
|
||||||
private DensityFunction.Visitor captureVisitor(DensityFunction.Visitor visitor) {
|
|
||||||
this.visitor = visitor;
|
|
||||||
return visitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DensityFunction.Visitor getVisitor() {
|
|
||||||
return this.visitor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -27,7 +27,7 @@ public abstract class ServerChunkCacheMixin
|
|||||||
|
|
||||||
@Shadow @Final private DistanceManager distanceManager;
|
@Shadow @Final private DistanceManager distanceManager;
|
||||||
|
|
||||||
@Redirect(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At(
|
@Redirect(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/server/level/DistanceManager;getNaturalSpawnChunkCount()I"
|
target = "Lnet/minecraft/server/level/DistanceManager;getNaturalSpawnChunkCount()I"
|
||||||
))
|
))
|
||||||
@@ -54,7 +54,7 @@ public abstract class ServerChunkCacheMixin
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At("RETURN"))
|
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At("RETURN"))
|
||||||
private void onFinishSpawnWorldCycle(CallbackInfo ci)
|
private void onFinishSpawnWorldCycle(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
LevelData levelData = this.level.getLevelData(); // levelProperies class
|
LevelData levelData = this.level.getLevelData(); // levelProperies class
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ public abstract class ServerChunkCache_profilerMixin
|
|||||||
|
|
||||||
CarpetProfiler.ProfilerToken currentSection;
|
CarpetProfiler.ProfilerToken currentSection;
|
||||||
|
|
||||||
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At("HEAD"))
|
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At("HEAD"))
|
||||||
private void startSpawningSection(CallbackInfo ci)
|
private void startSpawningSection(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
currentSection = CarpetProfiler.start_section(level, "Spawning", CarpetProfiler.TYPE.GENERAL);
|
currentSection = CarpetProfiler.start_section(level, "Spawning", CarpetProfiler.TYPE.GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At("RETURN"))
|
@Inject(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At("RETURN"))
|
||||||
private void stopSpawningSection(CallbackInfo ci)
|
private void stopSpawningSection(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (currentSection != null)
|
if (currentSection != null)
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ public abstract class ServerGamePacketListenerImpl_antiCheatDisabledMixin extend
|
|||||||
return isSingleplayerOwner() || CarpetSettings.antiCheatDisabled;
|
return isSingleplayerOwner() || CarpetSettings.antiCheatDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "handleMovePlayer", require = 0, // don't crash with immersive portals,
|
@Redirect(method = "handlePlayerPositionChange", require = 0, // don't crash with immersive portals,
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/server/level/ServerPlayer;isChangingDimension()Z"))
|
target = "Lnet/minecraft/server/level/ServerPlayer;isChangingDimension()Z"))
|
||||||
|
|||||||
@@ -122,11 +122,11 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "handleMovePlayer", at = @At(
|
@Inject(method = "handlePlayerPositionChange", at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/server/level/ServerPlayer;jumpFromGround()V"
|
target = "Lnet/minecraft/server/level/ServerPlayer;jumpFromGround()V"
|
||||||
))
|
))
|
||||||
private void onJump(ServerboundMovePlayerPacket playerMoveC2SPacket_1, CallbackInfo ci)
|
private void onJump(double requestedX, double requestedY, double requestedZ, float requestedYRot, float requestedXRot, boolean isOnGround, boolean horizontalCollision, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
PLAYER_JUMPS.onPlayerEvent(player);
|
PLAYER_JUMPS.onPlayerEvent(player);
|
||||||
}
|
}
|
||||||
@@ -152,28 +152,29 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
|
|||||||
{
|
{
|
||||||
if (PLAYER_RELEASED_ITEM.isNeeded())
|
if (PLAYER_RELEASED_ITEM.isNeeded())
|
||||||
{
|
{
|
||||||
InteractionHand hand = serverPlayerEntity.getUsedItemHand();
|
InteractionHand hand = player.getUsedItemHand();
|
||||||
ItemStack stack = serverPlayerEntity.getUseItem().copy();
|
ItemStack stack = player.getUseItem().copy();
|
||||||
serverPlayerEntity.releaseUsingItem();
|
player.releaseUsingItem();
|
||||||
PLAYER_RELEASED_ITEM.onItemAction(player, hand, stack);
|
PLAYER_RELEASED_ITEM.onItemAction(player, hand, stack);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
serverPlayerEntity.releaseUsingItem();
|
player.releaseUsingItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "handleUseItemOn", cancellable = true, at = @At(
|
@Inject(method = "handleUseItemOn", cancellable = true, at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/server/level/ServerPlayerGameMode;useItemOn(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/InteractionResult;"
|
target = "Lnet/minecraft/server/level/ServerPlayerGameMode;useItemOn(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/InteractionResult;",
|
||||||
|
shift = At.Shift.BEFORE
|
||||||
))
|
))
|
||||||
private void onBlockInteracted(ServerboundUseItemOnPacket playerInteractBlockC2SPacket_1, CallbackInfo ci)
|
private void onBlockInteracted(ServerboundUseItemOnPacket packet, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (PLAYER_RIGHT_CLICKS_BLOCK.isNeeded())
|
if (PLAYER_RIGHT_CLICKS_BLOCK.isNeeded())
|
||||||
{
|
{
|
||||||
InteractionHand hand = playerInteractBlockC2SPacket_1.hand();
|
InteractionHand handd = packet.hand();
|
||||||
BlockHitResult hitRes = playerInteractBlockC2SPacket_1.hitResult();
|
BlockHitResult hitRes = packet.hitResult();
|
||||||
if(PLAYER_RIGHT_CLICKS_BLOCK.onBlockHit(player, hand, hitRes)) {
|
if(PLAYER_RIGHT_CLICKS_BLOCK.onBlockHit(player, handd, hitRes)) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,11 +184,11 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
|
|||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/server/level/ServerPlayer;resetLastActionTime()V"
|
target = "Lnet/minecraft/server/level/ServerPlayer;resetLastActionTime()V"
|
||||||
))
|
))
|
||||||
private void onItemClicked(ServerboundUseItemPacket playerInteractItemC2SPacket_1, CallbackInfo ci)
|
private void onItemClicked(ServerboundUseItemPacket packet, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (PLAYER_USES_ITEM.isNeeded())
|
if (PLAYER_USES_ITEM.isNeeded())
|
||||||
{
|
{
|
||||||
InteractionHand hand = playerInteractItemC2SPacket_1.hand();
|
InteractionHand hand = packet.hand();
|
||||||
if(PLAYER_USES_ITEM.onItemAction(player, hand, player.getItemInHand(hand).copy())) {
|
if(PLAYER_USES_ITEM.onItemAction(player, hand, player.getItemInHand(hand).copy())) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
@@ -283,10 +284,10 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
|
|||||||
@Inject(method = "lambda$handleChatCommand$0", // lambda of handleChatCommand(ServerboundChatCommandPacket)
|
@Inject(method = "lambda$handleChatCommand$0", // lambda of handleChatCommand(ServerboundChatCommandPacket)
|
||||||
at = @At(value = "HEAD")
|
at = @At(value = "HEAD")
|
||||||
)
|
)
|
||||||
private void onChatCommandMessage(ServerboundChatCommandPacket serverboundChatCommandPacket, CallbackInfo ci) {
|
private void onChatCommandMessage(ServerboundChatCommandPacket packet, CallbackInfo ci) {
|
||||||
if (PLAYER_COMMAND.isNeeded())
|
if (PLAYER_COMMAND.isNeeded())
|
||||||
{
|
{
|
||||||
PLAYER_COMMAND.onPlayerMessage(player, serverboundChatCommandPacket.command());
|
PLAYER_COMMAND.onPlayerMessage(player, packet.command());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,10 +69,10 @@ public abstract class ServerLevel_scarpetMixin extends Level
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "explode", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "explode", at = @At("HEAD"), cancellable = true)
|
||||||
private void handleExplosion(Entity entity, DamageSource damageSource, ExplosionDamageCalculator explosionDamageCalculator, double x, double y, double z, float g, boolean bl, ExplosionInteraction explosionInteraction, ParticleOptions particleOptions, ParticleOptions particleOptions2, WeightedList<ExplosionParticleInfo> weightedList, Holder<SoundEvent> holder, CallbackInfo ci)
|
private void handleExplosion(Entity source, DamageSource damageSource, ExplosionDamageCalculator damageCalculator, double x, double y, double z, float r, boolean fire, ExplosionInteraction interactionType, ParticleOptions smallExplosionParticles, ParticleOptions largeExplosionParticles, WeightedList<ExplosionParticleInfo> blockParticles, Holder<SoundEvent> explosionSound, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (EXPLOSION.isNeeded()) {
|
if (EXPLOSION.isNeeded()) {
|
||||||
Explosion.BlockInteraction var10000 = switch (explosionInteraction) {
|
Explosion.BlockInteraction var10000 = switch (interactionType) {
|
||||||
case NONE -> Explosion.BlockInteraction.KEEP;
|
case NONE -> Explosion.BlockInteraction.KEEP;
|
||||||
case BLOCK -> this.getCMDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY);
|
case BLOCK -> this.getCMDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY);
|
||||||
case MOB -> this.getGameRules().get(GameRules.MOB_GRIEFING) ? this.getCMDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP;
|
case MOB -> this.getGameRules().get(GameRules.MOB_GRIEFING) ? this.getCMDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP;
|
||||||
@@ -80,7 +80,7 @@ public abstract class ServerLevel_scarpetMixin extends Level
|
|||||||
case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK;
|
case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK;
|
||||||
};
|
};
|
||||||
|
|
||||||
boolean cancelled = EXPLOSION.onExplosion((ServerLevel) (Object) this, entity, null, new Vec3(x, y, z), g, bl, null, null, var10000);
|
boolean cancelled = EXPLOSION.onExplosion((ServerLevel) (Object) this, source, null, new Vec3(x, y, z), r, fire, null, null, var10000);
|
||||||
if (cancelled) ci.cancel();
|
if (cancelled) ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,8 +88,7 @@ public class CarpetEventServer
|
|||||||
public static class Callback
|
public static class Callback
|
||||||
{
|
{
|
||||||
public final String host;
|
public final String host;
|
||||||
@Nullable
|
public final @Nullable String optionalTarget;
|
||||||
public final String optionalTarget;
|
|
||||||
public final FunctionValue function;
|
public final FunctionValue function;
|
||||||
public final List<Value> parametrizedArgs;
|
public final List<Value> parametrizedArgs;
|
||||||
public final CarpetScriptServer scriptServer;
|
public final CarpetScriptServer scriptServer;
|
||||||
@@ -382,15 +381,15 @@ public class CarpetEventServer
|
|||||||
public void removeEventCall(String hostName, String target, String funName)
|
public void removeEventCall(String hostName, String target, String funName)
|
||||||
{
|
{
|
||||||
removeCallsIf((c) -> c.function.getString().equals(funName)
|
removeCallsIf((c) -> c.function.getString().equals(funName)
|
||||||
&& (Objects.equals(c.host, hostName))
|
&& Objects.equals(c.host, hostName)
|
||||||
&& (Objects.equals(c.optionalTarget, target))
|
&& Objects.equals(c.optionalTarget, target)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAllCalls(CarpetScriptHost host)
|
public void removeAllCalls(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
removeCallsIf((c) -> (Objects.equals(c.host, host.getName()))
|
removeCallsIf((c) -> Objects.equals(c.host, host.getName())
|
||||||
&& (Objects.equals(c.optionalTarget, host.user)));
|
&& Objects.equals(c.optionalTarget, host.user));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createChildEvents(CarpetScriptHost host)
|
public void createChildEvents(CarpetScriptHost host)
|
||||||
@@ -398,7 +397,7 @@ public class CarpetEventServer
|
|||||||
List<Callback> copyCalls = new ArrayList<>();
|
List<Callback> copyCalls = new ArrayList<>();
|
||||||
callList.forEach((c) ->
|
callList.forEach((c) ->
|
||||||
{
|
{
|
||||||
if ((Objects.equals(c.host, host.getName())) // TODO fix me
|
if (Objects.equals(c.host, host.getName()) // TODO fix me
|
||||||
&& c.optionalTarget == null)
|
&& c.optionalTarget == null)
|
||||||
{
|
{
|
||||||
copyCalls.add(new Callback(c.host, host.user, c.function, c.parametrizedArgs, host.scriptServer()));
|
copyCalls.add(new Callback(c.host, host.user, c.function, c.parametrizedArgs, host.scriptServer()));
|
||||||
|
|||||||
@@ -772,62 +772,50 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
String sign = "";
|
String sign = "";
|
||||||
for (Token tok : Tokenizer.simple(arg).parseTokens())
|
for (Token tok : Tokenizer.simple(arg).parseTokens())
|
||||||
{
|
{
|
||||||
switch (tok.type)
|
switch (tok.type) {
|
||||||
{
|
case VARIABLE -> {
|
||||||
case VARIABLE:
|
|
||||||
LazyValue variable = getGlobalVariable(tok.surface);
|
LazyValue variable = getGlobalVariable(tok.surface);
|
||||||
if (variable != null)
|
if (variable != null) {
|
||||||
{
|
|
||||||
argv.add(variable);
|
argv.add(variable);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case STRINGPARAM:
|
case STRINGPARAM -> {
|
||||||
argv.add((c, t) -> new StringValue(tok.surface));
|
argv.add((c, t) -> new StringValue(tok.surface));
|
||||||
sign = "";
|
sign = "";
|
||||||
break;
|
}
|
||||||
|
case LITERAL -> {
|
||||||
case LITERAL:
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
String finalSign = sign;
|
String finalSign = sign;
|
||||||
argv.add((c, t) -> new NumericValue(finalSign + tok.surface));
|
argv.add((c, t) -> new NumericValue(finalSign + tok.surface));
|
||||||
sign = "";
|
sign = "";
|
||||||
}
|
} catch (NumberFormatException exception) {
|
||||||
catch (NumberFormatException exception)
|
|
||||||
{
|
|
||||||
throw new CarpetExpressionException("Fail: " + sign + tok.surface + " seems like a number but it is" +
|
throw new CarpetExpressionException("Fail: " + sign + tok.surface + " seems like a number but it is" +
|
||||||
" not a number. Use quotes to ensure its a string", null);
|
" not a number. Use quotes to ensure its a string", null);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case HEX_LITERAL:
|
case HEX_LITERAL -> {
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
String finalSign = sign;
|
String finalSign = sign;
|
||||||
argv.add((c, t) -> new NumericValue(new BigInteger(finalSign + tok.surface.substring(2), 16).doubleValue()));
|
argv.add((c, t) -> new NumericValue(new BigInteger(finalSign + tok.surface.substring(2), 16).doubleValue()));
|
||||||
sign = "";
|
sign = "";
|
||||||
}
|
} catch (NumberFormatException exception) {
|
||||||
catch (NumberFormatException exception)
|
|
||||||
{
|
|
||||||
throw new CarpetExpressionException("Fail: " + sign + tok.surface + " seems like a number but it is" +
|
throw new CarpetExpressionException("Fail: " + sign + tok.surface + " seems like a number but it is" +
|
||||||
" not a number. Use quotes to ensure its a string", null);
|
" not a number. Use quotes to ensure its a string", null);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case OPERATOR, UNARY_OPERATOR:
|
case OPERATOR, UNARY_OPERATOR -> {
|
||||||
if ((tok.surface.equals("-") || tok.surface.equals("-u")) && sign.isEmpty())
|
if ((tok.surface.equals("-") || tok.surface.equals("-u")) && sign.isEmpty()) {
|
||||||
{
|
|
||||||
sign = "-";
|
sign = "-";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new CarpetExpressionException("Fail: operators, like " + tok.surface + " are not " +
|
throw new CarpetExpressionException("Fail: operators, like " + tok.surface + " are not " +
|
||||||
"allowed in invoke", null);
|
"allowed in invoke", null);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case FUNCTION:
|
case FUNCTION ->
|
||||||
throw new CarpetExpressionException("Fail: passing functions like " + tok.surface + "() to invoke is " +
|
throw new CarpetExpressionException("Fail: passing functions like " + tok.surface + "() to invoke is " +
|
||||||
"not allowed", null);
|
"not allowed", null);
|
||||||
case OPEN_PAREN, COMMA, CLOSE_PAREN, MARKER:
|
case OPEN_PAREN, COMMA, CLOSE_PAREN, MARKER ->
|
||||||
throw new CarpetExpressionException("Fail: " + tok.surface + " is not allowed in invoke", null);
|
throw new CarpetExpressionException("Fail: " + tok.surface + " is not allowed in invoke", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<String> args = function.getArguments();
|
List<String> args = function.getArguments();
|
||||||
@@ -1109,7 +1097,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Creates a {@link Component} using {@link carper.utils.Messenger} that has the locals in the {@code line} snippet with a hover over
|
* <p>Creates a {@link Component} using carpet.utils.Messenger that has the locals in the {@code line} snippet with a hover over
|
||||||
* tooltip with the value of the local at that location</p>
|
* tooltip with the value of the local at that location</p>
|
||||||
*
|
*
|
||||||
* @param line The line to find references to locals on
|
* @param line The line to find references to locals on
|
||||||
@@ -1189,7 +1177,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.error(intro + ": " + exception.getMessage());
|
CarpetScriptServer.LOG.error("{}", intro, exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a Scarpet App to be used as a Rule App (to be controlled with the value of a Carpet rule).
|
* Registers a Scarpet App to be used as a Rule App (to be controlled with the value of a Carpet rule).
|
||||||
* Libraries should be registered with {@link #registerBuiltInScript(BundledModule)} instead
|
* Libraries should be registered with #registerBuiltInScript(BundledModule) instead
|
||||||
*
|
*
|
||||||
* @param app The {@link Module} of the app.
|
* @param app The {@link Module} of the app.
|
||||||
* @see Module#fromJarPath(String, String, boolean)
|
* @see Module#fromJarPath(String, String, boolean)
|
||||||
@@ -159,7 +159,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Module globalModule = Carpet.fetchGlobalModule(name, allowLibraries);
|
Module globalModule = fetchGlobalModule(server, name, allowLibraries);
|
||||||
if (globalModule != null)
|
if (globalModule != null)
|
||||||
{
|
{
|
||||||
return globalModule;
|
return globalModule;
|
||||||
@@ -179,6 +179,53 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static @Nullable Module fetchGlobalModule(MinecraftServer server, String name, boolean allowLibraries) throws IOException
|
||||||
|
{
|
||||||
|
Path globalFolder = Carpet.fetchGlobalPath(server);
|
||||||
|
if (globalFolder == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!Files.exists(globalFolder))
|
||||||
|
{
|
||||||
|
Files.createDirectories(globalFolder);
|
||||||
|
}
|
||||||
|
try (Stream<Path> folderWalker = Files.walk(globalFolder))
|
||||||
|
{
|
||||||
|
Optional<Path> scriptPath = folderWalker
|
||||||
|
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
||||||
|
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
|
||||||
|
.findFirst();
|
||||||
|
if (scriptPath.isPresent())
|
||||||
|
{
|
||||||
|
return Module.fromPath(scriptPath.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addGlobalModules(final MinecraftServer server, final List<String> moduleNames, boolean includeBuiltIns) throws IOException
|
||||||
|
{
|
||||||
|
if (!includeBuiltIns)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Path globalScripts = Carpet.fetchGlobalPath(server);
|
||||||
|
if (globalScripts == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Files.exists(globalScripts))
|
||||||
|
{
|
||||||
|
Files.createDirectories(globalScripts);
|
||||||
|
}
|
||||||
|
try (Stream<Path> folderWalker = Files.walk(globalScripts, FileVisitOption.FOLLOW_LINKS))
|
||||||
|
{
|
||||||
|
folderWalker
|
||||||
|
.filter(f -> f.toString().endsWith(".sc"))
|
||||||
|
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$", "").toLowerCase(Locale.ROOT)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Module getRuleModule(String name)
|
public Module getRuleModule(String name)
|
||||||
{
|
{
|
||||||
for (Module moduleData : ruleModuleData)
|
for (Module moduleData : ruleModuleData)
|
||||||
@@ -218,7 +265,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$", "").toLowerCase(Locale.ROOT)));
|
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$", "").toLowerCase(Locale.ROOT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Carpet.addGlobalModules(moduleNames, includeBuiltIns);
|
addGlobalModules(server, moduleNames, includeBuiltIns);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
@@ -330,7 +377,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
}
|
}
|
||||||
token.run();
|
token.run();
|
||||||
long end = System.nanoTime();
|
long end = System.nanoTime();
|
||||||
LOG.info("App " + name + " loaded in " + (end - start) / 1000000 + " ms");
|
LOG.info("App {} loaded in {} ms", name, (end - start) / 1000000);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ public class Expression
|
|||||||
private boolean allowNewlineSubstitutions = true;
|
private boolean allowNewlineSubstitutions = true;
|
||||||
private boolean allowComments = false;
|
private boolean allowComments = false;
|
||||||
|
|
||||||
@Nullable
|
public @Nullable Module module = null;
|
||||||
public Module module = null;
|
|
||||||
|
|
||||||
public String getModuleName()
|
public String getModuleName()
|
||||||
{
|
{
|
||||||
@@ -93,11 +92,9 @@ public class Expression
|
|||||||
/**
|
/**
|
||||||
* Cached AST (Abstract Syntax Tree) (root) of the expression
|
* Cached AST (Abstract Syntax Tree) (root) of the expression
|
||||||
*/
|
*/
|
||||||
@Nullable
|
private @Nullable LazyValue ast = null;
|
||||||
private LazyValue ast = null;
|
|
||||||
|
|
||||||
@Nullable
|
private @Nullable ExpressionNode root = null;
|
||||||
private ExpressionNode root = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* script specific operatos and built-in functions
|
* script specific operatos and built-in functions
|
||||||
@@ -1102,118 +1099,94 @@ public class Expression
|
|||||||
Token previousToken = null;
|
Token previousToken = null;
|
||||||
for (Token token : tokens)
|
for (Token token : tokens)
|
||||||
{
|
{
|
||||||
switch (token.type)
|
switch (token.type) {
|
||||||
{
|
case STRINGPARAM,
|
||||||
case STRINGPARAM:
|
//stack.push(token); // changed that so strings are treated like literals
|
||||||
//stack.push(token); // changed that so strings are treated like literals
|
//break;
|
||||||
//break;
|
LITERAL, HEX_LITERAL -> {
|
||||||
case LITERAL, HEX_LITERAL:
|
|
||||||
if (previousToken != null && (
|
if (previousToken != null && (
|
||||||
previousToken.type == Token.TokenType.LITERAL ||
|
previousToken.type == Token.TokenType.LITERAL ||
|
||||||
previousToken.type == Token.TokenType.HEX_LITERAL ||
|
previousToken.type == Token.TokenType.HEX_LITERAL ||
|
||||||
previousToken.type == Token.TokenType.STRINGPARAM))
|
previousToken.type == Token.TokenType.STRINGPARAM)) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Missing operator");
|
throw new ExpressionException(c, this, token, "Missing operator");
|
||||||
}
|
}
|
||||||
outputQueue.add(token);
|
outputQueue.add(token);
|
||||||
break;
|
}
|
||||||
case VARIABLE:
|
case VARIABLE -> outputQueue.add(token);
|
||||||
outputQueue.add(token);
|
case FUNCTION -> {
|
||||||
break;
|
|
||||||
case FUNCTION:
|
|
||||||
stack.push(token);
|
stack.push(token);
|
||||||
lastFunction = token;
|
lastFunction = token;
|
||||||
break;
|
}
|
||||||
case COMMA:
|
case COMMA -> {
|
||||||
if (previousToken != null && previousToken.type == Token.TokenType.OPERATOR)
|
if (previousToken != null && previousToken.type == Token.TokenType.OPERATOR) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, previousToken, "Missing parameter(s) for operator ");
|
throw new ExpressionException(c, this, previousToken, "Missing parameter(s) for operator ");
|
||||||
}
|
}
|
||||||
while (!stack.isEmpty() && stack.top().type != Token.TokenType.OPEN_PAREN)
|
while (!stack.isEmpty() && stack.top().type != Token.TokenType.OPEN_PAREN) {
|
||||||
{
|
|
||||||
outputQueue.add(stack.pop());
|
outputQueue.add(stack.pop());
|
||||||
}
|
}
|
||||||
if (stack.isEmpty())
|
if (stack.isEmpty()) {
|
||||||
{
|
if (lastFunction == null) {
|
||||||
if (lastFunction == null)
|
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Unexpected comma");
|
throw new ExpressionException(c, this, token, "Unexpected comma");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, lastFunction, "Parse error for function");
|
throw new ExpressionException(c, this, lastFunction, "Parse error for function");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case OPERATOR:
|
case OPERATOR -> {
|
||||||
{
|
|
||||||
if (previousToken != null
|
if (previousToken != null
|
||||||
&& (previousToken.type == Token.TokenType.COMMA || previousToken.type == Token.TokenType.OPEN_PAREN))
|
&& (previousToken.type == Token.TokenType.COMMA || previousToken.type == Token.TokenType.OPEN_PAREN)) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator '" + token + "'");
|
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator '" + token + "'");
|
||||||
}
|
}
|
||||||
ILazyOperator o1 = operators.get(token.surface);
|
ILazyOperator o1 = operators.get(token.surface);
|
||||||
if (o1 == null)
|
if (o1 == null) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Unknown operator '" + token + "'");
|
throw new ExpressionException(c, this, token, "Unknown operator '" + token + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
shuntOperators(outputQueue, stack, o1);
|
shuntOperators(outputQueue, stack, o1);
|
||||||
stack.push(token);
|
stack.push(token);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case UNARY_OPERATOR:
|
case UNARY_OPERATOR -> {
|
||||||
{
|
|
||||||
if (previousToken != null && previousToken.type != Token.TokenType.OPERATOR
|
if (previousToken != null && previousToken.type != Token.TokenType.OPERATOR
|
||||||
&& previousToken.type != Token.TokenType.COMMA && previousToken.type != Token.TokenType.OPEN_PAREN)
|
&& previousToken.type != Token.TokenType.COMMA && previousToken.type != Token.TokenType.OPEN_PAREN) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Invalid position for unary operator " + token);
|
throw new ExpressionException(c, this, token, "Invalid position for unary operator " + token);
|
||||||
}
|
}
|
||||||
ILazyOperator o1 = operators.get(token.surface);
|
ILazyOperator o1 = operators.get(token.surface);
|
||||||
if (o1 == null)
|
if (o1 == null) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Unknown unary operator '" + token.surface.substring(0, token.surface.length() - 1) + "'");
|
throw new ExpressionException(c, this, token, "Unknown unary operator '" + token.surface.substring(0, token.surface.length() - 1) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
shuntOperators(outputQueue, stack, o1);
|
shuntOperators(outputQueue, stack, o1);
|
||||||
stack.push(token);
|
stack.push(token);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case OPEN_PAREN:
|
case OPEN_PAREN -> {
|
||||||
// removed implicit multiplication in this missing code block
|
// removed implicit multiplication in this missing code block
|
||||||
if (previousToken != null && previousToken.type == Token.TokenType.FUNCTION)
|
if (previousToken != null && previousToken.type == Token.TokenType.FUNCTION) {
|
||||||
{
|
|
||||||
outputQueue.add(token);
|
outputQueue.add(token);
|
||||||
}
|
}
|
||||||
stack.push(token);
|
stack.push(token);
|
||||||
break;
|
}
|
||||||
case CLOSE_PAREN:
|
case CLOSE_PAREN -> {
|
||||||
if (previousToken != null && previousToken.type == Token.TokenType.OPERATOR)
|
if (previousToken != null && previousToken.type == Token.TokenType.OPERATOR) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, previousToken, "Missing parameter(s) for operator " + previousToken);
|
throw new ExpressionException(c, this, previousToken, "Missing parameter(s) for operator " + previousToken);
|
||||||
}
|
}
|
||||||
while (!stack.isEmpty() && stack.top().type != Token.TokenType.OPEN_PAREN)
|
while (!stack.isEmpty() && stack.top().type != Token.TokenType.OPEN_PAREN) {
|
||||||
{
|
|
||||||
outputQueue.add(stack.pop());
|
outputQueue.add(stack.pop());
|
||||||
}
|
}
|
||||||
if (stack.isEmpty())
|
if (stack.isEmpty()) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, "Mismatched parentheses");
|
throw new ExpressionException(c, this, "Mismatched parentheses");
|
||||||
}
|
}
|
||||||
stack.pop();
|
stack.pop();
|
||||||
if (!stack.isEmpty() && stack.top().type == Token.TokenType.FUNCTION)
|
if (!stack.isEmpty() && stack.top().type == Token.TokenType.FUNCTION) {
|
||||||
{
|
|
||||||
outputQueue.add(stack.pop());
|
outputQueue.add(stack.pop());
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case MARKER:
|
case MARKER -> {
|
||||||
if ("$".equals(token.surface))
|
if ("$".equals(token.surface)) {
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder(expression);
|
StringBuilder sb = new StringBuilder(expression);
|
||||||
sb.setCharAt(token.pos, '\n');
|
sb.setCharAt(token.pos, '\n');
|
||||||
expression = sb.toString();
|
expression = sb.toString();
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
if (token.type != Token.TokenType.MARKER)
|
if (token.type != Token.TokenType.MARKER)
|
||||||
{
|
{
|
||||||
@@ -1437,7 +1410,7 @@ public class Expression
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExpressionNode newNode = new ExpressionNode(((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t)), Collections.emptyList(), token);
|
ExpressionNode newNode = new ExpressionNode((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t), Collections.emptyList(), token);
|
||||||
token.node = newNode;
|
token.node = newNode;
|
||||||
nodeStack.push(newNode);
|
nodeStack.push(newNode);
|
||||||
}
|
}
|
||||||
@@ -1767,7 +1740,7 @@ public class Expression
|
|||||||
boolean leftOptimizable = operators.get(operator).isLeftAssoc();
|
boolean leftOptimizable = operators.get(operator).isLeftAssoc();
|
||||||
ExpressionNode optimizedChild = node.args.get(leftOptimizable ? 0 : (node.args.size() - 1));
|
ExpressionNode optimizedChild = node.args.get(leftOptimizable ? 0 : (node.args.size() - 1));
|
||||||
String type = optimizedChild.token.surface;
|
String type = optimizedChild.token.surface;
|
||||||
if ((type.equals(operator) || type.equals(function)) && (!(optimizedChild.op instanceof LazyValue.ContextFreeLazyValue)))
|
if ((type.equals(operator) || type.equals(function)) && !(optimizedChild.op instanceof LazyValue.ContextFreeLazyValue))
|
||||||
{
|
{
|
||||||
List<ExpressionNode> newargs = new ArrayList<>();
|
List<ExpressionNode> newargs = new ArrayList<>();
|
||||||
if (leftOptimizable)
|
if (leftOptimizable)
|
||||||
@@ -1883,9 +1856,9 @@ public class Expression
|
|||||||
// applying argument unpacking
|
// applying argument unpacking
|
||||||
args = AbstractLazyFunction.lazify(AbstractLazyFunction.unpackLazy(args, ctx, requestedType));
|
args = AbstractLazyFunction.lazify(AbstractLazyFunction.unpackLazy(args, ctx, requestedType));
|
||||||
Value result;
|
Value result;
|
||||||
if (operation instanceof ILazyFunction)
|
if (operation instanceof final ILazyFunction iLazyFunction)
|
||||||
{
|
{
|
||||||
result = ((ILazyFunction) operation).lazyEval(ctx, expectedType, this, node.token, args).evalValue(null, expectedType);
|
result = iLazyFunction.lazyEval(ctx, expectedType, this, node.token, args).evalValue(null, expectedType);
|
||||||
}
|
}
|
||||||
else if (args.size() == 1)
|
else if (args.size() == 1)
|
||||||
{
|
{
|
||||||
@@ -1922,38 +1895,31 @@ public class Expression
|
|||||||
return (c, t) -> ret;
|
return (c, t) -> ret;
|
||||||
}
|
}
|
||||||
Token token = node.token;
|
Token token = node.token;
|
||||||
switch (token.type)
|
return switch (token.type) {
|
||||||
{
|
case UNARY_OPERATOR -> {
|
||||||
case UNARY_OPERATOR:
|
|
||||||
{
|
|
||||||
ILazyOperator op = operators.get(token.surface);
|
ILazyOperator op = operators.get(token.surface);
|
||||||
Context.Type requestedType = op.staticType(expectedType);
|
Context.Type requestedType = op.staticType(expectedType);
|
||||||
LazyValue arg = extractOp(ctx, node.args.get(0), requestedType);
|
LazyValue arg = extractOp(ctx, node.args.get(0), requestedType);
|
||||||
return (c, t) -> op.lazyEval(c, t, this, token, arg, null).evalValue(c, t);
|
yield (c, t) -> op.lazyEval(c, t, this, token, arg, null).evalValue(c, t);
|
||||||
}
|
}
|
||||||
case OPERATOR:
|
case OPERATOR -> {
|
||||||
{
|
|
||||||
ILazyOperator op = operators.get(token.surface);
|
ILazyOperator op = operators.get(token.surface);
|
||||||
Context.Type requestedType = op.staticType(expectedType);
|
Context.Type requestedType = op.staticType(expectedType);
|
||||||
LazyValue arg = extractOp(ctx, node.args.get(0), requestedType);
|
LazyValue arg = extractOp(ctx, node.args.get(0), requestedType);
|
||||||
LazyValue arh = extractOp(ctx, node.args.get(1), requestedType);
|
LazyValue arh = extractOp(ctx, node.args.get(1), requestedType);
|
||||||
return (c, t) -> op.lazyEval(c, t, this, token, arg, arh).evalValue(c, t);
|
yield (c, t) -> op.lazyEval(c, t, this, token, arg, arh).evalValue(c, t);
|
||||||
}
|
}
|
||||||
case VARIABLE:
|
case VARIABLE -> (c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t);
|
||||||
return (c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t);
|
case FUNCTION -> {
|
||||||
case FUNCTION:
|
|
||||||
{
|
|
||||||
ILazyFunction f = functions.get(token.surface);
|
ILazyFunction f = functions.get(token.surface);
|
||||||
Context.Type requestedType = f.staticType(expectedType);
|
Context.Type requestedType = f.staticType(expectedType);
|
||||||
List<LazyValue> params = node.args.stream().map(n -> extractOp(ctx, n, requestedType)).collect(Collectors.toList());
|
List<LazyValue> params = node.args.stream().map(n -> extractOp(ctx, n, requestedType)).collect(Collectors.toList());
|
||||||
return (c, t) -> f.lazyEval(c, t, this, token, params).evalValue(c, t);
|
yield (c, t) -> f.lazyEval(c, t, this, token, params).evalValue(c, t);
|
||||||
}
|
}
|
||||||
case CONSTANT:
|
case CONSTANT -> node.op;
|
||||||
return node.op;
|
default ->
|
||||||
default:
|
throw new ExpressionException(ctx, this, node.token, "Unexpected token '" + node.token.type + " " + node.token.surface + "'");
|
||||||
throw new ExpressionException(ctx, this, node.token, "Unexpected token '" + node.token.type + " " + node.token.surface + "'");
|
};
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validate(Context c, List<Token> rpn)
|
private void validate(Context c, List<Token> rpn)
|
||||||
@@ -1973,27 +1939,23 @@ public class Expression
|
|||||||
|
|
||||||
for (Token token : rpn)
|
for (Token token : rpn)
|
||||||
{
|
{
|
||||||
switch (token.type)
|
switch (token.type) {
|
||||||
{
|
case UNARY_OPERATOR -> {
|
||||||
case UNARY_OPERATOR:
|
if (stack.topInt() < 1) {
|
||||||
if (stack.topInt() < 1)
|
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator " + token);
|
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator " + token);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case OPERATOR:
|
case OPERATOR -> {
|
||||||
if (stack.topInt() < 2)
|
if (stack.topInt() < 2) {
|
||||||
{
|
if (token.surface.equals(";")) {
|
||||||
if (token.surface.equals(";"))
|
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Empty expression found for ';'");
|
throw new ExpressionException(c, this, token, "Empty expression found for ';'");
|
||||||
}
|
}
|
||||||
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator " + token);
|
throw new ExpressionException(c, this, token, "Missing parameter(s) for operator " + token);
|
||||||
}
|
}
|
||||||
// pop the operator's 2 parameters and add the result
|
// pop the operator's 2 parameters and add the result
|
||||||
stack.set(stack.size() - 1, stack.topInt() - 2 + 1);
|
stack.set(stack.size() - 1, stack.topInt() - 2 + 1);
|
||||||
break;
|
}
|
||||||
case FUNCTION:
|
case FUNCTION -> {
|
||||||
//ILazyFunction f = functions.get(token.surface);// don't validate global - userdef functions
|
//ILazyFunction f = functions.get(token.surface);// don't validate global - userdef functions
|
||||||
//int numParams = stack.pop();
|
//int numParams = stack.pop();
|
||||||
//if (f != null && !f.numParamsVaries() && numParams != f.getNumParams())
|
//if (f != null && !f.numParamsVaries() && numParams != f.getNumParams())
|
||||||
@@ -2004,18 +1966,14 @@ public class Expression
|
|||||||
// due to unpacking, all functions can have variable number of arguments
|
// due to unpacking, all functions can have variable number of arguments
|
||||||
// we will be checking that at runtime.
|
// we will be checking that at runtime.
|
||||||
// TODO try analyze arguments and assess if its possible that they are static
|
// TODO try analyze arguments and assess if its possible that they are static
|
||||||
if (stack.size() <= 0)
|
if (stack.size() <= 0) {
|
||||||
{
|
|
||||||
throw new ExpressionException(c, this, token, "Too many function calls, maximum scope exceeded");
|
throw new ExpressionException(c, this, token, "Too many function calls, maximum scope exceeded");
|
||||||
}
|
}
|
||||||
// push the result of the function
|
// push the result of the function
|
||||||
stack.set(stack.size() - 1, stack.topInt() + 1);
|
stack.set(stack.size() - 1, stack.topInt() + 1);
|
||||||
break;
|
}
|
||||||
case OPEN_PAREN:
|
case OPEN_PAREN -> stack.push(0);
|
||||||
stack.push(0);
|
default -> stack.set(stack.size() - 1, stack.topInt() + 1);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
stack.set(stack.size() - 1, stack.topInt() + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public record Module(String name, String code, boolean library)
|
|||||||
*
|
*
|
||||||
* @param scriptName A {@link String} being the name of the script. The extension will be autocompleted
|
* @param scriptName A {@link String} being the name of the script. The extension will be autocompleted
|
||||||
* @param isLibrary A {@link boolean} indicating whether or not the script is a library
|
* @param isLibrary A {@link boolean} indicating whether or not the script is a library
|
||||||
* @return The created {@link BundledModule}
|
* @return The created BundledModule
|
||||||
*/
|
*/
|
||||||
public static Module carpetNative(String scriptName, boolean isLibrary)
|
public static Module carpetNative(String scriptName, boolean isLibrary)
|
||||||
{
|
{
|
||||||
@@ -53,7 +53,7 @@ public record Module(String name, String code, boolean library)
|
|||||||
* @param path A {@link String} being the path to the directory where the app is located.
|
* @param path A {@link String} being the path to the directory where the app is located.
|
||||||
* @param scriptName A {@link String} being the name of the script. The extension will be autocompleted
|
* @param scriptName A {@link String} being the name of the script. The extension will be autocompleted
|
||||||
* @param isLibrary A {@link boolean} indicating whether or not the script is a library
|
* @param isLibrary A {@link boolean} indicating whether or not the script is a library
|
||||||
* @return The created {@link BundledModule}
|
* @return The created BundledModule
|
||||||
* @see #fromJarPathWithCustomName(String, String, boolean)
|
* @see #fromJarPathWithCustomName(String, String, boolean)
|
||||||
*/
|
*/
|
||||||
public static Module fromJarPath(String path, String scriptName, boolean isLibrary)
|
public static Module fromJarPath(String path, String scriptName, boolean isLibrary)
|
||||||
@@ -90,7 +90,7 @@ public record Module(String name, String code, boolean library)
|
|||||||
public static Tag getData(Module module, ScriptServer scriptServer)
|
public static Tag getData(Module module, ScriptServer scriptServer)
|
||||||
{
|
{
|
||||||
Path dataFile = resolveResource(module, scriptServer);
|
Path dataFile = resolveResource(module, scriptServer);
|
||||||
if (dataFile == null || !Files.exists(dataFile) || !(Files.isRegularFile(dataFile)))
|
if (dataFile == null || !Files.exists(dataFile) || !Files.isRegularFile(dataFile))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class ScriptCommand
|
|||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
Set<String> allFunctions = (new CarpetExpression(null, "null", null, null)).getExpr().getFunctionNames();
|
Set<String> allFunctions = new CarpetExpression(null, "null", null, null).getExpr().getFunctionNames();
|
||||||
scarpetFunctions = new TreeSet<>(Expression.none.getFunctionNames());
|
scarpetFunctions = new TreeSet<>(Expression.none.getFunctionNames());
|
||||||
APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new));
|
APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new));
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ public class ScriptCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A method to suggest the available scarpet scripts based off of the current player input and {@link AppStoreManager#APP_STORE_ROOT}
|
* A method to suggest the available scarpet scripts based off of the current player input and AppStoreManager#APP_STORE_ROOT
|
||||||
* variable.
|
* variable.
|
||||||
*/
|
*/
|
||||||
private static CompletableFuture<Suggestions> suggestDownloadableApps(
|
private static CompletableFuture<Suggestions> suggestDownloadableApps(
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public abstract class ScriptHost
|
|||||||
{
|
{
|
||||||
randomizers.clear();
|
randomizers.clear();
|
||||||
}
|
}
|
||||||
return randomizers.computeIfAbsent(aLong, Random::new);
|
return randomizers.computeIfAbsent(aLong, seed -> new Random(seed));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean resetRandom(long aLong)
|
public boolean resetRandom(long aLong)
|
||||||
@@ -134,8 +134,7 @@ public abstract class ScriptHost
|
|||||||
return main == null;
|
return main == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public final @Nullable Module main;
|
||||||
public final Module main;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ErrorSnooper
|
public interface ErrorSnooper
|
||||||
@@ -234,8 +233,7 @@ public abstract class ScriptHost
|
|||||||
|
|
||||||
protected abstract void runModuleCode(Context c, Module module); // this should be shell out in the executor
|
protected abstract void runModuleCode(Context c, Module module); // this should be shell out in the executor
|
||||||
|
|
||||||
@Nullable
|
public @Nullable FunctionValue getFunction(String name)
|
||||||
public FunctionValue getFunction(String name)
|
|
||||||
{
|
{
|
||||||
return getFunction(main, name);
|
return getFunction(main, name);
|
||||||
}
|
}
|
||||||
@@ -257,8 +255,7 @@ public abstract class ScriptHost
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private @Nullable FunctionValue getFunction(Module module, String name)
|
||||||
private FunctionValue getFunction(Module module, String name)
|
|
||||||
{
|
{
|
||||||
ModuleData local = getModuleData(module);
|
ModuleData local = getModuleData(module);
|
||||||
FunctionValue ret = local.globalFunctions.get(name); // most uses would be from local scope anyways
|
FunctionValue ret = local.globalFunctions.get(name); // most uses would be from local scope anyways
|
||||||
@@ -291,8 +288,7 @@ public abstract class ScriptHost
|
|||||||
return target.globalFunctions.get(name);
|
return target.globalFunctions.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private @Nullable ModuleData findModuleDataFromFunctionImports(String name, ModuleData source, int ttl)
|
||||||
private ModuleData findModuleDataFromFunctionImports(String name, ModuleData source, int ttl)
|
|
||||||
{
|
{
|
||||||
if (ttl > 64)
|
if (ttl > 64)
|
||||||
{
|
{
|
||||||
@@ -570,7 +566,7 @@ public abstract class ScriptHost
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
deprecations.add(feature);
|
deprecations.add(feature);
|
||||||
DEPRECATION_LOG.warn("App '" + getVisualName() + "' uses '" + feature + "', which is deprecated for removal. Check the docs for a replacement");
|
DEPRECATION_LOG.warn("App '{}' uses '{}', which is deprecated for removal. Check the docs for a replacement", getVisualName(), feature);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,15 +34,13 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
|||||||
return (allowSingletonCreation ? itemConverter.getTypeName() + " or " : "") + "list of " + itemConverter.getTypeName() + "s";
|
return (allowSingletonCreation ? itemConverter.getTypeName() + " or " : "") + "list of " + itemConverter.getTypeName() + "s";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public List<T> convert(Value value, @Nullable Context context)
|
public @Nullable List<T> convert(Value value, @Nullable Context context)
|
||||||
{
|
{
|
||||||
return value instanceof ListValue ? convertListValue((ListValue) value, context) : allowSingletonCreation ? convertSingleton(value, context) : null;
|
return value instanceof final ListValue listValue ? convertListValue(listValue, context) : allowSingletonCreation ? convertSingleton(value, context) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private @Nullable List<T> convertListValue(ListValue values, @Nullable Context context)
|
||||||
private List<T> convertListValue(ListValue values, @Nullable Context context)
|
|
||||||
{
|
{
|
||||||
List<T> list = new ArrayList<>(values.getItems().size());
|
List<T> list = new ArrayList<>(values.getItems().size());
|
||||||
for (Value value : values)
|
for (Value value : values)
|
||||||
@@ -57,8 +55,7 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private @Nullable List<T> convertSingleton(Value val, @Nullable Context context)
|
||||||
private List<T> convertSingleton(Value val, @Nullable Context context)
|
|
||||||
{
|
{
|
||||||
T converted = itemConverter.convert(val, context);
|
T converted = itemConverter.convert(val, context);
|
||||||
if (converted == null)
|
if (converted == null)
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
|||||||
public Map<K, V> convert(Value value, @Nullable Context context)
|
public Map<K, V> convert(Value value, @Nullable Context context)
|
||||||
{
|
{
|
||||||
Map<K, V> result = new HashMap<>();
|
Map<K, V> result = new HashMap<>();
|
||||||
if (value instanceof MapValue)
|
if (value instanceof MapValue mapValue)
|
||||||
{
|
{
|
||||||
for (Entry<Value, Value> entry : ((MapValue) value).getMap().entrySet())
|
for (Entry<Value, Value> entry : mapValue.getMap().entrySet())
|
||||||
{
|
{
|
||||||
K key = keyConverter.convert(entry.getKey(), context);
|
K key = keyConverter.convert(entry.getKey(), context);
|
||||||
V val = valueConverter.convert(entry.getValue(), context);
|
V val = valueConverter.convert(entry.getValue(), context);
|
||||||
@@ -106,17 +106,14 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
|||||||
return acceptMultiParam;
|
return acceptMultiParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public Map<K, V> convert(Value value, @Nullable Context context) {
|
public @Nullable Map<K, V> convert(Value value, @Nullable Context context) {
|
||||||
return value instanceof MapValue ? super.convert(value, context)
|
return value instanceof MapValue ? super.convert(value, context)
|
||||||
: value instanceof ListValue ? convertList(((ListValue)value).getItems(), context)
|
: value instanceof final ListValue listValue ? convertList(listValue.getItems(), context)
|
||||||
: null; // Multiparam mode can only be used in evalAndConvert
|
: null; // Multiparam mode can only be used in evalAndConvert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @Nullable Map<K, V> convertList(List<Value> valueList, @Nullable Context context)
|
||||||
@Nullable
|
|
||||||
private Map<K, V> convertList(List<Value> valueList, @Nullable Context context)
|
|
||||||
{
|
{
|
||||||
if (valueList.size() % 2 == 1)
|
if (valueList.size() % 2 == 1)
|
||||||
{
|
{
|
||||||
@@ -137,9 +134,8 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public Map<K, V> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
public @Nullable Map<K, V> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||||
{
|
{
|
||||||
if (!valueIterator.hasNext())
|
if (!valueIterator.hasNext())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,9 +51,8 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
|||||||
* @implNote Unlike most other converters, {@link OptionalConverter} will not call this method from
|
* @implNote Unlike most other converters, {@link OptionalConverter} will not call this method from
|
||||||
* {@link #checkAndConvert(Iterator, Context, Context.Type)} and is only used as a fallback in types that don't support it.
|
* {@link #checkAndConvert(Iterator, Context, Context.Type)} and is only used as a fallback in types that don't support it.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<R> convert(Value value, @Nullable Context context)
|
public @Nullable Optional<R> convert(Value value, @Nullable Context context)
|
||||||
{
|
{
|
||||||
if (value.isNull())
|
if (value.isNull())
|
||||||
{
|
{
|
||||||
@@ -67,9 +66,8 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
|||||||
return Optional.of(converted);
|
return Optional.of(converted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<R> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
public @Nullable Optional<R> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||||
{
|
{
|
||||||
if (!valueIterator.hasNext() || valueIterator.next().isNull())
|
if (!valueIterator.hasNext() || valueIterator.next().isNull())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -146,9 +146,8 @@ public interface Param
|
|||||||
*/
|
*/
|
||||||
static final ValueConverter<Context> CONTEXT_PROVIDER = new ValueConverter<>()
|
static final ValueConverter<Context> CONTEXT_PROVIDER = new ValueConverter<>()
|
||||||
{
|
{
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public String getTypeName()
|
public @Nullable String getTypeName()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -178,9 +177,8 @@ public interface Param
|
|||||||
*/
|
*/
|
||||||
static final ValueConverter<Context.Type> CONTEXT_TYPE_PROVIDER = new ValueConverter<>()
|
static final ValueConverter<Context.Type> CONTEXT_TYPE_PROVIDER = new ValueConverter<>()
|
||||||
{
|
{
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public String getTypeName()
|
public @Nullable String getTypeName()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,10 +106,9 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
|||||||
return (SimpleTypeConverter<Value, R>) byResult.get(outputType);
|
return (SimpleTypeConverter<Value, R>) byResult.get(outputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked") // more than checked. not using class.cast because then "method is too big" for inlining, because javac is useless
|
@SuppressWarnings("unchecked") // more than checked. not using class.cast because then "method is too big" for inlining, because javac is useless
|
||||||
public R convert(Value value, @Nullable Context context) // and adds millions of casts. This one is even removed
|
public @Nullable R convert(Value value, @Nullable Context context) // and adds millions of casts. This one is even removed
|
||||||
{
|
{
|
||||||
return valueClass.isInstance(value) ? converter.apply((T)value, context) : null;
|
return valueClass.isInstance(value) ? converter.apply((T)value, context) : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,10 +80,9 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
|
|||||||
return (ValueCaster<R>) byResult.get(outputType);
|
return (ValueCaster<R>) byResult.get(outputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked") // more than checked, see SimpleTypeConverter#converter for reasoning
|
@SuppressWarnings("unchecked") // more than checked, see SimpleTypeConverter#converter for reasoning
|
||||||
public R convert(Value value, @Nullable Context context)
|
public @Nullable R convert(Value value, @Nullable Context context)
|
||||||
{
|
{
|
||||||
if (!outputType.isInstance(value))
|
if (!outputType.isInstance(value))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,9 +77,8 @@ public interface ValueConverter<R>
|
|||||||
* @return A converted value
|
* @return A converted value
|
||||||
* @deprecated Calling this method instead of {@link #convert(Value, Context)} may not return values for some converters
|
* @deprecated Calling this method instead of {@link #convert(Value, Context)} may not return values for some converters
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
default R convert(Value value)
|
default @Nullable R convert(Value value)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -211,8 +210,7 @@ public interface ValueConverter<R>
|
|||||||
* @implNote This method's default implementation runs the {@link #convert(Value, Context)} function in the next {@link Value} ignoring {@link Context} and
|
* @implNote This method's default implementation runs the {@link #convert(Value, Context)} function in the next {@link Value} ignoring {@link Context} and
|
||||||
* {@code theLazyT}.
|
* {@code theLazyT}.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
default @Nullable R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type contextType)
|
||||||
default R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type contextType)
|
|
||||||
{
|
{
|
||||||
return !valueIterator.hasNext() ? null : convert(valueIterator.next(), context);
|
return !valueIterator.hasNext() ? null : convert(valueIterator.next(), context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ public class Auxiliary
|
|||||||
Vec3 vec = locator.vec;
|
Vec3 vec = locator.vec;
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
for (ServerPlayer p : (world.players()))
|
for (ServerPlayer p : world.players())
|
||||||
{
|
{
|
||||||
world.sendParticles(p, particle, true, true, vec.x, vec.y, vec.z, count,
|
world.sendParticles(p, particle, true, true, vec.x, vec.y, vec.z, count,
|
||||||
spread, spread, spread, speed);
|
spread, spread, spread, speed);
|
||||||
@@ -346,7 +346,7 @@ public class Auxiliary
|
|||||||
}
|
}
|
||||||
|
|
||||||
ShapeDispatcher.sendShape(
|
ShapeDispatcher.sendShape(
|
||||||
(playerTargets.isEmpty()) ? cc.level().players() : playerTargets,
|
playerTargets.isEmpty() ? cc.level().players() : playerTargets,
|
||||||
shapes, cc.registryAccess()
|
shapes, cc.registryAccess()
|
||||||
);
|
);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
@@ -469,8 +469,8 @@ public class Auxiliary
|
|||||||
{
|
{
|
||||||
return Value.FALSE;
|
return Value.FALSE;
|
||||||
}
|
}
|
||||||
Tag source = ((NBTSerializableValue) (NBTSerializableValue.fromValue(lv.get(0)))).getTag();
|
Tag source = ((NBTSerializableValue) NBTSerializableValue.fromValue(lv.get(0))).getTag();
|
||||||
Tag match = ((NBTSerializableValue) (NBTSerializableValue.fromValue(lv.get(1)))).getTag();
|
Tag match = ((NBTSerializableValue) NBTSerializableValue.fromValue(lv.get(1))).getTag();
|
||||||
return BooleanValue.of(NbtUtils.compareNbt(match, source, numParam == 2 || lv.get(2).getBoolean()));
|
return BooleanValue.of(NbtUtils.compareNbt(match, source, numParam == 2 || lv.get(2).getBoolean()));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -560,39 +560,30 @@ public class Auxiliary
|
|||||||
});
|
});
|
||||||
Function<Component, Packet<?>> packetGetter = null;
|
Function<Component, Packet<?>> packetGetter = null;
|
||||||
String actionString = lv.get(1).getString().toLowerCase(Locale.ROOT);
|
String actionString = lv.get(1).getString().toLowerCase(Locale.ROOT);
|
||||||
switch (actionString)
|
switch (actionString) {
|
||||||
{
|
case "title" -> {
|
||||||
case "title":
|
|
||||||
packetGetter = ClientboundSetTitleTextPacket::new;
|
packetGetter = ClientboundSetTitleTextPacket::new;
|
||||||
if (lv.size() < 3)
|
if (lv.size() < 3) {
|
||||||
{
|
|
||||||
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
|
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
case "subtitle" -> {
|
||||||
case "subtitle":
|
|
||||||
packetGetter = ClientboundSetSubtitleTextPacket::new;
|
packetGetter = ClientboundSetSubtitleTextPacket::new;
|
||||||
if (lv.size() < 3)
|
if (lv.size() < 3) {
|
||||||
{
|
|
||||||
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
|
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
case "actionbar" -> {
|
||||||
case "actionbar":
|
|
||||||
packetGetter = ClientboundSetActionBarTextPacket::new;
|
packetGetter = ClientboundSetActionBarTextPacket::new;
|
||||||
if (lv.size() < 3)
|
if (lv.size() < 3) {
|
||||||
{
|
|
||||||
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
|
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
case "clear" -> packetGetter = x -> new ClientboundClearTitlesPacket(true); // resetting default fade
|
||||||
case "clear":
|
case "player_list_header", "player_list_footer" -> {
|
||||||
packetGetter = x -> new ClientboundClearTitlesPacket(true); // resetting default fade
|
}
|
||||||
break;
|
default ->
|
||||||
case "player_list_header", "player_list_footer":
|
throw new InternalExpressionException("'display_title' requires 'title', 'subtitle', 'actionbar', 'player_list_header', 'player_list_footer' or 'clear' as second argument");
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new InternalExpressionException("'display_title' requires 'title', 'subtitle', 'actionbar', 'player_list_header', 'player_list_footer' or 'clear' as second argument");
|
|
||||||
}
|
}
|
||||||
Component title;
|
Component title;
|
||||||
boolean soundsTrue = false;
|
boolean soundsTrue = false;
|
||||||
@@ -915,7 +906,7 @@ public class Auxiliary
|
|||||||
if (lv.size() == 1)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
res = lv.get(0);
|
res = lv.get(0);
|
||||||
CarpetScriptServer.LOG.info(res.getString());
|
CarpetScriptServer.LOG.info("{}", res.getString());
|
||||||
}
|
}
|
||||||
else if (lv.size() == 2)
|
else if (lv.size() == 2)
|
||||||
{
|
{
|
||||||
@@ -923,11 +914,11 @@ public class Auxiliary
|
|||||||
res = lv.get(1);
|
res = lv.get(1);
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case "debug" -> CarpetScriptServer.LOG.debug(res.getString());
|
case "debug" -> CarpetScriptServer.LOG.debug("{}", res.getString());
|
||||||
case "warn" -> CarpetScriptServer.LOG.warn(res.getString());
|
case "warn" -> CarpetScriptServer.LOG.warn("{}", res.getString());
|
||||||
case "info" -> CarpetScriptServer.LOG.info(res.getString());
|
case "info" -> CarpetScriptServer.LOG.info("{}", res.getString());
|
||||||
// Somehow issue deprecation
|
// Somehow issue deprecation
|
||||||
case "fatal", "error" -> CarpetScriptServer.LOG.error(res.getString());
|
case "fatal", "error" -> CarpetScriptServer.LOG.error("{}", res.getString());
|
||||||
default -> throw new InternalExpressionException("Unknown log level for 'logger': " + level);
|
default -> throw new InternalExpressionException("Unknown log level for 'logger': " + level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1386,8 +1377,7 @@ public class Auxiliary
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private static <T> @Nullable Stat<T> getStat(StatType<T> type, Identifier id)
|
||||||
private static <T> Stat<T> getStat(StatType<T> type, Identifier id)
|
|
||||||
{
|
{
|
||||||
T key = type.getRegistry().getValue(id);
|
T key = type.getRegistry().getValue(id);
|
||||||
if (key == null || !type.contains(key))
|
if (key == null || !type.contains(key))
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ public class Inventories
|
|||||||
amount = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong();
|
amount = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong();
|
||||||
}
|
}
|
||||||
// not enough
|
// not enough
|
||||||
if (((amount == 1) && (!inventoryLocator.inventory().hasAnyOf(Set.of(searchItem.getItem()))))
|
if (((amount == 1) && !inventoryLocator.inventory().hasAnyOf(Set.of(searchItem.getItem())))
|
||||||
|| (inventoryLocator.inventory().countItem(searchItem.getItem()) < amount))
|
|| (inventoryLocator.inventory().countItem(searchItem.getItem()) < amount))
|
||||||
{
|
{
|
||||||
return Value.FALSE;
|
return Value.FALSE;
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class Scoreboards
|
|||||||
}
|
}
|
||||||
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
|
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
|
||||||
Vanilla.Objective_setCriterion(objective, criterion);
|
Vanilla.Objective_setCriterion(objective, criterion);
|
||||||
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList())).add(objective);
|
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList()).add(objective);
|
||||||
scoreboard.onObjectiveAdded(objective);
|
scoreboard.onObjectiveAdded(objective);
|
||||||
return Value.FALSE;
|
return Value.FALSE;
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ public class Scoreboards
|
|||||||
}
|
}
|
||||||
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
|
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
|
||||||
Vanilla.Objective_setCriterion(objective, criterion);
|
Vanilla.Objective_setCriterion(objective, criterion);
|
||||||
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList())).add(objective);
|
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList()).add(objective);
|
||||||
scoreboard.onObjectiveAdded(objective);
|
scoreboard.onObjectiveAdded(objective);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
@@ -585,7 +585,7 @@ public class Scoreboards
|
|||||||
case "color" -> {
|
case "color" -> {
|
||||||
if (propertyValue == null)
|
if (propertyValue == null)
|
||||||
{
|
{
|
||||||
BossEvent.BossBarColor color = (bossBar).getColor();
|
BossEvent.BossBarColor color = bossBar.getColor();
|
||||||
return color == null ? Value.NULL : StringValue.of(color.getName());
|
return color == null ? Value.NULL : StringValue.of(color.getName());
|
||||||
}
|
}
|
||||||
BossEvent.BossBarColor color = ((StringRepresentable.EnumCodec<BossEvent.BossBarColor>)BossEvent.BossBarColor.CODEC).byName(propertyValue.getString());
|
BossEvent.BossBarColor color = ((StringRepresentable.EnumCodec<BossEvent.BossBarColor>)BossEvent.BossBarColor.CODEC).byName(propertyValue.getString());
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import carpet.script.value.ValueConversions;
|
|||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
@@ -58,21 +58,20 @@ import net.minecraft.util.ProblemReporter;
|
|||||||
import net.minecraft.util.random.WeightedList;
|
import net.minecraft.util.random.WeightedList;
|
||||||
import net.minecraft.world.entity.EntityTypes;
|
import net.minecraft.world.entity.EntityTypes;
|
||||||
import net.minecraft.world.level.ServerExplosion;
|
import net.minecraft.world.level.ServerExplosion;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import net.minecraft.world.level.levelgen.Aquifer;
|
import net.minecraft.world.level.levelgen.Aquifer;
|
||||||
|
import net.minecraft.world.level.levelgen.NoiseRouterData;
|
||||||
import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
|
import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
|
||||||
import net.minecraft.world.level.levelgen.densityfunction.DensityFunctions;
|
|
||||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||||
import net.minecraft.world.level.levelgen.NoiseRouter;
|
|
||||||
import net.minecraft.world.level.levelgen.RandomState;
|
import net.minecraft.world.level.levelgen.RandomState;
|
||||||
|
import net.minecraft.world.level.levelgen.densityfunction.DensitySamplerSet;
|
||||||
|
import net.minecraft.world.level.levelgen.densityfunction.SamplerContext;
|
||||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureType;
|
import net.minecraft.world.level.levelgen.structure.StructureType;
|
||||||
import net.minecraft.world.level.saveddata.WeatherData;
|
import net.minecraft.world.level.saveddata.WeatherData;
|
||||||
import net.minecraft.world.level.storage.TagValueInput;
|
import net.minecraft.world.level.storage.TagValueInput;
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -96,7 +95,6 @@ import net.minecraft.sounds.SoundSource;
|
|||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.entity.ai.village.poi.PoiManager;
|
import net.minecraft.world.entity.ai.village.poi.PoiManager;
|
||||||
import net.minecraft.world.entity.ai.village.poi.PoiRecord;
|
import net.minecraft.world.entity.ai.village.poi.PoiRecord;
|
||||||
@@ -133,7 +131,6 @@ import net.minecraft.world.level.levelgen.WorldgenRandom;
|
|||||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||||
import net.minecraft.world.level.pathfinder.PathComputationType;
|
import net.minecraft.world.level.pathfinder.PathComputationType;
|
||||||
import net.minecraft.world.level.storage.ServerLevelData;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
@@ -351,7 +348,7 @@ public class WorldAccess
|
|||||||
{
|
{
|
||||||
status = PoiManager.Occupancy.HAS_SPACE;
|
status = PoiManager.Occupancy.HAS_SPACE;
|
||||||
}
|
}
|
||||||
else if (!("any".equals(statusString)))
|
else if (!"any".equals(statusString))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException(
|
throw new InternalExpressionException(
|
||||||
"Incorrect POI occupation status " + status + " use `any`, " + "`occupied` or `available`"
|
"Incorrect POI occupation status " + status + " use `any`, " + "`occupied` or `available`"
|
||||||
@@ -603,7 +600,7 @@ public class WorldAccess
|
|||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("loaded", -1, (c, t, lv) ->
|
expression.addContextFunction("loaded", -1, (c, t, lv) ->
|
||||||
BooleanValue.of((((CarpetContext) c).level().hasChunkAt(BlockArgument.findIn((CarpetContext) c, lv, 0).block.getPos()))));
|
BooleanValue.of(((CarpetContext) c).level().hasChunkAt(BlockArgument.findIn((CarpetContext) c, lv, 0).block.getPos())));
|
||||||
|
|
||||||
// Deprecated, use loaded_status as more indicative
|
// Deprecated, use loaded_status as more indicative
|
||||||
expression.addContextFunction("loaded_ep", -1, (c, t, lv) ->
|
expression.addContextFunction("loaded_ep", -1, (c, t, lv) ->
|
||||||
@@ -1088,9 +1085,7 @@ public class WorldAccess
|
|||||||
ServerExplosion serverExplosion = new ServerExplosion(cc.level(), source, null, null, pos, powah, createFire, mode)
|
ServerExplosion serverExplosion = new ServerExplosion(cc.level(), source, null, null, pos, powah, createFire, mode)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
public @Nullable LivingEntity getIndirectSourceEntity()
|
||||||
public
|
|
||||||
LivingEntity getIndirectSourceEntity()
|
|
||||||
{
|
{
|
||||||
return theAttacker;
|
return theAttacker;
|
||||||
}
|
}
|
||||||
@@ -1484,7 +1479,7 @@ public class WorldAccess
|
|||||||
}
|
}
|
||||||
catch (NullPointerException npe)
|
catch (NullPointerException npe)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.error("Failed to detect structure: " + reg.getKey(str));
|
CarpetScriptServer.LOG.error("Failed to detect structure: {}", reg.getKey(str));
|
||||||
start = null;
|
start = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1494,7 +1489,7 @@ public class WorldAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
Value key = NBTSerializableValue.nameFromRegistryId(reg.getKey(str));
|
Value key = NBTSerializableValue.nameFromRegistryId(reg.getKey(str));
|
||||||
ret.put(key, (!needSize) ? Value.NULL : ValueConversions.of(start, cc.registryAccess()));
|
ret.put(key, !needSize ? Value.NULL : ValueConversions.of(start, cc.registryAccess()));
|
||||||
}
|
}
|
||||||
return MapValue.wrap(ret);
|
return MapValue.wrap(ret);
|
||||||
});
|
});
|
||||||
@@ -1731,104 +1726,68 @@ public class WorldAccess
|
|||||||
{
|
{
|
||||||
return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of));
|
return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of));
|
||||||
}
|
}
|
||||||
RandomState router = level.getChunkSource().randomState();
|
|
||||||
return densityFunctionQueries.length == 1
|
return densityFunctionQueries.length == 1
|
||||||
? NumericValue.of(sampleNoise(router, level, densityFunctionQueries[0], pos))
|
? NumericValue.of(sampleNoise(level, densityFunctionQueries[0], pos))
|
||||||
: ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(sampleNoise(router, level, s, pos))));
|
: ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(sampleNoise(level, s, pos))));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double sampleNoise(RandomState router, ServerLevel level, String what, BlockPos pos)
|
|
||||||
|
private static @Nullable DensitySamplerSet samplersCache = null;
|
||||||
|
private static @Nullable ServerLevel samplerLevel = null;
|
||||||
|
|
||||||
|
public static double sampleNoise(ServerLevel level, String what, BlockPos pos)
|
||||||
{
|
{
|
||||||
DensityFunction densityFunction = switch (what)
|
if (samplersCache == null || samplerLevel != level) {
|
||||||
{
|
final ServerChunkCache chunkSource = level.getChunkSource();
|
||||||
case "temperature" -> router.router().temperature();
|
final RandomState randomState = chunkSource.randomState();
|
||||||
case "vegetation" -> router.router().vegetation();
|
final SamplerContext samplerContext = SamplerContext.builder().enableCaches().build();
|
||||||
case "continents" -> router.router().continents();
|
samplersCache = randomState.samplersWithContext(samplerContext);
|
||||||
case "erosion" -> router.router().erosion();
|
samplerLevel = level;
|
||||||
case "depth" -> router.router().depth();
|
|
||||||
case "ridges" -> router.router().ridges();
|
|
||||||
case "preliminary_surface_level" -> router.router().preliminarySurfaceLevel();
|
|
||||||
case "final_density" -> router.router().finalDensity();
|
|
||||||
//case "vein_toggle" -> router. router(). veinToggle();
|
|
||||||
//case "vein_ridged" -> router.router().veinRidged();
|
|
||||||
//case "vein_gap" -> router.router().veinGap();
|
|
||||||
default -> {
|
|
||||||
Aquifer.Config aquifer = router.aquifers().orElse(null);
|
|
||||||
if (aquifer != null) {
|
|
||||||
yield switch (what) {
|
|
||||||
case "barrier_noise" -> aquifer.barrierNoise();
|
|
||||||
case "fluid_level_floodedness_noise" -> aquifer.fluidLevelFloodednessNoise();
|
|
||||||
case "fluid_level_spread_noise" -> aquifer.fluidLevelSpreadNoise();
|
|
||||||
case "lava_noise" -> aquifer.lavaNoise();
|
|
||||||
default -> stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, what));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
yield stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, what));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return densityFunction.compute(new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// to be used with future seedable noise
|
|
||||||
public static final Function<Pair<ServerLevel, String>, DensityFunction> stupidWorldgenNoiseCacheGetter = Util.memoize(pair -> {
|
|
||||||
ServerLevel level = pair.getKey();
|
|
||||||
String densityFunctionQuery = pair.getValue();
|
|
||||||
ChunkGenerator generator = level.getChunkSource().getGenerator();
|
|
||||||
|
|
||||||
if (generator instanceof final NoiseBasedChunkGenerator noiseBasedChunkGenerator)
|
|
||||||
{
|
|
||||||
Registry<DensityFunction> densityFunctionRegistry = level.registryAccess().lookupOrThrow(Registries.DENSITY_FUNCTION);
|
|
||||||
NoiseRouter router = noiseBasedChunkGenerator.generatorSettings().value().noiseRouter();
|
|
||||||
DensityFunction densityFunction = switch (densityFunctionQuery)
|
|
||||||
{
|
|
||||||
case "temperature" -> router.temperature();
|
|
||||||
case "vegetation" -> router.vegetation();
|
|
||||||
case "continents" -> router.continents();
|
|
||||||
case "erosion" -> router.erosion();
|
|
||||||
case "depth" -> router.depth();
|
|
||||||
case "ridges" -> router.ridges();
|
|
||||||
case "preliminary_surface_level" -> router.preliminarySurfaceLevel();
|
|
||||||
case "final_density" -> router.finalDensity();
|
|
||||||
//case "vein_toggle" -> router.veinToggle();
|
|
||||||
//case "vein_ridged" -> router.veinRidged();
|
|
||||||
//case "vein_gap" -> router.veinGap();
|
|
||||||
default -> {
|
|
||||||
Aquifer.Config aquifers = noiseBasedChunkGenerator.generatorSettings().value().aquifers().orElse(null);
|
|
||||||
if (aquifers != null) {
|
|
||||||
yield switch (densityFunctionQuery) {
|
|
||||||
case "barrier_noise" -> aquifers.barrierNoise();
|
|
||||||
case "fluid_level_floodedness_noise" -> aquifers.fluidLevelFloodednessNoise();
|
|
||||||
case "fluid_level_spread_noise" -> aquifers.fluidLevelSpreadNoise();
|
|
||||||
case "lava_noise" -> aquifers.lavaNoise();
|
|
||||||
default -> {
|
|
||||||
DensityFunction result = densityFunctionRegistry.getValue(InputValidator.identifierOf(densityFunctionQuery));
|
|
||||||
if (result == null)
|
|
||||||
{
|
|
||||||
throw new InternalExpressionException("Density function '" + densityFunctionQuery + "' is not defined in the registies.");
|
|
||||||
}
|
|
||||||
yield result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DensityFunction result = densityFunctionRegistry.getValue(InputValidator.identifierOf(densityFunctionQuery));
|
|
||||||
if (result == null)
|
|
||||||
{
|
|
||||||
throw new InternalExpressionException("Density function '" + densityFunctionQuery + "' is not defined in the registies.");
|
|
||||||
}
|
|
||||||
yield result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RandomState randomState = RandomState.create(
|
|
||||||
level.registryAccess().lookupOrThrow(Registries.NOISE), level.getSeed(), noiseBasedChunkGenerator.generatorSettings().value()
|
|
||||||
);
|
|
||||||
DensityFunction.Visitor visitor = Vanilla.RandomState_getVisitor(randomState);
|
|
||||||
|
|
||||||
return densityFunction.mapAll(visitor);
|
|
||||||
}
|
}
|
||||||
return DensityFunctions.zero();
|
|
||||||
});
|
ResourceKey<DensityFunction> key = switch (what) {
|
||||||
|
case "temperature" -> NoiseRouterData.OVERWORLD_FUNCTIONS.temperature();
|
||||||
|
case "vegetation" -> NoiseRouterData.OVERWORLD_FUNCTIONS.vegetation();
|
||||||
|
case "continents" -> NoiseRouterData.OVERWORLD_FUNCTIONS.continents();
|
||||||
|
case "erosion" -> NoiseRouterData.OVERWORLD_FUNCTIONS.erosion();
|
||||||
|
case "depth" -> NoiseRouterData.OVERWORLD_FUNCTIONS.depth();
|
||||||
|
case "ridges" -> NoiseRouterData.RIDGES;
|
||||||
|
case "preliminary_height" -> NoiseRouterData.OVERWORLD_FUNCTIONS.preliminarySurfaceLevel();
|
||||||
|
case "final_density" -> NoiseRouterData.OVERWORLD_FUNCTIONS.finalDensity();
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
final DensityFunction df;
|
||||||
|
if (key != null) {
|
||||||
|
df = level.registryAccess().lookupOrThrow(Registries.DENSITY_FUNCTION).get(key).get().value();
|
||||||
|
} else {
|
||||||
|
df = level.registryAccess().lookupOrThrow(Registries.DENSITY_FUNCTION).getValue(InputValidator.identifierOf(what));
|
||||||
|
}
|
||||||
|
if (df == null)
|
||||||
|
{
|
||||||
|
// last call, maybe its the aquifers
|
||||||
|
DensityFunction dfa;
|
||||||
|
if (level.getChunkSource().getGenerator() instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||||
|
Aquifer.Config aquifers = noiseBasedChunkGenerator.generatorSettings().value().aquifers().orElse(null);
|
||||||
|
if (aquifers != null) {
|
||||||
|
dfa = switch (what) {
|
||||||
|
case "barrier_noise" -> aquifers.barrierNoise();
|
||||||
|
case "fluid_level_floodedness_noise" -> aquifers.fluidLevelFloodednessNoise();
|
||||||
|
case "fluid_level_spread_noise" -> aquifers.fluidLevelSpreadNoise();
|
||||||
|
case "lava_noise" -> aquifers.lavaNoise();
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
if (dfa != null) {
|
||||||
|
return samplersCache.sampleValue(dfa, pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (what.equalsIgnoreCase("barrier_noise") || what.equalsIgnoreCase("fluid_level_floodedness_noise") || what.equalsIgnoreCase("fluid_level_spread_noise") || what.equalsIgnoreCase("lava_noise")) {
|
||||||
|
// querying for aquifers outside of noise based level should not result in an invalid exception, but rather a 0 value, as the aquifers are not present in that world.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InternalExpressionException("Density function '" + what + "' is not defined in the registries.");
|
||||||
|
}
|
||||||
|
return samplersCache.sampleValue(df, pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ import org.jspecify.annotations.Nullable;
|
|||||||
public class BlockArgument extends Argument
|
public class BlockArgument extends Argument
|
||||||
{
|
{
|
||||||
public final BlockValue block;
|
public final BlockValue block;
|
||||||
@Nullable public final String replacement;
|
public final @Nullable String replacement;
|
||||||
|
|
||||||
private BlockArgument(BlockValue b, int o)
|
private BlockArgument(BlockValue b, int o)
|
||||||
{
|
{
|
||||||
@@ -68,14 +68,14 @@ public class BlockArgument extends Argument
|
|||||||
{
|
{
|
||||||
return new BlockArgument(BlockValue.fromString(v1.getString(), c.level()), 1 + offset);
|
return new BlockArgument(BlockValue.fromString(v1.getString(), c.level()), 1 + offset);
|
||||||
}
|
}
|
||||||
if (v1 instanceof BlockValue)
|
if (v1 instanceof final BlockValue blockValue)
|
||||||
{
|
{
|
||||||
return new BlockArgument(((BlockValue) v1), 1 + offset);
|
return new BlockArgument(blockValue, 1 + offset);
|
||||||
}
|
}
|
||||||
BlockPos pos = c.origin();
|
BlockPos pos = c.origin();
|
||||||
if (v1 instanceof ListValue)
|
if (v1 instanceof final ListValue listValue)
|
||||||
{
|
{
|
||||||
List<Value> args = ((ListValue) v1).getItems();
|
List<Value> args = listValue.getItems();
|
||||||
int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
|
int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
|
||||||
int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
|
int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
|
||||||
int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
|
int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
|
||||||
|
|||||||
@@ -202,8 +202,7 @@ public class FileArgument
|
|||||||
return host.resolveScriptFile(suffix);
|
return host.resolveScriptFile(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private @Nullable Path toPath(@Nullable Module module)
|
||||||
private Path toPath(@Nullable Module module)
|
|
||||||
{
|
{
|
||||||
if (!isShared && module == null)
|
if (!isShared && module == null)
|
||||||
{
|
{
|
||||||
@@ -245,8 +244,7 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private @Nullable Path moduleRootPath(@Nullable Module module)
|
||||||
private Path moduleRootPath(@Nullable Module module)
|
|
||||||
{
|
{
|
||||||
return !isShared && module == null
|
return !isShared && module == null
|
||||||
? null
|
? null
|
||||||
@@ -294,8 +292,7 @@ public class FileArgument
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public @Nullable Stream<Path> listFiles(Module module)
|
||||||
public Stream<Path> listFiles(Module module)
|
|
||||||
{
|
{
|
||||||
Path dir = toPath(module);
|
Path dir = toPath(module);
|
||||||
if (dir == null || !Files.exists(dir))
|
if (dir == null || !Files.exists(dir))
|
||||||
@@ -316,8 +313,7 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public @Nullable Stream<String> listFolder(Module module)
|
||||||
public Stream<String> listFolder(Module module)
|
|
||||||
{
|
{
|
||||||
Stream<String> strings;
|
Stream<String> strings;
|
||||||
try (Stream<Path> result = listFiles(module))
|
try (Stream<Path> result = listFiles(module))
|
||||||
@@ -407,8 +403,7 @@ public class FileArgument
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public @Nullable Tag getNbtData(Module module) // aka getData
|
||||||
public Tag getNbtData(Module module) // aka getData
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -430,8 +425,7 @@ public class FileArgument
|
|||||||
|
|
||||||
//copied private method from net.minecraft.nbt.NbtIo.read()
|
//copied private method from net.minecraft.nbt.NbtIo.read()
|
||||||
// to read non-compound tags - these won't be compressed
|
// to read non-compound tags - these won't be compressed
|
||||||
@Nullable
|
public static @Nullable Tag readTag(Path path)
|
||||||
public static Tag readTag(Path path)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -567,8 +561,7 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public @Nullable List<String> listFile(Module module)
|
||||||
public List<String> listFile(Module module)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -615,8 +608,7 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public @Nullable JsonElement readJsonFile(Module module)
|
||||||
public JsonElement readJsonFile(Module module)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,9 +96,9 @@ public class FunctionArgument extends Argument
|
|||||||
throw CommandArgument.error("Function has empty spec");
|
throw CommandArgument.error("Function has empty spec");
|
||||||
}
|
}
|
||||||
Value first = params.get(0);
|
Value first = params.get(0);
|
||||||
if (first instanceof FunctionValue)
|
if (first instanceof final FunctionValue functionValue)
|
||||||
{
|
{
|
||||||
function = (FunctionValue) first;
|
function = functionValue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ public class Vector3Argument extends Argument
|
|||||||
public final double yaw;
|
public final double yaw;
|
||||||
public final double pitch;
|
public final double pitch;
|
||||||
public boolean fromBlock = false;
|
public boolean fromBlock = false;
|
||||||
@Nullable
|
public @Nullable Entity entity = null;
|
||||||
public Entity entity = null;
|
|
||||||
|
|
||||||
private Vector3Argument(Vec3 v, int o)
|
private Vector3Argument(Vec3 v, int o)
|
||||||
{
|
{
|
||||||
@@ -68,18 +67,18 @@ public class Vector3Argument extends Argument
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Value v1 = params.next();
|
Value v1 = params.next();
|
||||||
if (v1 instanceof BlockValue)
|
if (v1 instanceof final BlockValue blockValue)
|
||||||
{
|
{
|
||||||
return (new Vector3Argument(Vec3.atCenterOf(((BlockValue) v1).getPos()), 1 + offset)).fromBlock();
|
return new Vector3Argument(Vec3.atCenterOf(blockValue.getPos()), 1 + offset).fromBlock();
|
||||||
}
|
}
|
||||||
if (optionalEntity && v1 instanceof EntityValue)
|
if (optionalEntity && v1 instanceof final EntityValue entityValue)
|
||||||
{
|
{
|
||||||
Entity e = ((EntityValue) v1).getEntity();
|
Entity e = entityValue.getEntity();
|
||||||
return new Vector3Argument(e.position(), 1 + offset).withEntity(e);
|
return new Vector3Argument(e.position(), 1 + offset).withEntity(e);
|
||||||
}
|
}
|
||||||
if (v1 instanceof ListValue)
|
if (v1 instanceof final ListValue listValue)
|
||||||
{
|
{
|
||||||
List<Value> args = ((ListValue) v1).getItems();
|
List<Value> args = listValue.getItems();
|
||||||
Vec3 pos = new Vec3(
|
Vec3 pos = new Vec3(
|
||||||
NumericValue.asNumber(args.get(0)).getDouble(),
|
NumericValue.asNumber(args.get(0)).getDouble(),
|
||||||
NumericValue.asNumber(args.get(1)).getDouble(),
|
NumericValue.asNumber(args.get(1)).getDouble(),
|
||||||
|
|||||||
@@ -321,8 +321,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String suffix;
|
protected String suffix;
|
||||||
@Nullable
|
protected @Nullable Collection<String> examples;
|
||||||
protected Collection<String> examples;
|
|
||||||
protected boolean needsMatching;
|
protected boolean needsMatching;
|
||||||
protected boolean caseSensitive = true;
|
protected boolean caseSensitive = true;
|
||||||
protected Function<String, SuggestionProvider<CommandSourceStack>> suggestionProvider;
|
protected Function<String, SuggestionProvider<CommandSourceStack>> suggestionProvider;
|
||||||
@@ -385,11 +384,11 @@ public abstract class CommandArgument
|
|||||||
throw error("Attempted to provide 'suggest' list while 'suggester' is present" + " for custom type " + suffix);
|
throw error("Attempted to provide 'suggest' list while 'suggester' is present" + " for custom type " + suffix);
|
||||||
}
|
}
|
||||||
Value suggestionValue = config.get("suggest");
|
Value suggestionValue = config.get("suggest");
|
||||||
if (!(suggestionValue instanceof ListValue))
|
if (!(suggestionValue instanceof final ListValue listValue))
|
||||||
{
|
{
|
||||||
throw error("Argument suggestions needs to be a list" + " for custom type " + suffix);
|
throw error("Argument suggestions needs to be a list" + " for custom type " + suffix);
|
||||||
}
|
}
|
||||||
examples = ((ListValue) suggestionValue).getItems().stream()
|
examples = listValue.getItems().stream()
|
||||||
.map(Value::getString)
|
.map(Value::getString)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
if (!examples.isEmpty())
|
if (!examples.isEmpty())
|
||||||
@@ -437,11 +436,11 @@ public abstract class CommandArgument
|
|||||||
args.add(MapValue.wrap(params));
|
args.add(MapValue.wrap(params));
|
||||||
args.addAll(customSuggester.args);
|
args.addAll(customSuggester.args);
|
||||||
Value response = host.handleCommand(context.getSource(), customSuggester.function, args);
|
Value response = host.handleCommand(context.getSource(), customSuggester.function, args);
|
||||||
if (!(response instanceof ListValue))
|
if (!(response instanceof final ListValue listValue))
|
||||||
{
|
{
|
||||||
throw error("Custom suggester should return a list of options" + " for custom type " + suffix);
|
throw error("Custom suggester should return a list of options" + " for custom type " + suffix);
|
||||||
}
|
}
|
||||||
Collection<String> res = ((ListValue) response).getItems().stream().map(Value::getString).collect(Collectors.toList());
|
Collection<String> res = listValue.getItems().stream().map(Value::getString).collect(Collectors.toList());
|
||||||
currentSection.run();
|
currentSection.run();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -504,12 +503,12 @@ public abstract class CommandArgument
|
|||||||
if (config.containsKey("options"))
|
if (config.containsKey("options"))
|
||||||
{
|
{
|
||||||
Value optionsValue = config.get("options");
|
Value optionsValue = config.get("options");
|
||||||
if (!(optionsValue instanceof ListValue))
|
if (!(optionsValue instanceof final ListValue listValue))
|
||||||
{
|
{
|
||||||
throw error("Custom string type requires options passed as a list" + " for custom type " + suffix);
|
throw error("Custom string type requires options passed as a list" + " for custom type " + suffix);
|
||||||
}
|
}
|
||||||
validOptions = ((ListValue) optionsValue).getItems().stream()
|
validOptions = listValue.getItems().stream()
|
||||||
.map(v -> caseSensitive ? v.getString() : (v.getString().toLowerCase(Locale.ROOT)))
|
.map(v -> caseSensitive ? v.getString() : v.getString().toLowerCase(Locale.ROOT))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -879,11 +878,11 @@ public abstract class CommandArgument
|
|||||||
if (config.containsKey("options"))
|
if (config.containsKey("options"))
|
||||||
{
|
{
|
||||||
Value optionsValue = config.get("options");
|
Value optionsValue = config.get("options");
|
||||||
if (!(optionsValue instanceof ListValue))
|
if (!(optionsValue instanceof final ListValue listValue))
|
||||||
{
|
{
|
||||||
throw error("Custom sting type requires options passed as a list" + " for custom type " + suffix);
|
throw error("Custom sting type requires options passed as a list" + " for custom type " + suffix);
|
||||||
}
|
}
|
||||||
validOptions = ((ListValue) optionsValue).getItems().stream().map(v -> Identifier.parse(v.getString())).collect(Collectors.toSet());
|
validOptions = listValue.getItems().stream().map(v -> Identifier.parse(v.getString())).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1005,6 +1004,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String restrict;
|
private String restrict;
|
||||||
|
@SuppressWarnings("DoubleBraceInitialization")
|
||||||
private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<>()
|
private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<>()
|
||||||
{{
|
{{
|
||||||
int i;
|
int i;
|
||||||
@@ -1293,8 +1293,8 @@ public abstract class CommandArgument
|
|||||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return argumentTypeSupplier != null
|
return argumentTypeSupplier != null
|
||||||
? (() -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples))
|
? () -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples)
|
||||||
: (() -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplierEx, valueExtractor, providesExamples, server));
|
: () -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplierEx, valueExtractor, providesExamples, server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,8 +22,7 @@ public class CommandToken implements Comparable<CommandToken>
|
|||||||
{
|
{
|
||||||
public final String surface;
|
public final String surface;
|
||||||
public final boolean isArgument;
|
public final boolean isArgument;
|
||||||
@Nullable
|
public final @Nullable CommandArgument type;
|
||||||
public final CommandArgument type;
|
|
||||||
|
|
||||||
private CommandToken(String surface, @Nullable CommandArgument type)
|
private CommandToken(String surface, @Nullable CommandArgument type)
|
||||||
{
|
{
|
||||||
@@ -32,8 +31,7 @@ public class CommandToken implements Comparable<CommandToken>
|
|||||||
isArgument = type != null;
|
isArgument = type != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static @Nullable CommandToken getToken(String source, CarpetScriptHost host)
|
||||||
public static CommandToken getToken(String source, CarpetScriptHost host)
|
|
||||||
{
|
{
|
||||||
// todo add more type checking and return null
|
// todo add more type checking and return null
|
||||||
if (!source.startsWith("<"))
|
if (!source.startsWith("<"))
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import org.jspecify.annotations.Nullable;
|
|||||||
/* Exception thrown to terminate execution mid expression (aka return statement) */
|
/* Exception thrown to terminate execution mid expression (aka return statement) */
|
||||||
public class ExitStatement extends StacklessRuntimeException
|
public class ExitStatement extends StacklessRuntimeException
|
||||||
{
|
{
|
||||||
@Nullable
|
public final @Nullable Value retval;
|
||||||
public final Value retval;
|
|
||||||
|
|
||||||
public ExitStatement(@Nullable Value value)
|
public ExitStatement(@Nullable Value value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import java.util.Map;
|
|||||||
public class Throwables
|
public class Throwables
|
||||||
{
|
{
|
||||||
private final String id;
|
private final String id;
|
||||||
@Nullable
|
private final @Nullable Throwables parent;
|
||||||
private final Throwables parent;
|
|
||||||
|
|
||||||
private static final Map<String, Throwables> byId = new HashMap<>();
|
private static final Map<String, Throwables> byId = new HashMap<>();
|
||||||
|
|
||||||
|
|||||||
+3
-38
@@ -147,49 +147,14 @@ public class Carpet
|
|||||||
return CarpetSettings.superSecretSetting;
|
return CarpetSettings.superSecretSetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static @Nullable Path fetchGlobalPath(MinecraftServer server) {
|
||||||
public static Module fetchGlobalModule(String name, boolean allowLibraries) throws IOException
|
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
|
||||||
{
|
|
||||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT)
|
|
||||||
{
|
|
||||||
Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
||||||
if (!Files.exists(globalFolder))
|
return globalFolder;
|
||||||
{
|
|
||||||
Files.createDirectories(globalFolder);
|
|
||||||
}
|
|
||||||
try (Stream<Path> folderWalker = Files.walk(globalFolder))
|
|
||||||
{
|
|
||||||
Optional<Path> scriptPath = folderWalker
|
|
||||||
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
|
||||||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
|
|
||||||
.findFirst();
|
|
||||||
if (scriptPath.isPresent())
|
|
||||||
{
|
|
||||||
return Module.fromPath(scriptPath.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addGlobalModules(final List<String> moduleNames, boolean includeBuiltIns) throws IOException
|
|
||||||
{
|
|
||||||
if (includeBuiltIns && (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT))
|
|
||||||
{
|
|
||||||
Path globalScripts = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
|
||||||
if (!Files.exists(globalScripts))
|
|
||||||
{
|
|
||||||
Files.createDirectories(globalScripts);
|
|
||||||
}
|
|
||||||
try (Stream<Path> folderWalker = Files.walk(globalScripts, FileVisitOption.FOLLOW_LINKS))
|
|
||||||
{
|
|
||||||
folderWalker
|
|
||||||
.filter(f -> f.toString().endsWith(".sc"))
|
|
||||||
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$", "").toLowerCase(Locale.ROOT)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void assertRequirementMet(CarpetScriptHost host, String requiredModId, String stringPredicate)
|
public static void assertRequirementMet(CarpetScriptHost host, String requiredModId, String stringPredicate)
|
||||||
{
|
{
|
||||||
VersionPredicate predicate;
|
VersionPredicate predicate;
|
||||||
|
|||||||
+9
-5
@@ -17,7 +17,10 @@ import com.mojang.brigadier.CommandDispatcher;
|
|||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.fabricmc.loader.api.ModContainer;
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
|
import net.minecraft.commands.CommandResultCallback;
|
||||||
|
import net.minecraft.commands.CommandSigningContext;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
|
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||||
import net.minecraft.commands.arguments.blocks.BlockInput;
|
import net.minecraft.commands.arguments.blocks.BlockInput;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
@@ -31,6 +34,7 @@ import net.minecraft.server.level.ServerPlayerGameMode;
|
|||||||
import net.minecraft.server.level.Ticket;
|
import net.minecraft.server.level.Ticket;
|
||||||
import net.minecraft.server.permissions.PermissionSet;
|
import net.minecraft.server.permissions.PermissionSet;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
|
import net.minecraft.util.TaskChainer;
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
@@ -64,6 +68,7 @@ import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.OptionalLong;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@@ -109,11 +114,6 @@ public class Vanilla
|
|||||||
return ((TicketsFetcherInterface) ticketManager).getTicketsByPosition();
|
return ((TicketsFetcherInterface) ticketManager).getTicketsByPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DensityFunction.Visitor RandomState_getVisitor(RandomState randomState)
|
|
||||||
{
|
|
||||||
return ((RandomStateVisitorAccessor) (Object) randomState).getVisitor();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CompoundTag BlockInput_getTag(BlockInput blockInput)
|
public static CompoundTag BlockInput_getTag(BlockInput blockInput)
|
||||||
{
|
{
|
||||||
return ((BlockStateArgumentInterface) blockInput).getCMTag();
|
return ((BlockStateArgumentInterface) blockInput).getCMTag();
|
||||||
@@ -144,6 +144,10 @@ public class Vanilla
|
|||||||
return CarpetSettings.runPermissionLevel;
|
return CarpetSettings.runPermissionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void CommandSourceStack_setupPrivates(CommandSourceStack css, boolean bl, CommandResultCallback commandResultCallback, EntityAnchorArgument.Anchor anchor, CommandSigningContext commandSigningContext, TaskChainer taskChainer) {
|
||||||
|
((CommandSourceStackInterface) css).setupPrivates(bl, commandResultCallback, anchor, commandSigningContext, taskChainer);
|
||||||
|
};
|
||||||
|
|
||||||
public static int [] MinecraftServer_getReleaseTarget(MinecraftServer server)
|
public static int [] MinecraftServer_getReleaseTarget(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return CarpetSettings.releaseTarget;
|
return CarpetSettings.releaseTarget;
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ public class Arithmetic
|
|||||||
expression.addMathematicalUnaryFunction("cot", d -> 1.0 / Math.tan(Math.toRadians(d))); // Formula: cot(x) = cos(x) / sin(x) = 1 / tan(x)
|
expression.addMathematicalUnaryFunction("cot", d -> 1.0 / Math.tan(Math.toRadians(d))); // Formula: cot(x) = cos(x) / sin(x) = 1 / tan(x)
|
||||||
expression.addMathematicalUnaryFunction("acot", d -> Math.toDegrees(Math.atan(1.0 / d)));// Formula: acot(x) = atan(1/x)
|
expression.addMathematicalUnaryFunction("acot", d -> Math.toDegrees(Math.atan(1.0 / d)));// Formula: acot(x) = atan(1/x)
|
||||||
expression.addMathematicalUnaryFunction("coth", d -> 1.0 / Math.tanh(d)); // Formula: coth(x) = 1 / tanh(x)
|
expression.addMathematicalUnaryFunction("coth", d -> 1.0 / Math.tanh(d)); // Formula: coth(x) = 1 / tanh(x)
|
||||||
expression.addMathematicalUnaryFunction("asinh", d -> Math.log(d + (Math.sqrt(Math.pow(d, 2) + 1)))); // Formula: asinh(x) = ln(x + sqrt(x^2 + 1))
|
expression.addMathematicalUnaryFunction("asinh", d -> Math.log(d + Math.sqrt(Math.pow(d, 2) + 1))); // Formula: asinh(x) = ln(x + sqrt(x^2 + 1))
|
||||||
expression.addMathematicalUnaryFunction("acosh", d -> Math.log(d + (Math.sqrt(Math.pow(d, 2) - 1)))); // Formula: acosh(x) = ln(x + sqrt(x^2 - 1))
|
expression.addMathematicalUnaryFunction("acosh", d -> Math.log(d + Math.sqrt(Math.pow(d, 2) - 1))); // Formula: acosh(x) = ln(x + sqrt(x^2 - 1))
|
||||||
expression.addMathematicalUnaryFunction("atanh", d -> // Formula: atanh(x) = 0.5*ln((1 + x)/(1 - x))
|
expression.addMathematicalUnaryFunction("atanh", d -> // Formula: atanh(x) = 0.5*ln((1 + x)/(1 - x))
|
||||||
{
|
{
|
||||||
if (Math.abs(d) > 1 || Math.abs(d) == 1)
|
if (Math.abs(d) > 1 || Math.abs(d) == 1)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import carpet.script.value.ListValue;
|
|||||||
import carpet.script.value.MapValue;
|
import carpet.script.value.MapValue;
|
||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -23,21 +24,19 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class Operators
|
public class Operators
|
||||||
{
|
{
|
||||||
public static final Map<String, Integer> precedence = new HashMap<>()
|
public static final Map<String, Integer> precedence = ImmutableMap.<String, Integer>builder()
|
||||||
{{
|
.put("attribute~:", 80)
|
||||||
put("attribute~:", 80);
|
.put("unary+-!...", 60)
|
||||||
put("unary+-!...", 60);
|
.put("exponent^", 40)
|
||||||
put("exponent^", 40);
|
.put("multiplication*/%", 30)
|
||||||
put("multiplication*/%", 30);
|
.put("addition+-", 20)
|
||||||
put("addition+-", 20);
|
.put("compare>=><=<", 10)
|
||||||
put("compare>=><=<", 10);
|
.put("equal==!=", 7)
|
||||||
put("equal==!=", 7);
|
.put("and&&", 5)
|
||||||
put("and&&", 5);
|
.put("or||", 4)
|
||||||
put("or||", 4);
|
.put("assign=<>", 3)
|
||||||
put("assign=<>", 3);
|
.put("def->", 2)
|
||||||
put("def->", 2);
|
.put("nextop;", 1).build();
|
||||||
put("nextop;", 1);
|
|
||||||
}};
|
|
||||||
|
|
||||||
public static void apply(Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
@@ -149,7 +148,7 @@ public class Operators
|
|||||||
expression.addLazyBinaryOperator("&&", "and", precedence.get("and&&"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
expression.addLazyBinaryOperator("&&", "and", precedence.get("and&&"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
||||||
{ // todo check how is optimizations going
|
{ // todo check how is optimizations going
|
||||||
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||||
return v1.getBoolean() ? lv2 : ((cc, tt) -> v1);
|
return v1.getBoolean() ? lv2 : (cc, tt) -> v1;
|
||||||
}, (c, t, lv) -> {
|
}, (c, t, lv) -> {
|
||||||
int last = lv.size() - 1;
|
int last = lv.size() - 1;
|
||||||
if (last == -1)
|
if (last == -1)
|
||||||
@@ -184,7 +183,7 @@ public class Operators
|
|||||||
expression.addLazyBinaryOperator("||", "or", precedence.get("or||"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
expression.addLazyBinaryOperator("||", "or", precedence.get("or||"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
||||||
{
|
{
|
||||||
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||||
return v1.getBoolean() ? ((cc, tt) -> v1) : lv2;
|
return v1.getBoolean() ? (cc, tt) -> v1 : lv2;
|
||||||
}, (c, t, lv) -> {
|
}, (c, t, lv) -> {
|
||||||
int last = lv.size() - 1;
|
int last = lv.size() - 1;
|
||||||
if (last == -1)
|
if (last == -1)
|
||||||
@@ -379,7 +378,7 @@ public class Operators
|
|||||||
return (cc, tt) -> Value.NULL;
|
return (cc, tt) -> Value.NULL;
|
||||||
}
|
}
|
||||||
Value address = lcv.address();
|
Value address = lcv.address();
|
||||||
if (!(container.put(address, v2)))
|
if (!container.put(address, v2))
|
||||||
{
|
{
|
||||||
return (cc, tt) -> Value.NULL;
|
return (cc, tt) -> Value.NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -493,7 +493,7 @@ public class Sys
|
|||||||
c.host.scriptServer().systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c));
|
c.host.scriptServer().systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c));
|
||||||
}
|
}
|
||||||
Value res = c.host.scriptServer().systemGlobals.get(key);
|
Value res = c.host.scriptServer().systemGlobals.get(key);
|
||||||
return res == null ? LazyValue.NULL : ((cc, tt) -> res);
|
return res == null ? LazyValue.NULL : (cc, tt) -> res;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("system_variable_set", 2, (c, t, lv) ->
|
expression.addContextFunction("system_variable_set", 2, (c, t, lv) ->
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class Threading
|
|||||||
|
|
||||||
|
|
||||||
expression.addContextFunction("task_count", -1, (c, t, lv) ->
|
expression.addContextFunction("task_count", -1, (c, t, lv) ->
|
||||||
(!lv.isEmpty()) ? new NumericValue(c.host.taskCount(lv.get(0))) : new NumericValue(c.host.taskCount()));
|
!lv.isEmpty() ? new NumericValue(c.host.taskCount(lv.get(0))) : new NumericValue(c.host.taskCount()));
|
||||||
|
|
||||||
expression.addUnaryFunction("task_value", v ->
|
expression.addUnaryFunction("task_value", v ->
|
||||||
{
|
{
|
||||||
@@ -174,7 +174,7 @@ public class Threading
|
|||||||
throw new InternalExpressionException("'task_await' requires a coroutine task value");
|
throw new InternalExpressionException("'task_await' requires a coroutine task value");
|
||||||
}
|
}
|
||||||
Value ret = thread.next();
|
Value ret = thread.next();
|
||||||
return ret == Value.EOL ? ((cc, tt) -> Value.NULL) : ((cc, tt) -> ret);
|
return ret == Value.EOL ? (cc, tt) -> Value.NULL : (cc, tt) -> ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addLazyFunction("task_ready", 1, (c, t, lv) ->
|
expression.addLazyFunction("task_ready", 1, (c, t, lv) ->
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ public class AppStoreManager
|
|||||||
public static class StoreNode
|
public static class StoreNode
|
||||||
{
|
{
|
||||||
public String name;
|
public String name;
|
||||||
@Nullable
|
public @Nullable StoreNode parent;
|
||||||
public StoreNode parent;
|
|
||||||
public Map<String, StoreNode> children;
|
public Map<String, StoreNode> children;
|
||||||
public boolean sealed;
|
public boolean sealed;
|
||||||
public String value;
|
public String value;
|
||||||
@@ -406,7 +405,7 @@ public class AppStoreManager
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unable to write resource " + target);
|
throw new InternalExpressionException("Unable to write resource " + target);
|
||||||
}
|
}
|
||||||
CarpetScriptServer.LOG.info("Downloaded resource " + target + " from " + contentUrl);
|
CarpetScriptServer.LOG.info("Downloaded resource {} from {}", target, contentUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -417,8 +416,7 @@ public class AppStoreManager
|
|||||||
* @param contentUrl The full content URL, from {@link #getFullContentUrl(String, StoreNode, CommandSourceStack)}
|
* @param contentUrl The full content URL, from {@link #getFullContentUrl(String, StoreNode, CommandSourceStack)}
|
||||||
* @return A {@link StoreNode} that can be used in an app that came from the provided source
|
* @return A {@link StoreNode} that can be used in an app that came from the provided source
|
||||||
*/
|
*/
|
||||||
@Nullable
|
private static @Nullable StoreNode getNewStoreNode(CommandSourceStack commandSource, StoreNode originalSource, String sourceString, String contentUrl)
|
||||||
private static StoreNode getNewStoreNode(CommandSourceStack commandSource, StoreNode originalSource, String sourceString, String contentUrl)
|
|
||||||
{
|
{
|
||||||
StoreNode next = originalSource;
|
StoreNode next = originalSource;
|
||||||
if (sourceString == contentUrl) // External URL (check getFullUrlContent)
|
if (sourceString == contentUrl) // External URL (check getFullUrlContent)
|
||||||
@@ -471,7 +469,7 @@ public class AppStoreManager
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Error when installing app dependencies: " + e);
|
throw new InternalExpressionException("Error when installing app dependencies: " + e);
|
||||||
}
|
}
|
||||||
CarpetScriptServer.LOG.info("Downloaded app " + target + " from " + contentUrl);
|
CarpetScriptServer.LOG.info("Downloaded app {} from {}", target, contentUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CommandRuntimeException extends RuntimeException {
|
public static class CommandRuntimeException extends RuntimeException {
|
||||||
|
|||||||
@@ -20,9 +20,11 @@ import net.minecraft.world.attribute.EnvironmentAttribute;
|
|||||||
import net.minecraft.world.attribute.EnvironmentAttributes;
|
import net.minecraft.world.attribute.EnvironmentAttributes;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||||
|
import org.joml.Vector3fc;
|
||||||
|
|
||||||
public class BiomeInfo
|
public class BiomeInfo
|
||||||
{
|
{
|
||||||
|
@SuppressWarnings("DoubleBraceInitialization")
|
||||||
public static final Map<String, BiFunction<ServerLevel, Biome, Value>> biomeFeatures = new HashMap<>()
|
public static final Map<String, BiFunction<ServerLevel, Biome, Value>> biomeFeatures = new HashMap<>()
|
||||||
{{
|
{{
|
||||||
put("tags", (w, b) -> ListValue.wrap(w.registryAccess().lookupOrThrow(Registries.BIOME).getTags().filter(p -> p.stream().anyMatch(h -> h.value() == b)).map(ValueConversions::of)));
|
put("tags", (w, b) -> ListValue.wrap(w.registryAccess().lookupOrThrow(Registries.BIOME).getTags().filter(p -> p.stream().anyMatch(h -> h.value() == b)).map(ValueConversions::of)));
|
||||||
@@ -47,7 +49,7 @@ public class BiomeInfo
|
|||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
private static Value fromEnvironmentalAttribute(ServerLevel w, Biome b, EnvironmentAttribute<Integer> fogColor) {
|
private static Value fromEnvironmentalAttribute(ServerLevel w, Biome b, EnvironmentAttribute<Vector3fc> fogColor) {
|
||||||
return ValueConversions.ofRGB(b.getAttributes().applyModifier(fogColor, w.dimensionType().attributes().applyModifier(fogColor, fogColor.defaultValue())));
|
return ValueConversions.ofRGB(b.getAttributes().applyModifier(fogColor, w.dimensionType().attributes().applyModifier(fogColor, fogColor.defaultValue())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,6 +47,7 @@ import net.minecraft.world.level.levelgen.GenerationStep;
|
|||||||
import net.minecraft.world.level.levelgen.RandomState;
|
import net.minecraft.world.level.levelgen.RandomState;
|
||||||
import net.minecraft.world.level.levelgen.VerticalAnchor;
|
import net.minecraft.world.level.levelgen.VerticalAnchor;
|
||||||
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
|
||||||
|
import net.minecraft.world.level.levelgen.densityfunction.SamplerContext;
|
||||||
import net.minecraft.world.level.levelgen.feature.CoralClawFeature;
|
import net.minecraft.world.level.levelgen.feature.CoralClawFeature;
|
||||||
import net.minecraft.world.level.levelgen.feature.CoralTreeFeature;
|
import net.minecraft.world.level.levelgen.feature.CoralTreeFeature;
|
||||||
import net.minecraft.world.level.levelgen.feature.CuboidPlacement;
|
import net.minecraft.world.level.levelgen.feature.CuboidPlacement;
|
||||||
@@ -85,12 +86,9 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProc
|
|||||||
|
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
import static net.minecraft.world.level.levelgen.feature.TreeFeature.CAN_PLACE_BELOW_TREE_TRUNKS;
|
|
||||||
|
|
||||||
public class FeatureGenerator
|
public class FeatureGenerator
|
||||||
{
|
{
|
||||||
@Nullable
|
public static synchronized @Nullable Boolean plop(String featureName, ServerLevel world, BlockPos pos)
|
||||||
public static synchronized Boolean plop(String featureName, ServerLevel world, BlockPos pos)
|
|
||||||
{
|
{
|
||||||
Function<ServerLevel, Thing> custom = featureMap.get(featureName);
|
Function<ServerLevel, Thing> custom = featureMap.get(featureName);
|
||||||
if (custom != null)
|
if (custom != null)
|
||||||
@@ -148,8 +146,7 @@ public class FeatureGenerator
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static @Nullable Structure resolveConfiguredStructure(String name, ServerLevel world, BlockPos pos)
|
||||||
public static Structure resolveConfiguredStructure(String name, ServerLevel world, BlockPos pos)
|
|
||||||
{
|
{
|
||||||
Identifier id = Identifier.parse(name);
|
Identifier id = Identifier.parse(name);
|
||||||
Structure configuredStructureFeature = world.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValue(id);
|
Structure configuredStructureFeature = world.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValue(id);
|
||||||
@@ -269,8 +266,8 @@ public class FeatureGenerator
|
|||||||
{
|
{
|
||||||
//Holder<Biome> genBiome = generator.getBiomeSource().getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ()), seed.sampler());
|
//Holder<Biome> genBiome = generator.getBiomeSource().getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ()), seed.sampler());
|
||||||
if (structure.findValidGenerationPoint(new Structure.GenerationContext(
|
if (structure.findValidGenerationPoint(new Structure.GenerationContext(
|
||||||
world.registryAccess(), generator, world.uncachedBiomeResolver(),
|
world.registryAccess(), generator, generator.getBiomeSource(), seed.createClimateSampler(SamplerContext.EMPTY_UNCACHED),
|
||||||
seed, world.getStructureManager(), world.getSeed(), chunkPos, world, structureBiomes::contains
|
seed, world.getStructureTemplateManager(), world.getSeed(), chunkPos, world, structureBiomes::contains
|
||||||
)).isPresent())
|
)).isPresent())
|
||||||
{
|
{
|
||||||
return StructureStart.INVALID_START;
|
return StructureStart.INVALID_START;
|
||||||
@@ -279,7 +276,7 @@ public class FeatureGenerator
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
StructureStart filledStructure = structure.generate(Holder.direct(structure), world.dimension(),
|
StructureStart filledStructure = structure.generate(Holder.direct(structure), world.dimension(),
|
||||||
world.registryAccess(), generator, world.uncachedBiomeResolver(), seed, world.getStructureManager(),
|
world.registryAccess(), generator, generator.getBiomeSource(), seed.createClimateSampler(SamplerContext.EMPTY_UNCACHED), seed, world.getStructureTemplateManager(),
|
||||||
world.getSeed(), chunkPos, 0, world, structureBiomes::contains);
|
world.getSeed(), chunkPos, 0, world, structureBiomes::contains);
|
||||||
if (filledStructure != null && filledStructure.isValid())
|
if (filledStructure != null && filledStructure.isValid())
|
||||||
{
|
{
|
||||||
@@ -289,17 +286,17 @@ public class FeatureGenerator
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RuleBasedStateProvider belowTrees = RuleBasedStateProvider.ifTrueThenProvide(CAN_PLACE_BELOW_TREE_TRUNKS, Blocks.DIRT);
|
private static RuleBasedStateProvider belowTrees = RuleBasedStateProvider.ifTrueThenProvide(BlockPredicate.not(BlockPredicate.matchesTag(BlockTags.CANNOT_REPLACE_BELOW_TREE_TRUNK)), Blocks.DIRT);
|
||||||
|
|
||||||
private static TreeFeature.Builder createTree(Block block, Block block2, int i, int j, int k, int l)
|
private static TreeFeature.Builder createTree(Block block, Block block2, int i, int j, int k, int l)
|
||||||
{
|
{
|
||||||
return new TreeFeature.Builder(BlockStateProvider.simple(block), new StraightTrunkPlacer(i, j, k), BlockStateProvider.simple(block2), new BlobFoliagePlacer(ConstantInt.of(l), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), belowTrees);
|
return new TreeFeature.Builder(BlockStateProvider.of(block), new StraightTrunkPlacer(i, j, k), BlockStateProvider.of(block2), new BlobFoliagePlacer(ConstantInt.of(l), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), Holder.direct( belowTrees));
|
||||||
}
|
}
|
||||||
|
|
||||||
// from AquaticFeatures
|
// from AquaticFeatures
|
||||||
private static Holder<PlacedFeature> wallCoral(final HolderGetter<Block> blocks, final Direction direction) {
|
private static Holder<PlacedFeature> wallCoral(final HolderGetter<Block> blocks, final Direction direction) {
|
||||||
return PlacementUtils.inlinePlaced(
|
return PlacementUtils.inlinePlaced(
|
||||||
new SimpleBlockFeature(new RotatedBlockProvider(new RandomBlockProvider(blocks.getOrThrow(BlockTags.WALL_CORALS)), Optional.of(direction))),
|
new SimpleBlockFeature(new RotatedBlockProvider(Holder.direct(new RandomBlockProvider(blocks.getOrThrow(BlockTags.WALL_CORALS))), Optional.of(direction))),
|
||||||
new RandomChancePlacement(0.2f),
|
new RandomChancePlacement(0.2f),
|
||||||
OffsetPlacement.of(direction),
|
OffsetPlacement.of(direction),
|
||||||
BlockPredicateFilter.forPredicate(BlockPredicate.matchesBlocks(Blocks.WATER))
|
BlockPredicateFilter.forPredicate(BlockPredicate.matchesBlocks(Blocks.WATER))
|
||||||
@@ -308,7 +305,7 @@ public class FeatureGenerator
|
|||||||
|
|
||||||
public static Feature coral(final HolderGetter<Feature> features, final HolderGetter<Block> blocks, final Block block) {
|
public static Feature coral(final HolderGetter<Feature> features, final HolderGetter<Block> blocks, final Block block) {
|
||||||
return new OverlayFeature(HolderSet.direct(
|
return new OverlayFeature(HolderSet.direct(
|
||||||
PlacementUtils.inlinePlaced(new SimpleBlockFeature(BlockStateProvider.simple(block))),
|
PlacementUtils.inlinePlaced(new SimpleBlockFeature(BlockStateProvider.of(block))),
|
||||||
PlacementUtils.inlinePlaced(
|
PlacementUtils.inlinePlaced(
|
||||||
new WeightedRandomSelectorFeature(WeightedList.of(
|
new WeightedRandomSelectorFeature(WeightedList.of(
|
||||||
new Weighted<>(PlacementUtils.inlinePlaced(new SimpleBlockFeature(new RandomBlockProvider(blocks.getOrThrow(BlockTags.CORALS)))), 20),
|
new Weighted<>(PlacementUtils.inlinePlaced(new SimpleBlockFeature(new RandomBlockProvider(blocks.getOrThrow(BlockTags.CORALS)))), 20),
|
||||||
@@ -366,14 +363,13 @@ public class FeatureGenerator
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DoubleBraceInitialization")
|
||||||
|
|
||||||
public static final Map<String, Function<ServerLevel, Thing>> featureMap = new HashMap<>()
|
public static final Map<String, Function<ServerLevel, Thing>> featureMap = new HashMap<>()
|
||||||
{{
|
{{
|
||||||
|
|
||||||
// TODO remove this using what place feature is using
|
// TODO remove this using what place feature is using
|
||||||
put("oak_bees", l -> simpleTree(createTree(Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
|
put("oak_bees", l -> simpleTree(createTree(Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
|
||||||
put("fancy_oak_bees", l -> simpleTree(new TreeFeature.Builder(BlockStateProvider.simple(Blocks.OAK_LOG), new FancyTrunkPlacer(3, 11, 0), BlockStateProvider.simple(Blocks.OAK_LEAVES), new FancyFoliagePlacer(ConstantInt.of(2), ConstantInt.of(4), 4), new TwoLayersFeatureSize(0, 0, 0, OptionalInt.of(4)), belowTrees).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
|
put("fancy_oak_bees", l -> simpleTree(new TreeFeature.Builder(BlockStateProvider.of(Blocks.OAK_LOG), new FancyTrunkPlacer(3, 11, 0), BlockStateProvider.of(Blocks.OAK_LEAVES), new FancyFoliagePlacer(ConstantInt.of(2), ConstantInt.of(4), 4), new TwoLayersFeatureSize(0, 0, 0, OptionalInt.of(4)), Holder.direct(belowTrees)).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
|
||||||
put("birch_bees", l -> simpleTree(createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
|
put("birch_bees", l -> simpleTree(createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F)))));
|
||||||
|
|
||||||
put("coral_tree", l -> simplePlop(coral(l, 0)));
|
put("coral_tree", l -> simplePlop(coral(l, 0)));
|
||||||
@@ -508,7 +504,7 @@ public class FeatureGenerator
|
|||||||
checks.set(true);
|
checks.set(true);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
StructureStart start = structure.generate(Holder.direct(structure), world.dimension(), world.registryAccess(), generator, world.uncachedBiomeResolver(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), ChunkPos.containing(pos), 0, world, b -> true);
|
StructureStart start = structure.generate(Holder.direct(structure), world.dimension(), world.registryAccess(), generator, generator.getBiomeSource(), world.getChunkSource().randomState().createClimateSampler(SamplerContext.EMPTY_UNCACHED), world.getChunkSource().randomState(), world.getStructureTemplateManager(), world.getSeed(), ChunkPos.containing(pos), 0, world, b -> true);
|
||||||
if (start == StructureStart.INVALID_START)
|
if (start == StructureStart.INVALID_START)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -552,7 +548,7 @@ public class FeatureGenerator
|
|||||||
}
|
}
|
||||||
catch (Exception booboo)
|
catch (Exception booboo)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.error("Unknown Exception while plopping structure: " + booboo, booboo);
|
CarpetScriptServer.LOG.error("Unknown Exception while plopping structure: {}", booboo, booboo);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ public class GlocalFlag extends ThreadLocal<Boolean>
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public <T> @Nullable T runIfEnabled(Supplier<T> action)
|
||||||
public <T> T runIfEnabled(Supplier<T> action)
|
|
||||||
{
|
{
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ public class ParticleParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static @Nullable ParticleOptions getEffect(@Nullable String name, RegistryAccess lookup)
|
||||||
public static ParticleOptions getEffect(@Nullable String name, RegistryAccess lookup)
|
|
||||||
{
|
{
|
||||||
if (name == null)
|
if (name == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import carpet.script.value.StringValue;
|
|||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import carpet.script.value.ValueConversions;
|
import carpet.script.value.ValueConversions;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
@@ -236,8 +237,7 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
// client
|
// client
|
||||||
@Nullable
|
public static @Nullable ExpiringShape fromTag(CompoundTag tag, Level level)
|
||||||
public static ExpiringShape fromTag(CompoundTag tag, Level level)
|
|
||||||
{
|
{
|
||||||
Map<String, Value> options = new HashMap<>();
|
Map<String, Value> options = new HashMap<>();
|
||||||
for (String key : tag.keySet())
|
for (String key : tag.keySet())
|
||||||
@@ -245,7 +245,7 @@ public class ShapeDispatcher
|
|||||||
Param decoder = Param.of.get(key);
|
Param decoder = Param.of.get(key);
|
||||||
if (decoder == null)
|
if (decoder == null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info("Unknown parameter for shape: " + key);
|
CarpetScriptServer.LOG.info("Unknown parameter for shape: {}", key);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Value decodedValue = decoder.decode(tag.get(key), level);
|
Value decodedValue = decoder.decode(tag.get(key), level);
|
||||||
@@ -254,13 +254,13 @@ public class ShapeDispatcher
|
|||||||
Value shapeValue = options.get("shape");
|
Value shapeValue = options.get("shape");
|
||||||
if (shapeValue == null)
|
if (shapeValue == null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info("Shape id missing in " + String.join(", ", tag.keySet()));
|
CarpetScriptServer.LOG.info("Shape id missing in {}", String.join(", ", tag.keySet()));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeValue.getString());
|
BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeValue.getString());
|
||||||
if (factory == null)
|
if (factory == null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info("Unknown shape: " + shapeValue.getString());
|
CarpetScriptServer.LOG.info("Unknown shape: {}", shapeValue.getString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
@@ -269,24 +269,23 @@ public class ShapeDispatcher
|
|||||||
}
|
}
|
||||||
catch (InternalExpressionException exc)
|
catch (InternalExpressionException exc)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info(exc.getMessage());
|
CarpetScriptServer.LOG.info("", exc);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract static class ExpiringShape
|
public abstract static class ExpiringShape
|
||||||
{
|
{
|
||||||
public static final Map<String, BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape>> shapeProviders = new HashMap<>()
|
public static final ImmutableMap<String, BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape>> shapeProviders = ImmutableMap.<String, BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape>>builder().
|
||||||
{{
|
put("line", creator(Line::new)).
|
||||||
put("line", creator(Line::new));
|
put("box", creator(Box::new)).
|
||||||
put("box", creator(Box::new));
|
put("sphere", creator(Sphere::new)).
|
||||||
put("sphere", creator(Sphere::new));
|
put("cylinder", creator(Cylinder::new)).
|
||||||
put("cylinder", creator(Cylinder::new));
|
put("label", creator(DisplayedText::new)).
|
||||||
put("label", creator(DisplayedText::new));
|
put("polygon", creator(Polyface::new)).
|
||||||
put("polygon", creator(Polyface::new));
|
put("block", creator(() -> new DisplayedSprite(false))).
|
||||||
put("block", creator(() -> new DisplayedSprite(false)));
|
put("item", creator(() -> new DisplayedSprite(true))).
|
||||||
put("item", creator(() -> new DisplayedSprite(true)));
|
build();
|
||||||
}};
|
|
||||||
|
|
||||||
private static BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> creator(Supplier<ExpiringShape> shapeFactory)
|
private static BiFunction<Map<String, Value>, RegistryAccess, ExpiringShape> creator(Supplier<ExpiringShape> shapeFactory)
|
||||||
{
|
{
|
||||||
@@ -978,78 +977,65 @@ public class ShapeDispatcher
|
|||||||
return alterPoint;
|
return alterPoint;
|
||||||
}
|
}
|
||||||
alterPoint = new ArrayList<>();
|
alterPoint = new ArrayList<>();
|
||||||
switch (mode)
|
switch (mode) {
|
||||||
{
|
case 4 -> {
|
||||||
case 4:
|
for (int i = 0; i < vertexList.size(); i++) {
|
||||||
for (int i = 0; i < vertexList.size(); i++)
|
|
||||||
{
|
|
||||||
Vec3 vecA = vertexList.get(i);
|
Vec3 vecA = vertexList.get(i);
|
||||||
if (relative.get(i))
|
if (relative.get(i)) {
|
||||||
{
|
|
||||||
vecA = relativiseRender(p.level(), vecA, 0);
|
vecA = relativiseRender(p.level(), vecA, 0);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
Vec3 vecB = vertexList.get(i);
|
Vec3 vecB = vertexList.get(i);
|
||||||
if (relative.get(i))
|
if (relative.get(i)) {
|
||||||
{
|
|
||||||
vecB = relativiseRender(p.level(), vecB, 0);
|
vecB = relativiseRender(p.level(), vecB, 0);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
Vec3 vecC = vertexList.get(i);
|
Vec3 vecC = vertexList.get(i);
|
||||||
if (relative.get(i))
|
if (relative.get(i)) {
|
||||||
{
|
|
||||||
vecC = relativiseRender(p.level(), vecC, 0);
|
vecC = relativiseRender(p.level(), vecC, 0);
|
||||||
}
|
}
|
||||||
alterDrawTriangles(vecA, vecB, vecC);
|
alterDrawTriangles(vecA, vecB, vecC);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 6:
|
case 6 -> {
|
||||||
Vec3 vec0 = vertexList.get(0);
|
Vec3 vec0 = vertexList.get(0);
|
||||||
if (relative.get(0))
|
if (relative.get(0)) {
|
||||||
{
|
|
||||||
vec0 = relativiseRender(p.level(), vec0, 0);
|
vec0 = relativiseRender(p.level(), vec0, 0);
|
||||||
}
|
}
|
||||||
Vec3 vec1 = vertexList.get(1);
|
Vec3 vec1 = vertexList.get(1);
|
||||||
if (relative.get(1))
|
if (relative.get(1)) {
|
||||||
{
|
|
||||||
vec1 = relativiseRender(p.level(), vec1, 0);
|
vec1 = relativiseRender(p.level(), vec1, 0);
|
||||||
}
|
}
|
||||||
for (int i = 2; i < vertexList.size(); i++)
|
for (int i = 2; i < vertexList.size(); i++) {
|
||||||
{
|
|
||||||
Vec3 vec = vertexList.get(i);
|
Vec3 vec = vertexList.get(i);
|
||||||
if (relative.get(i))
|
if (relative.get(i)) {
|
||||||
{
|
|
||||||
vec = relativiseRender(p.level(), vec, 0);
|
vec = relativiseRender(p.level(), vec, 0);
|
||||||
}
|
}
|
||||||
alterDrawTriangles(vec0, vec1, vec);
|
alterDrawTriangles(vec0, vec1, vec);
|
||||||
vec1 = vec;
|
vec1 = vec;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 5:
|
case 5 -> {
|
||||||
Vec3 vecA = vertexList.get(0);
|
Vec3 vecA = vertexList.get(0);
|
||||||
if (relative.get(0))
|
if (relative.get(0)) {
|
||||||
{
|
|
||||||
vecA = relativiseRender(p.level(), vecA, 0);
|
vecA = relativiseRender(p.level(), vecA, 0);
|
||||||
}
|
}
|
||||||
Vec3 vecB = vertexList.get(1);
|
Vec3 vecB = vertexList.get(1);
|
||||||
if (relative.get(1))
|
if (relative.get(1)) {
|
||||||
{
|
|
||||||
vecB = relativiseRender(p.level(), vecB, 0);
|
vecB = relativiseRender(p.level(), vecB, 0);
|
||||||
}
|
}
|
||||||
for (int i = 2; i < vertexList.size(); i++)
|
for (int i = 2; i < vertexList.size(); i++) {
|
||||||
{
|
|
||||||
Vec3 vec = vertexList.get(i);
|
Vec3 vec = vertexList.get(i);
|
||||||
if (relative.get(i))
|
if (relative.get(i)) {
|
||||||
{
|
|
||||||
vec = relativiseRender(p.level(), vec, 0);
|
vec = relativiseRender(p.level(), vec, 0);
|
||||||
}
|
}
|
||||||
alterDrawTriangles(vecA, vecB, vec);
|
alterDrawTriangles(vecA, vecB, vec);
|
||||||
vecA = vecB;
|
vecA = vecB;
|
||||||
vecB = vec;
|
vecB = vec;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default:
|
default -> {
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return alterPoint;
|
return alterPoint;
|
||||||
@@ -1466,85 +1452,81 @@ public class ShapeDispatcher
|
|||||||
|
|
||||||
public abstract static class Param
|
public abstract static class Param
|
||||||
{
|
{
|
||||||
public static final Map<String, Param> of = new HashMap<>()
|
public static final ImmutableMap<String, Param> of = ImmutableMap.<String, Param>builder()
|
||||||
{{
|
.put("mode", new StringChoiceParam("mode", "polygon", "strip", "triangles"))
|
||||||
put("mode", new StringChoiceParam("mode", "polygon", "strip", "triangles"));
|
.put("relative", new OptionalBoolListParam("relative"))
|
||||||
put("relative", new OptionalBoolListParam("relative"));
|
.put("inner", new BoolParam("inner"))
|
||||||
put("inner", new BoolParam("inner"));
|
.put("shape", new ShapeParam())
|
||||||
put("shape", new ShapeParam());
|
.put("dim", new DimensionParam())
|
||||||
put("dim", new DimensionParam());
|
.put("duration", new NonNegativeIntParam("duration"))
|
||||||
put("duration", new NonNegativeIntParam("duration"));
|
.put("color", new ColorParam("color"))
|
||||||
put("color", new ColorParam("color"));
|
.put("follow", new EntityParam("follow"))
|
||||||
put("follow", new EntityParam("follow"));
|
.put("variant", new StringChoiceParam("variant",
|
||||||
put("variant", new StringChoiceParam("variant",
|
"NONE",
|
||||||
"NONE",
|
"THIRD_PERSON_LEFT_HAND",
|
||||||
"THIRD_PERSON_LEFT_HAND",
|
"THIRD_PERSON_RIGHT_HAND",
|
||||||
"THIRD_PERSON_RIGHT_HAND",
|
"FIRST_PERSON_LEFT_HAND",
|
||||||
"FIRST_PERSON_LEFT_HAND",
|
"FIRST_PERSON_RIGHT_HAND",
|
||||||
"FIRST_PERSON_RIGHT_HAND",
|
"HEAD",
|
||||||
"HEAD",
|
"GUI",
|
||||||
"GUI",
|
"GROUND",
|
||||||
"GROUND",
|
"FIXED",
|
||||||
"FIXED",
|
"ON_SHELF")
|
||||||
"ON_SHELF")
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public Value validate(Map<String, Value> o, MinecraftServer s, Value v)
|
|
||||||
{
|
{
|
||||||
return super.validate(o, s, new StringValue(v.getString().toUpperCase(Locale.ROOT)));
|
@Override
|
||||||
}
|
public Value validate(Map<String, Value> o, MinecraftServer s, Value v)
|
||||||
});
|
|
||||||
put("snap", new StringChoiceParam("snap",
|
|
||||||
"xyz", "xz", "yz", "xy", "x", "y", "z",
|
|
||||||
"dxdydz", "dxdz", "dydz", "dxdy", "dx", "dy", "dz",
|
|
||||||
"xdz", "dxz", "ydz", "dyz", "xdy", "dxy",
|
|
||||||
"xydz", "xdyz", "xdydz", "dxyz", "dxydz", "dxdyz"
|
|
||||||
));
|
|
||||||
put("line", new PositiveFloatParam("line"));
|
|
||||||
put("fill", new ColorParam("fill"));
|
|
||||||
|
|
||||||
put("from", new Vec3Param("from", false));
|
|
||||||
put("to", new Vec3Param("to", true));
|
|
||||||
put("center", new Vec3Param("center", false));
|
|
||||||
put("pos", new Vec3Param("pos", false));
|
|
||||||
put("radius", new PositiveFloatParam("radius"));
|
|
||||||
put("level", new PositiveIntParam("level"));
|
|
||||||
put("height", new FloatParam("height"));
|
|
||||||
put("width", new FloatParam("width"));
|
|
||||||
put("scale", new Vec3Param("scale", false)
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public Value validate(java.util.Map<String, Value> options, MinecraftServer server, Value value)
|
|
||||||
{
|
|
||||||
if (value instanceof final NumericValue vn)
|
|
||||||
{
|
{
|
||||||
value = ListValue.of(vn, vn, vn);
|
return super.validate(o, s, new StringValue(v.getString().toUpperCase(Locale.ROOT)));
|
||||||
}
|
}
|
||||||
return super.validate(options, server, value);
|
})
|
||||||
}
|
.put("snap", new StringChoiceParam("snap",
|
||||||
|
"xyz", "xz", "yz", "xy", "x", "y", "z",
|
||||||
|
"dxdydz", "dxdz", "dydz", "dxdy", "dx", "dy", "dz",
|
||||||
|
"xdz", "dxz", "ydz", "dyz", "xdy", "dxy",
|
||||||
|
"xydz", "xdyz", "xdydz", "dxyz", "dxydz", "dxdyz"
|
||||||
|
))
|
||||||
|
.put("line", new PositiveFloatParam("line"))
|
||||||
|
.put("fill", new ColorParam("fill"))
|
||||||
|
.put("from", new Vec3Param("from", false))
|
||||||
|
.put("to", new Vec3Param("to", true))
|
||||||
|
.put("center", new Vec3Param("center", false))
|
||||||
|
.put("pos", new Vec3Param("pos", false))
|
||||||
|
.put("radius", new PositiveFloatParam("radius"))
|
||||||
|
.put("level", new PositiveIntParam("level"))
|
||||||
|
.put("height", new FloatParam("height"))
|
||||||
|
.put("width", new FloatParam("width"))
|
||||||
|
.put("scale", new Vec3Param("scale", false)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Value validate(java.util.Map<String, Value> options, MinecraftServer server, Value value)
|
||||||
|
{
|
||||||
|
if (value instanceof final NumericValue vn)
|
||||||
|
{
|
||||||
|
value = ListValue.of(vn, vn, vn);
|
||||||
|
}
|
||||||
|
return super.validate(options, server, value);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.put("axis", new StringChoiceParam("axis", "x", "y", "z"))
|
||||||
|
.put("points", new PointsParam("points"))
|
||||||
|
.put("text", new FormattedTextParam("text"))
|
||||||
|
.put("value", new FormattedTextParam("value"))
|
||||||
|
.put("size", new PositiveIntParam("size"))
|
||||||
|
.put("align", new StringChoiceParam("align", "center", "left", "right"))
|
||||||
|
.put("block", new BlockParam("block"))
|
||||||
|
.put("item", new ItemParam("item"))
|
||||||
|
.put("blocklight", new NonNegativeIntParam("blocklight"))
|
||||||
|
.put("skylight", new NonNegativeIntParam("skylight"))
|
||||||
|
.put("indent", new FloatParam("indent"))
|
||||||
|
.put("raise", new FloatParam("raise"))
|
||||||
|
.put("tilt", new FloatParam("tilt"))
|
||||||
|
.put("lean", new FloatParam("lean"))
|
||||||
|
.put("turn", new FloatParam("turn"))
|
||||||
|
.put("facing", new StringChoiceParam("facing", "player", "camera", "north", "south", "east", "west", "up", "down"))
|
||||||
|
.put("doublesided", new BoolParam("doublesided"))
|
||||||
|
.put("debug", new BoolParam("debug"))
|
||||||
|
.build();
|
||||||
|
|
||||||
});
|
|
||||||
put("axis", new StringChoiceParam("axis", "x", "y", "z"));
|
|
||||||
put("points", new PointsParam("points"));
|
|
||||||
put("text", new FormattedTextParam("text"));
|
|
||||||
put("value", new FormattedTextParam("value"));
|
|
||||||
put("size", new PositiveIntParam("size"));
|
|
||||||
put("align", new StringChoiceParam("align", "center", "left", "right"));
|
|
||||||
|
|
||||||
put("block", new BlockParam("block"));
|
|
||||||
put("item", new ItemParam("item"));
|
|
||||||
put("blocklight", new NonNegativeIntParam("blocklight"));
|
|
||||||
put("skylight", new NonNegativeIntParam("skylight"));
|
|
||||||
put("indent", new FloatParam("indent"));
|
|
||||||
put("raise", new FloatParam("raise"));
|
|
||||||
put("tilt", new FloatParam("tilt"));
|
|
||||||
put("lean", new FloatParam("lean"));
|
|
||||||
put("turn", new FloatParam("turn"));
|
|
||||||
put("facing", new StringChoiceParam("facing", "player", "camera", "north", "south", "east", "west", "up", "down"));
|
|
||||||
put("doublesided", new BoolParam("doublesided"));
|
|
||||||
put("debug", new BoolParam("debug"));
|
|
||||||
|
|
||||||
}};
|
|
||||||
protected String id;
|
protected String id;
|
||||||
|
|
||||||
protected Param(String id)
|
protected Param(String id)
|
||||||
@@ -1552,8 +1534,7 @@ public class ShapeDispatcher
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public abstract @Nullable Tag toTag(Value value, final RegistryAccess regs); //validates value, returning null if not necessary to keep it and serialize
|
||||||
public abstract Tag toTag(Value value, final RegistryAccess regs); //validates value, returning null if not necessary to keep it and serialize
|
|
||||||
|
|
||||||
public abstract Value validate(Map<String, Value> options, MinecraftServer server, Value value); // makes sure the value is proper
|
public abstract Value validate(Map<String, Value> options, MinecraftServer server, Value value); // makes sure the value is proper
|
||||||
|
|
||||||
@@ -1640,9 +1621,8 @@ public class ShapeDispatcher
|
|||||||
return BlockValue.fromString(value.getString(), server.overworld());
|
return BlockValue.fromString(value.getString(), server.overworld());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(Value value, final RegistryAccess regs)
|
public @Nullable Tag toTag(Value value, final RegistryAccess regs)
|
||||||
{
|
{
|
||||||
if (value instanceof final BlockValue blv)
|
if (value instanceof final BlockValue blv)
|
||||||
{
|
{
|
||||||
@@ -1758,9 +1738,8 @@ public class ShapeDispatcher
|
|||||||
this.options = Sets.newHashSet(options);
|
this.options = Sets.newHashSet(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public Value validate(Map<String, Value> options, MinecraftServer server, Value value)
|
public @Nullable Value validate(Map<String, Value> options, MinecraftServer server, Value value)
|
||||||
{
|
{
|
||||||
if (this.options.contains(value.getString()))
|
if (this.options.contains(value.getString()))
|
||||||
{
|
{
|
||||||
@@ -2046,7 +2025,7 @@ public class ShapeDispatcher
|
|||||||
new NumericValue(e.getZ())
|
new NumericValue(e.getZ())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
CarpetScriptServer.LOG.error("Value: " + value.getString());
|
CarpetScriptServer.LOG.error("Value: {}", value.getString());
|
||||||
throw new InternalExpressionException("'" + p.id + "' requires a triple, block or entity to indicate position");
|
throw new InternalExpressionException("'" + p.id + "' requires a triple, block or entity to indicate position");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2206,7 +2185,7 @@ public class ShapeDispatcher
|
|||||||
{
|
{
|
||||||
ServerLevel world = player.level();
|
ServerLevel world = player.level();
|
||||||
world.sendParticles(player, particle, true, true,
|
world.sendParticles(player, particle, true, true,
|
||||||
(towards.x) / 2 + from.x, (towards.y) / 2 + from.y, (towards.z) / 2 + from.z, particles / 3,
|
towards.x / 2 + from.x, towards.y / 2 + from.y, towards.z / 2 + from.z, particles / 3,
|
||||||
towards.x / 6, towards.y / 6, towards.z / 6, 0.0);
|
towards.x / 6, towards.y / 6, towards.z / 6, 0.0);
|
||||||
world.sendParticles(player, particle, true, true,
|
world.sendParticles(player, particle, true, true,
|
||||||
from.x, from.y, from.z, 1, 0.0, 0.0, 0.0, 0.0);
|
from.x, from.y, from.z, 1, 0.0, 0.0, 0.0, 0.0);
|
||||||
@@ -2223,10 +2202,10 @@ public class ShapeDispatcher
|
|||||||
{
|
{
|
||||||
ServerLevel world = player.level();
|
ServerLevel world = player.level();
|
||||||
world.sendParticles(player, particle, true, true,
|
world.sendParticles(player, particle, true, true,
|
||||||
(towards.x) / center + from.x, (towards.y) / center + from.y, (towards.z) / center + from.z, particles / divider,
|
towards.x / center + from.x, towards.y / center + from.y, towards.z / center + from.z, particles / divider,
|
||||||
towards.x / dev, towards.y / dev, towards.z / dev, 0.0);
|
towards.x / dev, towards.y / dev, towards.z / dev, 0.0);
|
||||||
world.sendParticles(player, particle, true, true,
|
world.sendParticles(player, particle, true, true,
|
||||||
(towards.x) * (1.0 - 1.0 / center) + from.x, (towards.y) * (1.0 - 1.0 / center) + from.y, (towards.z) * (1.0 - 1.0 / center) + from.z, particles / divider,
|
towards.x * (1.0 - 1.0 / center) + from.x, towards.y * (1.0 - 1.0 / center) + from.y, towards.z * (1.0 - 1.0 / center) + from.z, particles / divider,
|
||||||
towards.x / dev, towards.y / dev, towards.z / dev, 0.0);
|
towards.x / dev, towards.y / dev, towards.z / dev, 0.0);
|
||||||
}
|
}
|
||||||
parts += 2 * particles / divider;
|
parts += 2 * particles / divider;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import carpet.script.CarpetScriptServer;
|
|||||||
import carpet.script.external.Carpet;
|
import carpet.script.external.Carpet;
|
||||||
import carpet.script.utils.shapes.ShapeDirection;
|
import carpet.script.utils.shapes.ShapeDirection;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.mojang.blaze3d.pipeline.RenderTarget;
|
import com.mojang.blaze3d.pipeline.RenderTarget;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
@@ -63,44 +64,42 @@ public class ShapesRenderer
|
|||||||
private final Map<ResourceKey<Level>, Long2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> labels;
|
private final Map<ResourceKey<Level>, Long2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> labels;
|
||||||
private final Minecraft client;
|
private final Minecraft client;
|
||||||
|
|
||||||
private final Map<String, BiFunction<Minecraft, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> renderedShapes
|
private final Map<String, BiFunction<Minecraft, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> renderedShapes = ImmutableMap.<String, BiFunction<Minecraft, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>>>builder()
|
||||||
= new HashMap<>()
|
.put("line", RenderedLine::new)
|
||||||
{{
|
.put("box", RenderedBox::new)
|
||||||
put("line", RenderedLine::new);
|
.put("sphere", RenderedSphere::new)
|
||||||
put("box", RenderedBox::new);
|
.put("cylinder", RenderedCylinder::new)
|
||||||
put("sphere", RenderedSphere::new);
|
.put("label", RenderedText::new)
|
||||||
put("cylinder", RenderedCylinder::new);
|
.put("polygon", RenderedPolyface::new)
|
||||||
put("label", RenderedText::new);
|
.put("block", (c, s) -> new RenderedSprite(c, s, false))
|
||||||
put("polygon", RenderedPolyface::new);
|
.put("item", (c, s) -> new RenderedSprite(c, s, true))
|
||||||
put("block", (c, s) -> new RenderedSprite(c, s, false));
|
.build();
|
||||||
put("item", (c, s) -> new RenderedSprite(c, s, true));
|
|
||||||
}};
|
|
||||||
|
|
||||||
public static void rotatePoseStackByShapeDirection(PoseStack poseStack, ShapeDirection shapeDirection, Camera camera, Vec3 objectPos)
|
public static void rotatePoseStackByShapeDirection(PoseStack poseStack, ShapeDirection shapeDirection, Camera camera, Vec3 objectPos)
|
||||||
{
|
{
|
||||||
switch (shapeDirection)
|
switch (shapeDirection)
|
||||||
{
|
{
|
||||||
case NORTH -> {}
|
case NORTH -> {}
|
||||||
case SOUTH -> poseStack.mulPose(Axis.YP.rotationDegrees(180));
|
case SOUTH -> poseStack.rotate(Axis.YP.rotationDegrees(180));
|
||||||
case EAST -> poseStack.mulPose(Axis.YP.rotationDegrees(270));
|
case EAST -> poseStack.rotate(Axis.YP.rotationDegrees(270));
|
||||||
case WEST -> poseStack.mulPose(Axis.YP.rotationDegrees(90));
|
case WEST -> poseStack.rotate(Axis.YP.rotationDegrees(90));
|
||||||
case UP -> poseStack.mulPose(Axis.XP.rotationDegrees(90));
|
case UP -> poseStack.rotate(Axis.XP.rotationDegrees(90));
|
||||||
case DOWN -> poseStack.mulPose(Axis.XP.rotationDegrees(-90));
|
case DOWN -> poseStack.rotate(Axis.XP.rotationDegrees(-90));
|
||||||
case CAMERA -> poseStack.mulPose(camera.rotation());
|
case CAMERA -> poseStack.rotate(camera.rotation());
|
||||||
case PLAYER -> {
|
case PLAYER -> {
|
||||||
Vec3 vector = objectPos.subtract(camera.position());
|
Vec3 vector = objectPos.subtract(camera.position());
|
||||||
double x = vector.x;
|
double x = vector.x;
|
||||||
double y = vector.y;
|
double y = vector.y;
|
||||||
double z = vector.z;
|
double z = vector.z;
|
||||||
double d = Math.sqrt(x * x + z * z);
|
double d = Math.sqrt(x * x + z * z);
|
||||||
float rotX = (float) (Math.atan2(x, z));
|
float rotX = (float) Math.atan2(x, z);
|
||||||
float rotY = (float) (Math.atan2(y, d));
|
float rotY = (float) Math.atan2(y, d);
|
||||||
|
|
||||||
// that should work somehow but it doesn't for some reason
|
// that should work somehow but it doesn't for some reason
|
||||||
//matrices.mulPose(new Quaternion( -rotY, rotX, 0, false));
|
//matrices.mulPose(new Quaternion( -rotY, rotX, 0, false));
|
||||||
|
|
||||||
poseStack.mulPose(Axis.YP.rotation(rotX));
|
poseStack.rotate(Axis.YP.rotation(rotX));
|
||||||
poseStack.mulPose(Axis.XP.rotation(-rotY));
|
poseStack.rotate(Axis.XP.rotation(-rotY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,7 +238,7 @@ public class ShapesRenderer
|
|||||||
shapeFactory = renderedShapes.get(tag.getString("shape").orElseThrow());
|
shapeFactory = renderedShapes.get(tag.getString("shape").orElseThrow());
|
||||||
if (shapeFactory == null)
|
if (shapeFactory == null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info("Unrecognized shape: " + tag.getString("shape"));
|
CarpetScriptServer.LOG.info("Unrecognized shape: {}", tag.getString("shape"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -373,21 +372,21 @@ public class ShapesRenderer
|
|||||||
matrices.translate(0.5, 0.5, 0.5);
|
matrices.translate(0.5, 0.5, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
matrices.mulPose(camera1.rotation().conjugate(new Quaternionf()));
|
matrices.rotate(camera1.rotation().conjugate(new Quaternionf()));
|
||||||
|
|
||||||
matrices.translate(v1.x - cx, v1.y - cy, v1.z - cz);
|
matrices.translate(v1.x - cx, v1.y - cy, v1.z - cz);
|
||||||
rotatePoseStackByShapeDirection(matrices, shape.facing, camera1, isitem ? v1 : v1.add(0.5, 0.5, 0.5));
|
rotatePoseStackByShapeDirection(matrices, shape.facing, camera1, isitem ? v1 : v1.add(0.5, 0.5, 0.5));
|
||||||
if (shape.tilt != 0.0f)
|
if (shape.tilt != 0.0f)
|
||||||
{
|
{
|
||||||
matrices.mulPose(Axis.ZP.rotationDegrees(-shape.tilt));
|
matrices.rotate(Axis.ZP.rotationDegrees(-shape.tilt));
|
||||||
}
|
}
|
||||||
if (shape.lean != 0.0f)
|
if (shape.lean != 0.0f)
|
||||||
{
|
{
|
||||||
matrices.mulPose(Axis.XP.rotationDegrees(-shape.lean));
|
matrices.rotate(Axis.XP.rotationDegrees(-shape.lean));
|
||||||
}
|
}
|
||||||
if (shape.turn != 0.0f)
|
if (shape.turn != 0.0f)
|
||||||
{
|
{
|
||||||
matrices.mulPose(Axis.YP.rotationDegrees(shape.turn));
|
matrices.rotate(Axis.YP.rotationDegrees(shape.turn));
|
||||||
}
|
}
|
||||||
matrices.scale(shape.scaleX, shape.scaleY, shape.scaleZ);
|
matrices.scale(shape.scaleX, shape.scaleY, shape.scaleZ);
|
||||||
|
|
||||||
@@ -399,7 +398,7 @@ public class ShapesRenderer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// items seems to be flipped by default
|
// items seems to be flipped by default
|
||||||
matrices.mulPose(Axis.YP.rotationDegrees(180));
|
matrices.rotate(Axis.YP.rotationDegrees(180));
|
||||||
}
|
}
|
||||||
|
|
||||||
blockPos = BlockPos.containing(v1);
|
blockPos = BlockPos.containing(v1);
|
||||||
@@ -546,15 +545,15 @@ public class ShapesRenderer
|
|||||||
//RenderSystem.scalef(shape.size* 0.0025f, -shape.size*0.0025f, shape.size*0.0025f);
|
//RenderSystem.scalef(shape.size* 0.0025f, -shape.size*0.0025f, shape.size*0.0025f);
|
||||||
if (shape.tilt != 0.0f)
|
if (shape.tilt != 0.0f)
|
||||||
{
|
{
|
||||||
matrices.mulPose(Axis.ZP.rotationDegrees(shape.tilt));
|
matrices.rotate(Axis.ZP.rotationDegrees(shape.tilt));
|
||||||
}
|
}
|
||||||
if (shape.lean != 0.0f)
|
if (shape.lean != 0.0f)
|
||||||
{
|
{
|
||||||
matrices.mulPose(Axis.XP.rotationDegrees(shape.lean));
|
matrices.rotate(Axis.XP.rotationDegrees(shape.lean));
|
||||||
}
|
}
|
||||||
if (shape.turn != 0.0f)
|
if (shape.turn != 0.0f)
|
||||||
{
|
{
|
||||||
matrices.mulPose(Axis.YP.rotationDegrees(shape.turn));
|
matrices.rotate(Axis.YP.rotationDegrees(shape.turn));
|
||||||
}
|
}
|
||||||
matrices.translate(-10 * shape.indent, -10 * shape.height - 9, (-10 * renderEpsilon) - 10 * shape.raise);
|
matrices.translate(-10 * shape.indent, -10 * shape.height - 9, (-10 * renderEpsilon) - 10 * shape.raise);
|
||||||
//if (visibleThroughWalls) RenderSystem.disableDepthTest();
|
//if (visibleThroughWalls) RenderSystem.disableDepthTest();
|
||||||
@@ -564,11 +563,11 @@ public class ShapesRenderer
|
|||||||
float text_x = 0;
|
float text_x = 0;
|
||||||
if (shape.align == 0)
|
if (shape.align == 0)
|
||||||
{
|
{
|
||||||
text_x = (float) (-textRenderer.width(shape.value.getString())) / 2.0F;
|
text_x = (float) -textRenderer.width(shape.value.getString()) / 2.0F;
|
||||||
}
|
}
|
||||||
else if (shape.align == 1)
|
else if (shape.align == 1)
|
||||||
{
|
{
|
||||||
text_x = (float) (-textRenderer.width(shape.value.getString()));
|
text_x = (float) -textRenderer.width(shape.value.getString());
|
||||||
}
|
}
|
||||||
//try (ByteBufferBuilder bbb = new ByteBufferBuilder(RenderType.TRANSIENT_BUFFER_SIZE))
|
//try (ByteBufferBuilder bbb = new ByteBufferBuilder(RenderType.TRANSIENT_BUFFER_SIZE))
|
||||||
//{
|
//{
|
||||||
@@ -620,7 +619,7 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
catch (ClassCastException ignored)
|
catch (ClassCastException ignored)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.error("shape " + rshape.shape.getClass() + " cannot cast to a Label");
|
CarpetScriptServer.LOG.error("shape {} cannot cast to a Label", rshape.shape.getClass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -893,7 +892,7 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||||
drawSphereWireframe(primitives,
|
drawSphereWireframe(primitives,
|
||||||
(float) (vc.x), (float) (vc.y), (float) (vc.z),
|
(float) vc.x, (float) vc.y, (float) vc.z,
|
||||||
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
||||||
shape.argb, shape.lineWidth);
|
shape.argb, shape.lineWidth);
|
||||||
}
|
}
|
||||||
@@ -907,7 +906,7 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||||
drawSphereFaces(primitives,
|
drawSphereFaces(primitives,
|
||||||
(float) (vc.x ), (float) (vc.y ), (float) (vc.z ),
|
(float) vc.x, (float) vc.y, (float) vc.z,
|
||||||
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
||||||
shape.fargb);
|
shape.fargb);
|
||||||
}
|
}
|
||||||
@@ -1358,8 +1357,8 @@ public class ShapesRenderer
|
|||||||
|
|
||||||
private static int shuffleColor(int argb) {
|
private static int shuffleColor(int argb) {
|
||||||
int a = 0xff000000 & argb;
|
int a = 0xff000000 & argb;
|
||||||
argb = (new Random(argb)).nextInt();
|
argb = new Random(argb).nextInt();
|
||||||
argb = (a) | (0x00ffffff & argb);
|
argb = a | (0x00ffffff & argb);
|
||||||
return argb;
|
return argb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package carpet.script.utils;
|
package carpet.script.utils;
|
||||||
|
|
||||||
import carpet.fakes.CommandSourceStackInterface;
|
|
||||||
import carpet.script.external.Vanilla;
|
import carpet.script.external.Vanilla;
|
||||||
import net.minecraft.commands.CommandResultCallback;
|
import net.minecraft.commands.CommandResultCallback;
|
||||||
import net.minecraft.commands.CommandSigningContext;
|
import net.minecraft.commands.CommandSigningContext;
|
||||||
@@ -31,8 +30,7 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
private final Vec3 position;
|
private final Vec3 position;
|
||||||
private final ServerLevel world;
|
private final ServerLevel world;
|
||||||
private final PermissionSet level;
|
private final PermissionSet level;
|
||||||
private final String simpleName;
|
private final CommandSourceStack.NamesProvider namesProvider;
|
||||||
private final Component name;
|
|
||||||
private final MinecraftServer server;
|
private final MinecraftServer server;
|
||||||
// skipping silent since snooper is never silent
|
// skipping silent since snooper is never silent
|
||||||
private final Entity entity;
|
private final Entity entity;
|
||||||
@@ -49,15 +47,14 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
public SnoopyCommandSource(CommandSourceStack original, Component[] error, List<Component> chatOutput, OptionalLong[] returnValue)
|
public SnoopyCommandSource(CommandSourceStack original, Component[] error, List<Component> chatOutput, OptionalLong[] returnValue)
|
||||||
{
|
{
|
||||||
super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()),
|
super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()),
|
||||||
original.getTextName(), original.getDisplayName(), original.getServer(), original.getEntity()
|
original.getServer(), original.getEntity()
|
||||||
//,false ,(b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer())
|
//,false ,(b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer())
|
||||||
);
|
);
|
||||||
this.output = CommandSource.NULL;
|
this.output = CommandSource.NULL;
|
||||||
this.position = original.getPosition();
|
this.position = original.getPosition();
|
||||||
this.world = original.getLevel();
|
this.world = original.getLevel();
|
||||||
this.level = Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer());
|
this.level = Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer());
|
||||||
this.simpleName = original.getTextName();
|
this.namesProvider = original.namesProvider;
|
||||||
this.name = original.getDisplayName();
|
|
||||||
this.server = original.getServer();
|
this.server = original.getServer();
|
||||||
this.entity = original.getEntity();
|
this.entity = original.getEntity();
|
||||||
this.resultConsumer = (b, i) -> returnValue[0] = OptionalLong.of(i);
|
this.resultConsumer = (b, i) -> returnValue[0] = OptionalLong.of(i);
|
||||||
@@ -67,21 +64,20 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
this.chatOutput = chatOutput;
|
this.chatOutput = chatOutput;
|
||||||
this.signingContext = original.getSigningContext();
|
this.signingContext = original.getSigningContext();
|
||||||
this.taskChainer = TaskChainer.immediate(original.getServer());
|
this.taskChainer = TaskChainer.immediate(original.getServer());
|
||||||
((CommandSourceStackInterface) this).setupPrivates(false, (b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer()));
|
Vanilla.CommandSourceStack_setupPrivates(this, false, (b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SnoopyCommandSource(ServerPlayer player, Component[] error, List<Component> output, int [] result)
|
public SnoopyCommandSource(ServerPlayer player, Component[] error, List<Component> output, int [] result)
|
||||||
{
|
{
|
||||||
super(player.commandSource(), player.position(), player.getRotationVector(),
|
super(player.commandSource(), player.position(), player.getRotationVector(),
|
||||||
player.level() instanceof final ServerLevel serverLevel ? serverLevel : null,
|
player.level(),
|
||||||
player.level().getServer().getProfilePermissions(player.nameAndId()), player.getName().getString(), player.getDisplayName(),
|
player.level().getServer().getProfilePermissions(player.nameAndId()),
|
||||||
player.level().getServer(), player);
|
player.level().getServer(), player);
|
||||||
this.output = player.commandSource();
|
this.output = player.commandSource();
|
||||||
this.position = player.position();
|
this.position = player.position();
|
||||||
this.world = player.level() instanceof final ServerLevel serverLevel ? serverLevel : null;
|
this.world = player.level();
|
||||||
this.level = player.level().getServer().getProfilePermissions(player.nameAndId());
|
this.level = player.level().getServer().getProfilePermissions(player.nameAndId());
|
||||||
this.simpleName = player.getName().getString();
|
this.namesProvider = NamesProvider.FOR_ENTITY;
|
||||||
this.name = player.getDisplayName();
|
|
||||||
this.server = player.level().getServer();
|
this.server = player.level().getServer();
|
||||||
this.entity = player;
|
this.entity = player;
|
||||||
this.resultConsumer = (b, i) -> result[0] = i;
|
this.resultConsumer = (b, i) -> result[0] = i;
|
||||||
@@ -91,15 +87,15 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
this.chatOutput = output;
|
this.chatOutput = output;
|
||||||
this.signingContext = CommandSigningContext.ANONYMOUS;
|
this.signingContext = CommandSigningContext.ANONYMOUS;
|
||||||
this.taskChainer = TaskChainer.immediate(player.level().getServer());
|
this.taskChainer = TaskChainer.immediate(player.level().getServer());
|
||||||
((CommandSourceStackInterface) this).setupPrivates(false, (b, i) -> result[0] = i, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(player.level().getServer()));
|
Vanilla.CommandSourceStack_setupPrivates(this, false, (b, i) -> result[0] = i, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(player.level().getServer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SnoopyCommandSource(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, PermissionSet level, String simpleName, Component name, MinecraftServer server, @Nullable Entity entity, CommandResultCallback consumer, EntityAnchorArgument.Anchor entityAnchor, CommandSigningContext context, TaskChainer chainer,
|
private SnoopyCommandSource(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, PermissionSet level, CommandSourceStack.NamesProvider namesProvider, MinecraftServer server, @Nullable Entity entity, CommandResultCallback consumer, EntityAnchorArgument.Anchor entityAnchor, CommandSigningContext context, TaskChainer chainer,
|
||||||
Component[] error, List<Component> chatOutput
|
Component[] error, List<Component> chatOutput
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(output, pos, rot, world, level,
|
super(output, pos, rot, world, level,
|
||||||
simpleName, name, server, entity
|
server, entity
|
||||||
// , false, consumer, entityAnchor, context, chainer
|
// , false, consumer, entityAnchor, context, chainer
|
||||||
);
|
);
|
||||||
this.output = output;
|
this.output = output;
|
||||||
@@ -107,8 +103,7 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
this.rotation = rot;
|
this.rotation = rot;
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
this.simpleName = simpleName;
|
this.namesProvider = namesProvider;
|
||||||
this.name = name;
|
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.resultConsumer = consumer;
|
this.resultConsumer = consumer;
|
||||||
@@ -117,31 +112,31 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
this.chatOutput = chatOutput;
|
this.chatOutput = chatOutput;
|
||||||
this.signingContext = context;
|
this.signingContext = context;
|
||||||
this.taskChainer = chainer;
|
this.taskChainer = chainer;
|
||||||
((CommandSourceStackInterface) this).setupPrivates(false, consumer, entityAnchor, context, chainer);
|
Vanilla.CommandSourceStack_setupPrivates(this, false, consumer, entityAnchor, context, chainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withEntity(Entity entity)
|
public CommandSourceStack withEntity(Entity entity)
|
||||||
{
|
{
|
||||||
return new SnoopyCommandSource(output, position, rotation, world, level, entity.getName().getString(), entity.getDisplayName(), server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
return new SnoopyCommandSource(output, position, rotation, world, level, NamesProvider.FOR_ENTITY, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withPosition(Vec3 position)
|
public CommandSourceStack withPosition(Vec3 position)
|
||||||
{
|
{
|
||||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withRotation(Vec2 rotation)
|
public CommandSourceStack withRotation(Vec2 rotation)
|
||||||
{
|
{
|
||||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withCallback(CommandResultCallback consumer)
|
public CommandSourceStack withCallback(CommandResultCallback consumer)
|
||||||
{
|
{
|
||||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, consumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, consumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -170,13 +165,13 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withAnchor(EntityAnchorArgument.Anchor anchor)
|
public CommandSourceStack withAnchor(EntityAnchorArgument.Anchor anchor)
|
||||||
{
|
{
|
||||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, anchor, signingContext, taskChainer, error, chatOutput);
|
return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, anchor, signingContext, taskChainer, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withSigningContext(CommandSigningContext commandSigningContext, TaskChainer taskChainer)
|
public CommandSourceStack withSigningContext(CommandSigningContext commandSigningContext, TaskChainer taskChainer)
|
||||||
{
|
{
|
||||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, commandSigningContext, taskChainer, error, chatOutput);
|
return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, entityAnchor, commandSigningContext, taskChainer, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -184,7 +179,7 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
{
|
{
|
||||||
double d = DimensionType.getTeleportationScale(this.world.dimensionType(), world.dimensionType());
|
double d = DimensionType.getTeleportationScale(this.world.dimensionType(), world.dimensionType());
|
||||||
Vec3 position = new Vec3(this.position.x * d, this.position.y, this.position.z * d);
|
Vec3 position = new Vec3(this.position.x * d, this.position.y, this.position.z * d);
|
||||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
return new SnoopyCommandSource(output, position, rotation, world, level, namesProvider, server, entity, resultConsumer, entityAnchor, signingContext, taskChainer, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -195,7 +190,7 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
double e = position.y - vec3d.y;
|
double e = position.y - vec3d.y;
|
||||||
double f = position.z - vec3d.z;
|
double f = position.z - vec3d.z;
|
||||||
double g = Math.sqrt(d * d + f * f);
|
double g = Math.sqrt(d * d + f * f);
|
||||||
float h = Mth.wrapDegrees((float) (-(Mth.atan2(e, g) * 57.2957763671875D)));
|
float h = Mth.wrapDegrees((float) -(Mth.atan2(e, g) * 57.2957763671875D));
|
||||||
float i = Mth.wrapDegrees((float) (Mth.atan2(f, d) * 57.2957763671875D) - 90.0F);
|
float i = Mth.wrapDegrees((float) (Mth.atan2(f, d) * 57.2957763671875D) - 90.0F);
|
||||||
return this.withRotation(new Vec2(h, i));
|
return this.withRotation(new Vec2(h, i));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import java.util.function.Function;
|
|||||||
|
|
||||||
public class SystemInfo
|
public class SystemInfo
|
||||||
{
|
{
|
||||||
|
@SuppressWarnings("DoubleBraceInitialization")
|
||||||
private static final Map<String, Function<CarpetContext, Value>> options = new HashMap<>()
|
private static final Map<String, Function<CarpetContext, Value>> options = new HashMap<>()
|
||||||
{{
|
{{
|
||||||
put("app_name", c ->
|
put("app_name", c ->
|
||||||
@@ -43,7 +44,7 @@ public class SystemInfo
|
|||||||
return name == null ? Value.NULL : new StringValue(name);
|
return name == null ? Value.NULL : new StringValue(name);
|
||||||
});
|
});
|
||||||
put("app_list", c -> ListValue.wrap(((CarpetScriptHost) c.host).scriptServer().modules.keySet().stream().filter(Objects::nonNull).map(StringValue::new)));
|
put("app_list", c -> ListValue.wrap(((CarpetScriptHost) c.host).scriptServer().modules.keySet().stream().filter(Objects::nonNull).map(StringValue::new)));
|
||||||
put("app_scope", c -> StringValue.of((c.host).isPerUser() ? "player" : "global"));
|
put("app_scope", c -> StringValue.of(c.host.isPerUser() ? "player" : "global"));
|
||||||
put("app_players", c -> ListValue.wrap(c.host.getUserList().stream().map(StringValue::new)));
|
put("app_players", c -> ListValue.wrap(c.host.getUserList().stream().map(StringValue::new)));
|
||||||
|
|
||||||
put("world_name", c -> new StringValue(c.server().getWorldData().getLevelName()));
|
put("world_name", c -> new StringValue(c.server().getWorldData().getLevelName()));
|
||||||
@@ -133,7 +134,7 @@ public class SystemInfo
|
|||||||
long[] tickArray = c.server().getTickTimesNanos();
|
long[] tickArray = c.server().getTickTimesNanos();
|
||||||
for (int i = currentReportedTick + 100; i > currentReportedTick; i--)
|
for (int i = currentReportedTick + 100; i > currentReportedTick; i--)
|
||||||
{
|
{
|
||||||
ticks.add(new NumericValue((tickArray[i % 100]) / 1000000.0));
|
ticks.add(new NumericValue(tickArray[i % 100] / 1000000.0));
|
||||||
}
|
}
|
||||||
return ListValue.wrap(ticks);
|
return ListValue.wrap(ticks);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ public enum ShapeDirection
|
|||||||
CAMERA,
|
CAMERA,
|
||||||
PLAYER;
|
PLAYER;
|
||||||
|
|
||||||
@Nullable
|
public static @Nullable ShapeDirection fromString(String direction)
|
||||||
public static ShapeDirection fromString(String direction)
|
|
||||||
{
|
{
|
||||||
return switch (direction.toLowerCase(Locale.ROOT))
|
return switch (direction.toLowerCase(Locale.ROOT))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -298,6 +298,7 @@ public class EntityValue extends Value
|
|||||||
return ListValue.wrap(types.stream().map(et -> nameFromRegistryId(entityRegs.getKey(et))));
|
return ListValue.wrap(types.stream().map(et -> nameFromRegistryId(entityRegs.getKey(et))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DoubleBraceInitialization")
|
||||||
public static final Map<String, EntityClassDescriptor> byName = new HashMap<>()
|
public static final Map<String, EntityClassDescriptor> byName = new HashMap<>()
|
||||||
{{
|
{{
|
||||||
List<EntityType<?>> allTypes = BuiltInRegistries.ENTITY_TYPE.stream().toList();
|
List<EntityType<?>> allTypes = BuiltInRegistries.ENTITY_TYPE.stream().toList();
|
||||||
@@ -409,7 +410,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
public Value get(String what, @Nullable Value arg)
|
public Value get(String what, @Nullable Value arg)
|
||||||
{
|
{
|
||||||
if (!(featureAccessors.containsKey(what)))
|
if (!featureAccessors.containsKey(what))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown entity feature: " + what);
|
throw new InternalExpressionException("Unknown entity feature: " + what);
|
||||||
}
|
}
|
||||||
@@ -432,6 +433,7 @@ public class EntityValue extends Value
|
|||||||
"feet", EquipmentSlot.FEET
|
"feet", EquipmentSlot.FEET
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@SuppressWarnings("DoubleBraceInitialization")
|
||||||
private static final Map<String, BiFunction<Entity, Value, Value>> featureAccessors = new HashMap<String, BiFunction<Entity, Value, Value>>()
|
private static final Map<String, BiFunction<Entity, Value, Value>> featureAccessors = new HashMap<String, BiFunction<Entity, Value, Value>>()
|
||||||
{{
|
{{
|
||||||
//put("test", (e, a) -> a == null ? Value.NULL : new StringValue(a.getString()));
|
//put("test", (e, a) -> a == null ? Value.NULL : new StringValue(a.getString()));
|
||||||
@@ -834,16 +836,11 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return ValueConversions.of(hitres.getLocation());
|
return ValueConversions.of(hitres.getLocation());
|
||||||
}
|
}
|
||||||
switch (hitres.getType())
|
return switch (hitres.getType()) {
|
||||||
{
|
case MISS -> Value.NULL;
|
||||||
case MISS:
|
case BLOCK -> new BlockValue((ServerLevel) e.level(), ((BlockHitResult) hitres).getBlockPos());
|
||||||
return Value.NULL;
|
case ENTITY -> new EntityValue(((EntityHitResult) hitres).getEntity());
|
||||||
case BLOCK:
|
};
|
||||||
return new BlockValue((ServerLevel) e.level(), ((BlockHitResult) hitres).getBlockPos());
|
|
||||||
case ENTITY:
|
|
||||||
return new EntityValue(((EntityHitResult) hitres).getEntity());
|
|
||||||
}
|
|
||||||
return Value.NULL;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
put("attribute", (e, a) -> {
|
put("attribute", (e, a) -> {
|
||||||
@@ -888,7 +885,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
public void set(String what, @Nullable Value toWhat)
|
public void set(String what, @Nullable Value toWhat)
|
||||||
{
|
{
|
||||||
if (!(featureModifiers.containsKey(what)))
|
if (!featureModifiers.containsKey(what))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown entity action: " + what);
|
throw new InternalExpressionException("Unknown entity action: " + what);
|
||||||
}
|
}
|
||||||
@@ -947,10 +944,11 @@ public class EntityValue extends Value
|
|||||||
e.syncVelocity = true;
|
e.syncVelocity = true;
|
||||||
if (Math.abs(scale) > 10000)
|
if (Math.abs(scale) > 10000)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.warn("Moved entity " + e.getScoreboardName() + " " + e.getName() + " at " + e.position() + " extremely fast: " + e.getDeltaMovement());
|
CarpetScriptServer.LOG.warn("Moved entity {} {} at {} extremely fast: {}", e.getScoreboardName(), e.getName(), e.position(), e.getDeltaMovement());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DoubleBraceInitialization")
|
||||||
private static final Map<String, BiConsumer<Entity, Value>> featureModifiers = new HashMap<String, BiConsumer<Entity, Value>>()
|
private static final Map<String, BiConsumer<Entity, Value>> featureModifiers = new HashMap<String, BiConsumer<Entity, Value>>()
|
||||||
{{
|
{{
|
||||||
put("remove", (entity, value) -> entity.discard()); // using discard here - will see other options if valid
|
put("remove", (entity, value) -> entity.discard()); // using discard here - will see other options if valid
|
||||||
@@ -1547,8 +1545,8 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GameType toSet = v instanceof NumericValue ?
|
GameType toSet = v instanceof final NumericValue numericValue ?
|
||||||
GameType.byId(((NumericValue) v).getInt()) :
|
GameType.byId(numericValue.getInt()) :
|
||||||
GameType.byName(v.getString().toLowerCase(Locale.ROOT), null);
|
GameType.byName(v.getString().toLowerCase(Locale.ROOT), null);
|
||||||
if (toSet != null)
|
if (toSet != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -434,9 +434,9 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
{
|
{
|
||||||
if (ind.isNull())
|
if (ind.isNull())
|
||||||
{
|
{
|
||||||
if (extend && value instanceof AbstractListValue)
|
if (extend && value instanceof final AbstractListValue abstractListValue)
|
||||||
{
|
{
|
||||||
((AbstractListValue) value).iterator().forEachRemaining(items::add);
|
abstractListValue.iterator().forEachRemaining(items::add);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -446,11 +446,11 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int numitems = items.size();
|
int numitems = items.size();
|
||||||
if (!(ind instanceof NumericValue))
|
if (!(ind instanceof final NumericValue numericValue))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int index = (int) ((NumericValue) ind).getLong();
|
int index = (int) numericValue.getLong();
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{// only for values < 0
|
{// only for values < 0
|
||||||
index = normalizeIndex(index, numitems);
|
index = normalizeIndex(index, numitems);
|
||||||
@@ -469,9 +469,9 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
items.add(Value.NULL);
|
items.add(Value.NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extend && value instanceof AbstractListValue)
|
if (extend && value instanceof final AbstractListValue abstractListValue)
|
||||||
{
|
{
|
||||||
Iterable<Value> iterable = ((AbstractListValue) value)::iterator;
|
Iterable<Value> iterable = abstractListValue::iterator;
|
||||||
List<Value> appendix = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
List<Value> appendix = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||||
items.addAll(index, appendix);
|
items.addAll(index, appendix);
|
||||||
return true;
|
return true;
|
||||||
@@ -498,11 +498,11 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
@Override
|
@Override
|
||||||
public boolean delete(Value where)
|
public boolean delete(Value where)
|
||||||
{
|
{
|
||||||
if (!(where instanceof NumericValue) || items.isEmpty())
|
if (!(where instanceof final NumericValue numericValue) || items.isEmpty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
long index = ((NumericValue) where).getLong();
|
long index = numericValue.getLong();
|
||||||
items.remove(normalizeIndex(index, items.size()));
|
items.remove(normalizeIndex(index, items.size()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -592,8 +592,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
// only numbers / mixed types
|
// only numbers / mixed types
|
||||||
tags.forEach(cases.contains(TagTypeCompat.DBL)
|
tags.forEach(cases.contains(TagTypeCompat.DBL)
|
||||||
? (t -> tag.add(DoubleTag.valueOf(((NumericTag) t).doubleValue())))
|
? t -> tag.add(DoubleTag.valueOf(((NumericTag) t).doubleValue()))
|
||||||
: (t -> tag.add(LongTag.valueOf(((NumericTag) t).longValue()))));
|
: t -> tag.add(LongTag.valueOf(((NumericTag) t).longValue())));
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,14 +118,12 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
return StringValue.of(nameFromResource(id));
|
return StringValue.of(nameFromResource(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static @Nullable String nameFromResource(@Nullable Identifier id)
|
||||||
public static String nameFromResource(@Nullable Identifier id)
|
|
||||||
{
|
{
|
||||||
return id == null ? null : id.getNamespace().equals("minecraft") ? id.getPath() : id.toString();
|
return id == null ? null : id.getNamespace().equals("minecraft") ? id.getPath() : id.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static @Nullable NBTSerializableValue parseString(String nbtString)
|
||||||
public static NBTSerializableValue parseString(String nbtString)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -356,7 +354,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
{
|
{
|
||||||
return res.createItemStack(1);
|
return res.createItemStack(1);
|
||||||
}
|
}
|
||||||
ItemInput parser = (new ItemParser(regs)).parse(new StringReader(itemString));
|
ItemInput parser = new ItemParser(regs).parse(new StringReader(itemString));
|
||||||
res = new ItemInput(parser.item(), parser.components());
|
res = new ItemInput(parser.item(), parser.components());
|
||||||
|
|
||||||
itemCache.put(itemString, res);
|
itemCache.put(itemString, res);
|
||||||
@@ -477,11 +475,11 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
Tag tag = getTag();
|
Tag tag = getTag();
|
||||||
if (tag instanceof final CompoundTag ctag)
|
if (tag instanceof final CompoundTag ctag)
|
||||||
{
|
{
|
||||||
return !(ctag).isEmpty();
|
return !ctag.isEmpty();
|
||||||
}
|
}
|
||||||
if (tag instanceof final CollectionTag ltag)
|
if (tag instanceof final CollectionTag ltag)
|
||||||
{
|
{
|
||||||
return !(ltag).isEmpty();
|
return !ltag.isEmpty();
|
||||||
}
|
}
|
||||||
if (tag instanceof final NumericTag number)
|
if (tag instanceof final NumericTag number)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -88,13 +88,13 @@ public class ScreenValue extends Value
|
|||||||
screenHandlerFactories.put("crafting", CraftingMenu::new);
|
screenHandlerFactories.put("crafting", CraftingMenu::new);
|
||||||
screenHandlerFactories.put("enchantment", EnchantmentMenu::new);
|
screenHandlerFactories.put("enchantment", EnchantmentMenu::new);
|
||||||
screenHandlerFactories.put("furnace", FurnaceMenu::new);
|
screenHandlerFactories.put("furnace", FurnaceMenu::new);
|
||||||
screenHandlerFactories.put("generic_3x3", ((syncId, playerInventory) -> new ChestMenu(GENERIC_3x3, syncId, playerInventory, new SimpleContainer(9), 1)));
|
screenHandlerFactories.put("generic_3x3", (syncId, playerInventory) -> new ChestMenu(GENERIC_3x3, syncId, playerInventory, new SimpleContainer(9), 1));
|
||||||
screenHandlerFactories.put("generic_9x1", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x1, syncId, playerInventory, new SimpleContainer(9), 1)));
|
screenHandlerFactories.put("generic_9x1", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x1, syncId, playerInventory, new SimpleContainer(9), 1));
|
||||||
screenHandlerFactories.put("generic_9x2", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x2, syncId, playerInventory, new SimpleContainer(9 * 2), 2)));
|
screenHandlerFactories.put("generic_9x2", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x2, syncId, playerInventory, new SimpleContainer(9 * 2), 2));
|
||||||
screenHandlerFactories.put("generic_9x3", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x3, syncId, playerInventory, new SimpleContainer(9 * 3), 3)));
|
screenHandlerFactories.put("generic_9x3", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x3, syncId, playerInventory, new SimpleContainer(9 * 3), 3));
|
||||||
screenHandlerFactories.put("generic_9x4", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x4, syncId, playerInventory, new SimpleContainer(9 * 4), 4)));
|
screenHandlerFactories.put("generic_9x4", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x4, syncId, playerInventory, new SimpleContainer(9 * 4), 4));
|
||||||
screenHandlerFactories.put("generic_9x5", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x5, syncId, playerInventory, new SimpleContainer(9 * 5), 5)));
|
screenHandlerFactories.put("generic_9x5", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x5, syncId, playerInventory, new SimpleContainer(9 * 5), 5));
|
||||||
screenHandlerFactories.put("generic_9x6", ((syncId, playerInventory) -> new ChestMenu(GENERIC_9x6, syncId, playerInventory, new SimpleContainer(9 * 6), 6)));
|
screenHandlerFactories.put("generic_9x6", (syncId, playerInventory) -> new ChestMenu(GENERIC_9x6, syncId, playerInventory, new SimpleContainer(9 * 6), 6));
|
||||||
screenHandlerFactories.put("grindstone", GrindstoneMenu::new);
|
screenHandlerFactories.put("grindstone", GrindstoneMenu::new);
|
||||||
screenHandlerFactories.put("hopper", HopperMenu::new);
|
screenHandlerFactories.put("hopper", HopperMenu::new);
|
||||||
screenHandlerFactories.put("lectern", (syncId, playerInventory) -> new LecternMenu(syncId, new SimpleContainer(1), new SimpleContainerData(1)));
|
screenHandlerFactories.put("lectern", (syncId, playerInventory) -> new LecternMenu(syncId, new SimpleContainer(1), new SimpleContainerData(1)));
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import net.minecraft.server.MinecraftServer;
|
|||||||
import net.minecraft.server.level.ColumnPos;
|
import net.minecraft.server.level.ColumnPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
|
import net.minecraft.util.ARGB;
|
||||||
import net.minecraft.util.StringRepresentable;
|
import net.minecraft.util.StringRepresentable;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
@@ -60,6 +61,7 @@ import java.util.UUID;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import org.joml.Vector3fc;
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
public class ValueConversions
|
public class ValueConversions
|
||||||
@@ -140,11 +142,16 @@ public class ValueConversions
|
|||||||
return new NumericValue(value * 256 + 255);
|
return new NumericValue(value * 256 + 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Value ofRGB(Vector3fc value)
|
||||||
|
{
|
||||||
|
return new NumericValue(ARGB.colorFromVector3f(value));
|
||||||
|
}
|
||||||
|
|
||||||
public static Level dimFromValue(Value dimensionValue, MinecraftServer server)
|
public static Level dimFromValue(Value dimensionValue, MinecraftServer server)
|
||||||
{
|
{
|
||||||
if (dimensionValue instanceof EntityValue)
|
if (dimensionValue instanceof final EntityValue entityValue)
|
||||||
{
|
{
|
||||||
return ((EntityValue) dimensionValue).getEntity().level();
|
return entityValue.getEntity().level();
|
||||||
}
|
}
|
||||||
else if (dimensionValue instanceof BlockValue bv)
|
else if (dimensionValue instanceof BlockValue bv)
|
||||||
{
|
{
|
||||||
@@ -168,7 +175,7 @@ public class ValueConversions
|
|||||||
ResourceKey<Level> dim = null;
|
ResourceKey<Level> dim = null;
|
||||||
Identifier id = Identifier.parse(dimString);
|
Identifier id = Identifier.parse(dimString);
|
||||||
// not using RegistryKey.of since that one creates on check
|
// not using RegistryKey.of since that one creates on check
|
||||||
for (ResourceKey<Level> world : (server.levelKeys()))
|
for (ResourceKey<Level> world : server.levelKeys())
|
||||||
{
|
{
|
||||||
if (id.equals(world.identifier()))
|
if (id.equals(world.identifier()))
|
||||||
{
|
{
|
||||||
@@ -412,6 +419,7 @@ public class ValueConversions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DoubleBraceInitialization")
|
||||||
private static final Int2ObjectMap<SlotParam> slotIdsToSlotParams = new Int2ObjectOpenHashMap<>()
|
private static final Int2ObjectMap<SlotParam> slotIdsToSlotParams = new Int2ObjectOpenHashMap<>()
|
||||||
{{
|
{{
|
||||||
int n;
|
int n;
|
||||||
|
|||||||
@@ -257,10 +257,10 @@ public class Messenger
|
|||||||
MutableComponent previousComponent = null;
|
MutableComponent previousComponent = null;
|
||||||
for (Object o: fields)
|
for (Object o: fields)
|
||||||
{
|
{
|
||||||
if (o instanceof MutableComponent)
|
if (o instanceof final MutableComponent mutableComponent)
|
||||||
{
|
{
|
||||||
message.append((MutableComponent)o);
|
message.append(mutableComponent);
|
||||||
previousComponent = (MutableComponent)o;
|
previousComponent = mutableComponent;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String txt = o.toString();
|
String txt = o.toString();
|
||||||
@@ -300,7 +300,7 @@ public class Messenger
|
|||||||
public static void print_server_message(MinecraftServer server, String message)
|
public static void print_server_message(MinecraftServer server, String message)
|
||||||
{
|
{
|
||||||
if (server == null)
|
if (server == null)
|
||||||
LOG.error("Message not delivered: "+message);
|
LOG.error("Message not delivered: {}", message);
|
||||||
server.sendSystemMessage(Component.literal(message));
|
server.sendSystemMessage(Component.literal(message));
|
||||||
Component txt = c("gi "+message);
|
Component txt = c("gi "+message);
|
||||||
for (ServerPlayer entityplayer : server.getPlayerList().getPlayers())
|
for (ServerPlayer entityplayer : server.getPlayerList().getPlayers())
|
||||||
@@ -311,7 +311,7 @@ public class Messenger
|
|||||||
public static void print_server_message(MinecraftServer server, Component message)
|
public static void print_server_message(MinecraftServer server, Component message)
|
||||||
{
|
{
|
||||||
if (server == null)
|
if (server == null)
|
||||||
LOG.error("Message not delivered: "+message.getString());
|
LOG.error("Message not delivered: {}", message.getString());
|
||||||
server.sendSystemMessage(message);
|
server.sendSystemMessage(message);
|
||||||
for (ServerPlayer entityplayer : server.getPlayerList().getPlayers())
|
for (ServerPlayer entityplayer : server.getPlayerList().getPlayers())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ accessible method net/minecraft/world/level/border/WorldBorder getListeners ()Lj
|
|||||||
accessible method net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator calculateTargetStrength (Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)I
|
accessible method net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator calculateTargetStrength (Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)I
|
||||||
accessible field net/minecraft/world/level/block/state/BlockBehaviour UPDATE_SHAPE_ORDER [Lnet/minecraft/core/Direction;
|
accessible field net/minecraft/world/level/block/state/BlockBehaviour UPDATE_SHAPE_ORDER [Lnet/minecraft/core/Direction;
|
||||||
accessible field net/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher blockModelResolver Lnet/minecraft/client/renderer/block/BlockModelResolver;
|
accessible field net/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher blockModelResolver Lnet/minecraft/client/renderer/block/BlockModelResolver;
|
||||||
|
accessible field net/minecraft/commands/CommandSourceStack namesProvider Lnet/minecraft/commands/CommandSourceStack$NamesProvider;
|
||||||
@@ -153,7 +153,6 @@
|
|||||||
"BlockPredicate_scarpetMixin",
|
"BlockPredicate_scarpetMixin",
|
||||||
"TagPredicate_scarpetMixin",
|
"TagPredicate_scarpetMixin",
|
||||||
"HorseBaseEntity_scarpetMixin",
|
"HorseBaseEntity_scarpetMixin",
|
||||||
"RandomState_ScarpetMixin",
|
|
||||||
"Biome_scarpetMixin",
|
"Biome_scarpetMixin",
|
||||||
"PortalProcessor_scarpetMixin",
|
"PortalProcessor_scarpetMixin",
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@
|
|||||||
"accessWidener" : "carpet.accesswidener",
|
"accessWidener" : "carpet.accesswidener",
|
||||||
|
|
||||||
"depends": {
|
"depends": {
|
||||||
"minecraft": ">26.2",
|
"minecraft": ">=26.3",
|
||||||
"fabricloader": ">=0.19.3",
|
"fabricloader": ">=0.19.5",
|
||||||
"java": ">=25"
|
"java": ">=25"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user