Merge branch '1.16' of https://github.com/gnembon/fabric-carpet into 1.16
This commit is contained in:
commit
18ecc4ec4f
11 files changed
+203
-50
No files matched your search
+19
-7
@@ -689,15 +689,22 @@ number('3bar') => null
|
||||
number('2')+number('2') => 4
|
||||
</pre>
|
||||
|
||||
### `str(expr, params? ... ), str(expr, param_list)`
|
||||
### `str(expr)`,`str(expr, params? ... )`, `str(expr, param_list)`
|
||||
|
||||
Returns a formatted string representing expression. Accepts formatting style accepted by `String.format`.
|
||||
Supported types (with `"%?"` syntax):
|
||||
If called with one argument, returns string representation of such value.
|
||||
|
||||
Otherwise, returns a formatted string representing the expression. Arguments for formatting can either be provided as
|
||||
each consecutive parameter, or as a list which then would be the only extra parameter. To format one list argument
|
||||
, you can use `str(list)`, or `str('foo %s', l(list))`.
|
||||
|
||||
Accepts formatting style accepted by `String.format`.
|
||||
Supported types (with `"%<?>"` syntax):
|
||||
|
||||
* `d`, `o`, `x`: integers, octal, hex
|
||||
* `a`, `e`, `f`, `g`: floats
|
||||
* `b`: booleans
|
||||
* `s`: strings
|
||||
* `%%`: '%' character
|
||||
|
||||
<pre>
|
||||
str(null) => null
|
||||
@@ -2069,13 +2076,17 @@ Returns spawn potential at a location (1.16+ only)
|
||||
Checks wordgen eligibility for a structure in a given chunk. If no structure is given, or `null`, then it will check
|
||||
for all structures. If bounding box of the structures is also requested, it will compute size of potential
|
||||
structures. This function, unlike other in the `structure*` category is not using world data nor accesses chunks
|
||||
making it preferred for scoping ungenerated terrain.
|
||||
making it preferred for scoping ungenerated terrain, but it takes some compute money to calculate the structure.
|
||||
|
||||
Unlike `'structure'` this will return a tentative structure location. Random factors in world generation may prevent
|
||||
actual structure from forming.
|
||||
|
||||
If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or
|
||||
a pair of coordinates indicating bounding box of the structure.
|
||||
a map with two values: `'box'` for a pair of coordinates indicating bounding box of the structure, and `'pieces'` for
|
||||
list of elements of the structure (as a tuple), with its name, direction, and box coordinates of the piece.
|
||||
|
||||
If structure is not specified, it will return a set of structure names that are eligible, or a map with structures
|
||||
as keys, and pair of bounding box coordinates as values. An empty set or an empty map would indicate that nothing
|
||||
as keys, and same type of map values as with a single structure call. An empty set or an empty map would indicate that nothing
|
||||
should be generated there.
|
||||
|
||||
|
||||
@@ -2085,7 +2096,8 @@ Returns structure information for a given block position. Note that structure in
|
||||
blocks from the same chunk. `structures` function can be called with a block, or a block and a structure name. In
|
||||
the first case it returns a map of structures at a given position, keyed by structure name, with values indicating
|
||||
the bounding box of the structure - a pair of two 3-value coords (see examples). When called with an extra structure
|
||||
name, returns list of components for that structure, with their name, direction and two sets of coordinates
|
||||
name, returns a map with two values, `'box'` for bounding box of the structure, and `'pieces'` for a list of
|
||||
components for that structure, with their name, direction and two sets of coordinates
|
||||
indicating the bounding box of the structure piece.
|
||||
|
||||
### `structure_references(pos), structure_references(pos, structure_name)`
|
||||
|
||||
@@ -532,13 +532,17 @@ Returns spawn potential at a location (1.16+ only)
|
||||
Checks wordgen eligibility for a structure in a given chunk. If no structure is given, or `null`, then it will check
|
||||
for all structures. If bounding box of the structures is also requested, it will compute size of potential
|
||||
structures. This function, unlike other in the `structure*` category is not using world data nor accesses chunks
|
||||
making it preferred for scoping ungenerated terrain.
|
||||
making it preferred for scoping ungenerated terrain, but it takes some compute money to calculate the structure.
|
||||
|
||||
Unlike `'structure'` this will return a tentative structure location. Random factors in world generation may prevent
|
||||
actual structure from forming.
|
||||
|
||||
If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or
|
||||
a pair of coordinates indicating bounding box of the structure.
|
||||
a map with two values: `'box'` for a pair of coordinates indicating bounding box of the structure, and `'pieces'` for
|
||||
list of elements of the structure (as a tuple), with its name, direction, and box coordinates of the piece.
|
||||
|
||||
If structure is not specified, it will return a set of structure names that are eligible, or a map with structures
|
||||
as keys, and pair of bounding box coordinates as values. An empty set or an empty map would indicate that nothing
|
||||
as keys, and same type of map values as with a single structure call. An empty set or an empty map would indicate that nothing
|
||||
should be generated there.
|
||||
|
||||
|
||||
@@ -548,7 +552,8 @@ Returns structure information for a given block position. Note that structure in
|
||||
blocks from the same chunk. `structures` function can be called with a block, or a block and a structure name. In
|
||||
the first case it returns a map of structures at a given position, keyed by structure name, with values indicating
|
||||
the bounding box of the structure - a pair of two 3-value coords (see examples). When called with an extra structure
|
||||
name, returns list of components for that structure, with their name, direction and two sets of coordinates
|
||||
name, returns a map with two values, `'box'` for bounding box of the structure, and `'pieces'` for a list of
|
||||
components for that structure, with their name, direction and two sets of coordinates
|
||||
indicating the bounding box of the structure piece.
|
||||
|
||||
### `structure_references(pos), structure_references(pos, structure_name)`
|
||||
|
||||
@@ -583,4 +583,10 @@ public class CarpetSettings
|
||||
category = CLIENT
|
||||
)
|
||||
public static boolean fogOff = false;
|
||||
|
||||
@Rule(
|
||||
desc = "Creative No Clip",
|
||||
category = {CREATIVE, CLIENT}
|
||||
)
|
||||
public static boolean creativeNoClip = false;
|
||||
}
|
||||
@@ -154,10 +154,9 @@ public class FeatureGenerator
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BlockBox DEFAULT_BOX = new BlockBox(0,0,0,1,1,1);
|
||||
public static BlockBox shouldStructureStartAt(ServerWorld world, BlockPos pos, StructureFeature<?> structure, boolean computeBox)
|
||||
public static StructureStart shouldStructureStartAt(ServerWorld world, BlockPos pos, StructureFeature<?> structure, boolean computeBox)
|
||||
{
|
||||
ChunkGenerator generator = world.getChunkManager().getChunkGenerator();
|
||||
ChunkGenerator<?> generator = world.getChunkManager().getChunkGenerator();
|
||||
if (!generator.getBiomeSource().hasStructureFeature(structure))
|
||||
return null;
|
||||
BiomeAccess biomeAccess = world.getBiomeAccess().withSource(generator.getBiomeSource());
|
||||
@@ -166,12 +165,12 @@ public class FeatureGenerator
|
||||
Biome biome = biomeAccess.getBiome(new BlockPos(chunkPos.getStartX() + 9, 0, chunkPos.getStartZ() + 9));
|
||||
if (structure.method_27217(biomeAccess, generator, chunkRandom, chunkPos.x, chunkPos.z, biome)) // should start at
|
||||
{
|
||||
if (!computeBox) return DEFAULT_BOX;
|
||||
if (!computeBox) return StructureStart.DEFAULT;
|
||||
StructureManager manager = world.getStructureManager();
|
||||
StructureStart structureStart3 = structure.getStructureStartFactory().create(structure, chunkPos.x, chunkPos.z, BlockBox.empty(), 0, generator.getSeed());
|
||||
structureStart3.init(generator, manager, chunkPos.x, chunkPos.z, biome);
|
||||
if (!structureStart3.hasChildren()) return null;
|
||||
return structureStart3.getBoundingBox();
|
||||
return structureStart3;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -196,9 +195,9 @@ public class FeatureGenerator
|
||||
structureToFeature.put(Feature.MINESHAFT.getName(), Arrays.asList("mineshaft", "mineshaft_mesa"));
|
||||
structureToFeature.put(Feature.IGLOO.getName(), Collections.singletonList("igloo"));
|
||||
structureToFeature.put(Feature.NETHER_BRIDGE.getName(), Collections.singletonList("fortress"));
|
||||
structureToFeature.put("Nether_Fossil", Collections.singletonList("nether_fossil"));
|
||||
structureToFeature.put("Bastion_Remnant", Arrays.asList("bastion_remnant", "bastion_remnant_housing", "bastion_remnant_stable", "bastion_remnant_treasure", "bastion_remnant_bridge"));
|
||||
structureToFeature.put("Ruined_Portal", Collections.singletonList("ruined_portal"));
|
||||
structureToFeature.put(Feature.NETHER_FOSSIL.getName(), Collections.singletonList("nether_fossil"));
|
||||
structureToFeature.put(Feature.BASTION_REMNANT.getName(), Arrays.asList("bastion_remnant", "bastion_remnant_housing", "bastion_remnant_stable", "bastion_remnant_treasure", "bastion_remnant_bridge"));
|
||||
structureToFeature.put(Feature.RUINED_PORTAL.getName(), Collections.singletonList("ruined_portal"));
|
||||
|
||||
structureToFeature.forEach((key, value) -> value.forEach(el -> featureToStructure.put(el, key)));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.block.entity.PistonBlockEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(PistonBlockEntity.class)
|
||||
public class PistonBlockEntity_creativeNoClipMixin
|
||||
{
|
||||
@Inject(method = "method_23672", at = @At("HEAD"), cancellable = true)
|
||||
private static void dontPushSpectators(Direction direction, Entity entity, double d, Direction direction2, CallbackInfo ci)
|
||||
{
|
||||
if (CarpetSettings.creativeNoClip && entity instanceof PlayerEntity && (((PlayerEntity) entity).isCreative()) && ((PlayerEntity) entity).abilities.flying) ci.cancel();
|
||||
}
|
||||
|
||||
@Redirect(method = "pushEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setVelocity(DDD)V"))
|
||||
private void ignoreAccel(Entity entity, double x, double y, double z)
|
||||
{
|
||||
if (CarpetSettings.creativeNoClip && entity instanceof PlayerEntity && (((PlayerEntity) entity).isCreative()) && ((PlayerEntity) entity).abilities.flying) return;
|
||||
entity.setVelocity(x,y,z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.MovementType;
|
||||
import net.minecraft.entity.player.PlayerAbilities;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(PlayerEntity.class)
|
||||
public abstract class PlayerEntity_creativeNoClipMixin extends LivingEntity
|
||||
{
|
||||
@Shadow public abstract boolean isCreative();
|
||||
|
||||
@Shadow @Final public PlayerAbilities abilities;
|
||||
|
||||
protected PlayerEntity_creativeNoClipMixin(EntityType<? extends LivingEntity> type, World world)
|
||||
{
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
@Redirect(method = "tick", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/entity/player/PlayerEntity;isSpectator()Z")
|
||||
)
|
||||
private boolean canClipTroughWorld(PlayerEntity playerEntity)
|
||||
{
|
||||
return playerEntity.isSpectator() || (CarpetSettings.creativeNoClip && playerEntity.isCreative() && playerEntity.abilities.flying);
|
||||
|
||||
}
|
||||
|
||||
@Redirect(method = "tickMovement", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/entity/player/PlayerEntity;isSpectator()Z")
|
||||
)
|
||||
private boolean collidesWithEntities(PlayerEntity playerEntity)
|
||||
{
|
||||
return playerEntity.isSpectator() || (CarpetSettings.creativeNoClip && playerEntity.isCreative() && playerEntity.abilities.flying);
|
||||
}
|
||||
|
||||
@Redirect(method = "updateSize", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/entity/player/PlayerEntity;isSpectator()Z")
|
||||
)
|
||||
private boolean spectatorsDontPose(PlayerEntity playerEntity)
|
||||
{
|
||||
return playerEntity.isSpectator() || (CarpetSettings.creativeNoClip && playerEntity.isCreative() && playerEntity.abilities.flying);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(WorldRenderer.class)
|
||||
public class WorldRenderer_creativeNoClipMixin
|
||||
{
|
||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isSpectator()Z"))
|
||||
private boolean canSeeWorld(ClientPlayerEntity clientPlayerEntity)
|
||||
{
|
||||
return clientPlayerEntity.isSpectator() || (CarpetSettings.creativeNoClip && clientPlayerEntity.isCreative());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -398,6 +398,32 @@ public class CarpetExpression
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Value structureToValue(StructureStart structure)
|
||||
{
|
||||
if (structure == null || structure == StructureStart.DEFAULT) return Value.NULL;
|
||||
List<Value> pieces = new ArrayList<>();
|
||||
for (StructurePiece piece : structure.getChildren())
|
||||
{
|
||||
BlockBox box = piece.getBoundingBox();
|
||||
pieces.add(ListValue.of(
|
||||
new StringValue( NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_PIECE.getId(piece.getType()))),
|
||||
(piece.getFacing()== null)?Value.NULL: new StringValue(piece.getFacing().getName()),
|
||||
ListValue.fromTriple(box.minX, box.minY, box.minZ),
|
||||
ListValue.fromTriple(box.maxX, box.maxY, box.maxZ)
|
||||
));
|
||||
};
|
||||
BlockBox boundingBox = structure.getBoundingBox();
|
||||
Map<Value, Value> ret = new HashMap<>();
|
||||
ret.put(new StringValue("box"), ListValue.of(
|
||||
ListValue.fromTriple(boundingBox.minX, boundingBox.minY, boundingBox.minZ),
|
||||
ListValue.fromTriple(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ)
|
||||
));
|
||||
ret.put(new StringValue("pieces"), ListValue.wrap(pieces));
|
||||
return MapValue.wrap(ret);
|
||||
}
|
||||
|
||||
private void API_BlockManipulation()
|
||||
{
|
||||
this.expr.addLazyFunction("block", -1, (c, t, lv) ->
|
||||
@@ -1148,25 +1174,20 @@ public class CarpetExpression
|
||||
}
|
||||
if (structure != null)
|
||||
{
|
||||
BlockBox box = FeatureGenerator.shouldStructureStartAt(world, pos, structure, needSize);
|
||||
if (box == null) return LazyValue.NULL;
|
||||
StructureStart start = FeatureGenerator.shouldStructureStartAt(world, pos, structure, needSize);
|
||||
if (start == null) return LazyValue.NULL;
|
||||
if (!needSize) return LazyValue.TRUE;
|
||||
Value ret = ListValue.of(
|
||||
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)),
|
||||
ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ))
|
||||
);
|
||||
Value ret = structureToValue(start);
|
||||
return (_c, _t) -> ret;
|
||||
}
|
||||
Map<Value, Value> ret = new HashMap<>();
|
||||
for(StructureFeature<?> str : Feature.STRUCTURES.values())
|
||||
{
|
||||
BlockBox box = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize);
|
||||
if (box == null) continue;
|
||||
StructureStart start = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize);
|
||||
if (start == null) continue;
|
||||
|
||||
Value key = new StringValue(FeatureGenerator.structureToFeature.get(str.getName()).get(0));
|
||||
ret.put(key, (!needSize)?Value.NULL:ListValue.of(
|
||||
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)),
|
||||
ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ))
|
||||
));
|
||||
ret.put(key, (!needSize)?Value.NULL:structureToValue(start));
|
||||
}
|
||||
Value retMap = MapValue.wrap(ret);
|
||||
return (_c, _t) -> retMap;
|
||||
@@ -1188,28 +1209,17 @@ public class CarpetExpression
|
||||
if (start == StructureStart.DEFAULT)
|
||||
continue;
|
||||
BlockBox box = start.getBoundingBox();
|
||||
ListValue coord1 = ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ));
|
||||
ListValue coord2 = ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ));
|
||||
structureList.put(new StringValue(FeatureGenerator.structureToFeature.get(entry.getKey()).get(0)), ListValue.of(coord1, coord2));
|
||||
structureList.put(
|
||||
new StringValue(FeatureGenerator.structureToFeature.get(entry.getKey()).get(0)),
|
||||
ListValue.of(ListValue.fromTriple(box.minX, box.minY, box.minZ), ListValue.fromTriple(box.maxX, box.maxY, box.maxZ))
|
||||
);
|
||||
}
|
||||
Value ret = MapValue.wrap(structureList);
|
||||
return (_c, _t) -> ret;
|
||||
}
|
||||
String structureName = lv.get(locator.offset).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||
StructureStart start = structures.get(FeatureGenerator.featureToStructure.get(structureName));
|
||||
if (start == null || start == StructureStart.DEFAULT) return LazyValue.NULL;
|
||||
List<Value> pieces = new ArrayList<>();
|
||||
for (StructurePiece piece : start.getChildren())
|
||||
{
|
||||
BlockBox box = piece.getBoundingBox();
|
||||
pieces.add(ListValue.of(
|
||||
new StringValue( NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_PIECE.getId(piece.getType()))),
|
||||
(piece.getFacing()== null)?Value.NULL: new StringValue(piece.getFacing().getName()),
|
||||
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)),
|
||||
ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ))
|
||||
));
|
||||
}
|
||||
Value ret = ListValue.wrap(pieces);
|
||||
Value ret = structureToValue(start);
|
||||
return (_c, _t) -> ret;
|
||||
});
|
||||
|
||||
|
||||
@@ -75,6 +75,18 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
);
|
||||
}
|
||||
|
||||
public static Value fromTriple(double a, double b, double c)
|
||||
{
|
||||
return ListValue.of(new NumericValue(a), new NumericValue(b), new NumericValue(c));
|
||||
}
|
||||
|
||||
public static Value fromTriple(int a, int b, int c)
|
||||
{
|
||||
return fromTriple((double) a, b, c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static ListValue wrap(List<Value> list)
|
||||
{
|
||||
|
||||
@@ -93,7 +93,7 @@ __structure_renderer(player_name) ->
|
||||
for (starts, l(position, name) = _;
|
||||
structure_data = structures(position):name;
|
||||
if (!structure_data, continue()); // messed up references - shouldn't happen
|
||||
structure_pieces = structures(position, name);
|
||||
structure_pieces = structures(position, name):'pieces';
|
||||
if (!structure_pieces, continue()); // messed up references - shouldn't happen
|
||||
l(from, to) = structure_data;
|
||||
total_size = _euclidean(from, to);
|
||||
|
||||
@@ -157,7 +157,10 @@
|
||||
"PistonBlockEntity_movableTEMixin",
|
||||
"World_movableTEMixin",
|
||||
"WorldChunk_movableTEMixin",
|
||||
"PistonHandler_movableTEMixin"
|
||||
"PistonHandler_movableTEMixin",
|
||||
"PlayerEntity_creativeNoClipMixin",
|
||||
"PistonBlockEntity_creativeNoClipMixin"
|
||||
|
||||
],
|
||||
"client": [
|
||||
"RenderTickCounter_tickSpeedMixin",
|
||||
@@ -170,7 +173,9 @@
|
||||
"PistonBlockEntityRenderer_movableTEMixin",
|
||||
"ClientPlayNetworkHandler_smoothClientAnimationsMixin",
|
||||
"ClientPlayerEntity_clientCommandMixin",
|
||||
"WorldRenderer_fogOffMixin"
|
||||
"WorldRenderer_fogOffMixin",
|
||||
"WorldRenderer_creativeNoClipMixin"
|
||||
|
||||
],
|
||||
"server": [
|
||||
"MinecraftDedicatedServerMixin"
|
||||
|
||||
Reference in new issue
Block a user