Merge branch 'master' into 1.16
This commit is contained in:
commit
52aab4a6cb
4 files changed
+107
-30
No files matched your search
+25
-10
@@ -62,7 +62,7 @@ or an OVERLY complex example:
|
|||||||
or simply
|
or simply
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
/script run print('There is'+for(rect(x,9,z,8,8,8), _ == 'diamond_ore')+' diamond ore around you')
|
/script run print('There is '+for(rect(x,9,z,8,8,8), _ == 'diamond_ore')+' diamond ore around you')
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
It definitely pays to check what higher level `scarpet` functions have to offer.
|
It definitely pays to check what higher level `scarpet` functions have to offer.
|
||||||
@@ -112,16 +112,17 @@ Or rather:
|
|||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
if
|
if
|
||||||
(
|
( x<y+6,
|
||||||
x<y+6,
|
|
||||||
(
|
(
|
||||||
set(x,8+y,z,'air');
|
set(x,8+y,z,'air');
|
||||||
plop(x,top('surface',x,z),z,'birch')
|
plop(x,top('surface',x,z),z,'birch')
|
||||||
),
|
),
|
||||||
|
// else if
|
||||||
sin(query(player(),'yaw'))>0.5,
|
sin(query(player(),'yaw'))>0.5,
|
||||||
(
|
(
|
||||||
plop(0,0,0,'boulder')
|
plop(0,0,0,'boulder')
|
||||||
),
|
),
|
||||||
|
// else
|
||||||
particle('fire',x,y,z)
|
particle('fire',x,y,z)
|
||||||
)
|
)
|
||||||
</pre>
|
</pre>
|
||||||
@@ -134,8 +135,10 @@ have problems with them
|
|||||||
## Functions and scoping
|
## Functions and scoping
|
||||||
|
|
||||||
Users can define functions in the form `fun(args....) -> expression` and they are compiled and saved for further
|
Users can define functions in the form `fun(args....) -> expression` and they are compiled and saved for further
|
||||||
execution in this but also subsequent calls of /script command. Functions can also be assigned to variables,
|
execution in this, but also subsequent calls of /script command, added to events, etc. Functions can also be
|
||||||
passed as arguments, called with `call` function, but in most cases you would want to call them directly by
|
assigned to variables,
|
||||||
|
passed as arguments, called with `call('fun', args...)` function, but in most cases you would want to
|
||||||
|
call them directly by
|
||||||
name, in the form of `fun(args...)`. This means that once defined functions are saved with the world for
|
name, in the form of `fun(args...)`. This means that once defined functions are saved with the world for
|
||||||
further use. For variables, there are two types of them, global - which are shared anywhere in the code,
|
further use. For variables, there are two types of them, global - which are shared anywhere in the code,
|
||||||
and those are all which name starts with 'global_', and local variables which is everything else and those
|
and those are all which name starts with 'global_', and local variables which is everything else and those
|
||||||
@@ -690,10 +693,10 @@ number('2')+number('2') => 4
|
|||||||
Returns a formatted string representing expression. Accepts formatting style accepted by `String.format`.
|
Returns a formatted string representing expression. Accepts formatting style accepted by `String.format`.
|
||||||
Supported types (with `"%?"` syntax):
|
Supported types (with `"%?"` syntax):
|
||||||
|
|
||||||
* d, o, x: integers
|
* `d`, `o`, `x`: integers, octal, hex
|
||||||
* a, e, f, g: floats
|
* `a`, `e`, `f`, `g`: floats
|
||||||
* b: booleans
|
* `b`: booleans
|
||||||
* s: strings
|
* `s`: strings
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
str(null) => null
|
str(null) => null
|
||||||
@@ -720,7 +723,8 @@ the off-tick time in between ticks that didn't take 50ms. There are however bene
|
|||||||
like fine time control not relying on the tick clock, or running things independent on each other. You can still run
|
like fine time control not relying on the tick clock, or running things independent on each other. You can still run
|
||||||
your actions on tick-by-tick basis, either taking control of the execution using `game_tick()` API function
|
your actions on tick-by-tick basis, either taking control of the execution using `game_tick()` API function
|
||||||
(nasty solution), or scheduling tick using `schedule()` function (much nicer solution), but threading often gives
|
(nasty solution), or scheduling tick using `schedule()` function (much nicer solution), but threading often gives
|
||||||
the neatest solution to solve problems in parallel (see scarpet camera).
|
the neatest solution to solve problems in parallel
|
||||||
|
(see [scarpet camera](/src/main/resources/assets/carpet/scripts/camera.sc)).
|
||||||
|
|
||||||
Due to limitations with the game, there are some limits to the threading as well. You cannot for
|
Due to limitations with the game, there are some limits to the threading as well. You cannot for
|
||||||
instance `join_task()` at all from the main script and server thread, because any use of Minecraft specific
|
instance `join_task()` at all from the main script and server thread, because any use of Minecraft specific
|
||||||
@@ -2298,6 +2302,17 @@ Returns mob's attack target or null if none or not applicable.
|
|||||||
|
|
||||||
Returns creature's home position or null if none or not applicable.
|
Returns creature's home position or null if none or not applicable.
|
||||||
|
|
||||||
|
### `query(e, 'pose')`
|
||||||
|
|
||||||
|
Returns a pose of an entity, one of the following options
|
||||||
|
* `'standing'`
|
||||||
|
* `'fall_flying'`
|
||||||
|
* `'sleeping'`
|
||||||
|
* `'swimming'`
|
||||||
|
* `'spin_attack'`
|
||||||
|
* `'crouching'`
|
||||||
|
* `'dying'`
|
||||||
|
|
||||||
### `query(e,'sneaking')`
|
### `query(e,'sneaking')`
|
||||||
|
|
||||||
Boolean, true if entity is sneaking.
|
Boolean, true if entity is sneaking.
|
||||||
|
|||||||
@@ -218,6 +218,17 @@ Returns mob's attack target or null if none or not applicable.
|
|||||||
|
|
||||||
Returns creature's home position or null if none or not applicable.
|
Returns creature's home position or null if none or not applicable.
|
||||||
|
|
||||||
|
### `query(e, 'pose')`
|
||||||
|
|
||||||
|
Returns a pose of an entity, one of the following options
|
||||||
|
* `'standing'`
|
||||||
|
* `'fall_flying'`
|
||||||
|
* `'sleeping'`
|
||||||
|
* `'swimming'`
|
||||||
|
* `'spin_attack'`
|
||||||
|
* `'crouching'`
|
||||||
|
* `'dying'`
|
||||||
|
|
||||||
### `query(e,'sneaking')`
|
### `query(e,'sneaking')`
|
||||||
|
|
||||||
Boolean, true if entity is sneaking.
|
Boolean, true if entity is sneaking.
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import carpet.CarpetSettings;
|
|||||||
import carpet.fakes.WorldInterface;
|
import carpet.fakes.WorldInterface;
|
||||||
import carpet.utils.SpawnReporter;
|
import carpet.utils.SpawnReporter;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.FenceGateBlock;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityCategory;
|
import net.minecraft.entity.EntityCategory;
|
||||||
import net.minecraft.entity.EntityData;
|
import net.minecraft.entity.EntityData;
|
||||||
@@ -13,6 +15,7 @@ import net.minecraft.entity.mob.MobEntity;
|
|||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.tag.BlockTags;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Box;
|
import net.minecraft.util.math.Box;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
@@ -46,30 +49,78 @@ public class SpawnHelperMixin
|
|||||||
// various configurations, but solid and 'passable' blocks, like air, water grass, etc.
|
// various configurations, but solid and 'passable' blocks, like air, water grass, etc.
|
||||||
// checking if in the BB of the entity are only passable blocks is very cheap and covers most cases
|
// checking if in the BB of the entity are only passable blocks is very cheap and covers most cases
|
||||||
// in case something more complex happens - we default to full block collision check
|
// in case something more complex happens - we default to full block collision check
|
||||||
if (CarpetSettings.lagFreeSpawning)
|
if (!CarpetSettings.lagFreeSpawning)
|
||||||
{
|
{
|
||||||
BlockPos.Mutable blockpos = new BlockPos.Mutable();
|
return world.doesNotCollide(bb);
|
||||||
int minX = MathHelper.floor(bb.x1);
|
}
|
||||||
int maxX = MathHelper.ceil(bb.x2);
|
int minX = MathHelper.floor(bb.x1);
|
||||||
int minY = MathHelper.floor(bb.y1);
|
int minY = MathHelper.floor(bb.y1);
|
||||||
int maxY = MathHelper.ceil(bb.y2);
|
int minZ = MathHelper.floor(bb.z1);
|
||||||
int minZ = MathHelper.floor(bb.z1);
|
int maxY = MathHelper.ceil(bb.y2)-1;
|
||||||
int maxZ = MathHelper.ceil(bb.z2);
|
BlockPos.Mutable blockpos = new BlockPos.Mutable();
|
||||||
for (int y = minY; y < maxY; y++)
|
if (bb.getXLength() <= 1) // small mobs
|
||||||
for (int x = minX; x < maxX; x++)
|
{
|
||||||
for (int z = minZ; z < maxZ; z++)
|
for (int y=minY; y <= maxY; y++)
|
||||||
|
{
|
||||||
|
blockpos.set(minX,y,minZ);
|
||||||
|
VoxelShape box = world.getBlockState(blockpos).getCollisionShape(world, blockpos);
|
||||||
|
if (box != VoxelShapes.empty())
|
||||||
|
{
|
||||||
|
if (box == VoxelShapes.fullCube())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
blockpos.set(x, y, z);
|
|
||||||
VoxelShape box = world.getBlockState(blockpos).getCollisionShape(world, blockpos);
|
|
||||||
if ( box == VoxelShapes.empty())
|
|
||||||
continue;
|
|
||||||
if (Block.isShapeFullCube(box))
|
|
||||||
return false;
|
|
||||||
return world.doesNotCollide(bb);
|
return world.doesNotCollide(bb);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return world.doesNotCollide(bb);
|
// this code is only applied for mobs larger than 1 block in footprint
|
||||||
|
int maxX = MathHelper.ceil(bb.x2)-1;
|
||||||
|
int maxZ = MathHelper.ceil(bb.z2)-1;
|
||||||
|
for (int y = minY; y <= maxY; y++)
|
||||||
|
for (int x = minX; x <= maxX; x++)
|
||||||
|
for (int z = minZ; z <= maxZ; z++)
|
||||||
|
{
|
||||||
|
blockpos.set(x, y, z);
|
||||||
|
VoxelShape box = world.getBlockState(blockpos).getCollisionShape(world, blockpos);
|
||||||
|
if (box != VoxelShapes.empty())
|
||||||
|
{
|
||||||
|
if (box == VoxelShapes.fullCube())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return world.doesNotCollide(bb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int min_below = minY - 1;
|
||||||
|
// we need to check blocks below for extended hitbox and in that case call
|
||||||
|
// only applies to 'large mobs', slimes, spiders, magmacubes, ghasts, etc.
|
||||||
|
for (int x = minX; x <= maxX; x++)
|
||||||
|
{
|
||||||
|
for (int z = minZ; z <= maxZ; z++)
|
||||||
|
{
|
||||||
|
blockpos.set(x, min_below, z);
|
||||||
|
BlockState state = world.getBlockState(blockpos);
|
||||||
|
Block block = state.getBlock();
|
||||||
|
if (
|
||||||
|
block.matches(BlockTags.FENCES) ||
|
||||||
|
block.matches(BlockTags.WALLS) ||
|
||||||
|
((block instanceof FenceGateBlock) && !state.get(FenceGateBlock.OPEN))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (x == minX || x == maxX || z == minZ || z == maxZ) return world.doesNotCollide(bb);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "method_24931", at = @At(
|
@Redirect(method = "method_24931", at = @At(
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import net.minecraft.nbt.CompoundTag;
|
|||||||
import net.minecraft.predicate.entity.EntityPredicates;
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.server.integrated.IntegratedServer;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
@@ -53,8 +52,8 @@ import java.util.Collection;
|
|||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
@@ -274,6 +273,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
});
|
});
|
||||||
|
put("pose", (e, a) -> new StringValue(e.getPose().name().toLowerCase(Locale.ROOT)));
|
||||||
put("sneaking", (e, a) -> e.isSneaking()?Value.TRUE:Value.FALSE);
|
put("sneaking", (e, a) -> e.isSneaking()?Value.TRUE:Value.FALSE);
|
||||||
put("sprinting", (e, a) -> e.isSprinting()?Value.TRUE:Value.FALSE);
|
put("sprinting", (e, a) -> e.isSprinting()?Value.TRUE:Value.FALSE);
|
||||||
put("swimming", (e, a) -> e.isSwimming()?Value.TRUE:Value.FALSE);
|
put("swimming", (e, a) -> e.isSwimming()?Value.TRUE:Value.FALSE);
|
||||||
|
|||||||
Reference in new issue
Block a user