Merge branch 'master' into 1.16

This commit is contained in:
gnembon committed 2020-03-22 23:33:39 -03:00
commit 52aab4a6cb
4 files changed
+107 -30

No files matched your search

+25 -10
View File
@@ -62,7 +62,7 @@ or an OVERLY complex example:
or simply
<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>
It definitely pays to check what higher level `scarpet` functions have to offer.
@@ -112,16 +112,17 @@ Or rather:
<pre>
if
(
x&lt;y+6,
( x&lt;y+6,
(
set(x,8+y,z,'air');
plop(x,top('surface',x,z),z,'birch')
),
// else if
sin(query(player(),'yaw'))>0.5,
(
plop(0,0,0,'boulder')
),
// else
particle('fire',x,y,z)
)
</pre>
@@ -134,8 +135,10 @@ have problems with them
## Functions and scoping
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,
passed as arguments, called with `call` function, but in most cases you would want to call them directly by
execution in this, but also subsequent calls of /script command, added to events, etc. Functions can also be
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
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
@@ -690,10 +693,10 @@ number('2')+number('2') => 4
Returns a formatted string representing expression. Accepts formatting style accepted by `String.format`.
Supported types (with `"%?"` syntax):
* d, o, x: integers
* a, e, f, g: floats
* b: booleans
* s: strings
* `d`, `o`, `x`: integers, octal, hex
* `a`, `e`, `f`, `g`: floats
* `b`: booleans
* `s`: strings
<pre>
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
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
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
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.
### `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')`
Boolean, true if entity is sneaking.
+11
View File
@@ -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.
### `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')`
Boolean, true if entity is sneaking.
@@ -4,6 +4,8 @@ import carpet.CarpetSettings;
import carpet.fakes.WorldInterface;
import carpet.utils.SpawnReporter;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.FenceGateBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityCategory;
import net.minecraft.entity.EntityData;
@@ -13,6 +15,7 @@ import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.tag.BlockTags;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
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.
// 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
if (CarpetSettings.lagFreeSpawning)
if (!CarpetSettings.lagFreeSpawning)
{
BlockPos.Mutable blockpos = new BlockPos.Mutable();
int minX = MathHelper.floor(bb.x1);
int maxX = MathHelper.ceil(bb.x2);
int minY = MathHelper.floor(bb.y1);
int maxY = MathHelper.ceil(bb.y2);
int minZ = MathHelper.floor(bb.z1);
int maxZ = MathHelper.ceil(bb.z2);
for (int y = minY; y < maxY; y++)
for (int x = minX; x < maxX; x++)
for (int z = minZ; z < maxZ; z++)
return world.doesNotCollide(bb);
}
int minX = MathHelper.floor(bb.x1);
int minY = MathHelper.floor(bb.y1);
int minZ = MathHelper.floor(bb.z1);
int maxY = MathHelper.ceil(bb.y2)-1;
BlockPos.Mutable blockpos = new BlockPos.Mutable();
if (bb.getXLength() <= 1) // small mobs
{
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 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(
@@ -33,7 +33,6 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.LiteralText;
@@ -53,8 +52,8 @@ import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
@@ -274,6 +273,7 @@ public class EntityValue extends Value
}
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("sprinting", (e, a) -> e.isSprinting()?Value.TRUE:Value.FALSE);
put("swimming", (e, a) -> e.isSwimming()?Value.TRUE:Value.FALSE);