spawn point control to entity api

This commit is contained in:
gnembon committed 2020-10-28 04:09:12 -03:00
1 parent 33f8baf12d
commit 41e745ca0c
4 files changed
+139 -55

No files matched your search

+13 -1
View File
@@ -278,7 +278,12 @@ Returns mob's attack target or null if none or not applicable.
### `query(e, 'home')`
Returns creature's home position or null if none or not applicable.
Returns creature's home position (as per mob's AI, leash etc) or null if none or not applicable.
### `query(e, 'spawn_point')`
Returns position tuple, dimension, spawn angle, and whether spawn is forced, assuming the player has a spawn position.
Returns `false` if spawn position is not set, and `null` if `e` is not a player.
### `query(e, 'path')`
@@ -633,6 +638,13 @@ it clears all effects.
Sets AI to stay around the home position, within `distance` blocks from it. `distance` defaults to 16 blocks.
`null` removes it. _May_ not work fully with mobs that have this AI built in, like Villagers.
### `modify(e, 'spawn_point')`, `modify(e, 'spawn_point', null)`, `modify(e, 'spawn_point', pos, dimension?, angle?, forced?)`
Changes player respawn position to given position, optional dimension (defaults to current player dimension), angle (defaults to
current player facing) and spawn forced/fixed (defaults to `false`). If `none` or nothing is passed, the respawn point
will be reset (as removed) instead.
### `modify(e, 'gamemode', gamemode?), modify(e, 'gamemode', gamemode_id?)`
Modifies gamemode of player to whatever string (case-insensitive) or number you put in.
+3 -54
View File
@@ -18,7 +18,6 @@ import carpet.script.exception.ExitStatement;
import carpet.script.exception.InternalExpressionException;
import carpet.script.utils.ShapeDispatcher;
import carpet.script.utils.WorldTools;
import carpet.script.value.BlockValue;
import carpet.script.value.EntityValue;
import carpet.script.value.FormattedTextValue;
import carpet.script.value.ListValue;
@@ -59,7 +58,6 @@ import net.minecraft.util.math.EulerAngle;
import net.minecraft.util.math.Vec2f;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair;
@@ -606,58 +604,9 @@ public class Auxiliary {
expression.addLazyFunction("in_dimension", 2, (c, t, lv) -> {
ServerCommandSource outerSource = ((CarpetContext)c).s;
Value dimensionValue = lv.get(0).evalValue(c);
ServerCommandSource innerSource = outerSource;
if (dimensionValue instanceof EntityValue)
{
innerSource = outerSource.withWorld((ServerWorld) ((EntityValue)dimensionValue).getEntity().getEntityWorld());
}
else if (dimensionValue instanceof BlockValue)
{
BlockValue bv = (BlockValue)dimensionValue;
if (bv.getWorld() != null)
{
innerSource = outerSource.withWorld(bv.getWorld());
}
else
{
throw new InternalExpressionException("'in_dimension' accepts only world-localized block arguments");
}
}
else
{
String dimString = dimensionValue.getString().toLowerCase(Locale.ROOT);
switch (dimString)
{
case "nether":
case "the_nether":
innerSource = outerSource.withWorld(outerSource.getMinecraftServer().getWorld(World.NETHER)); //nether
break;
case "end":
case "the_end":
innerSource = outerSource.withWorld(outerSource.getMinecraftServer().getWorld(World.END)); //end
break;
case "overworld":
case "over_world":
innerSource = outerSource.withWorld(outerSource.getMinecraftServer().getWorld(World.OVERWORLD)); //ow
break;
default:
RegistryKey<World> dim = null;
Identifier id = new Identifier(dimString);
// not using RegistryKey.of since that one creates on check
for (RegistryKey<World> world : (outerSource.getMinecraftServer().getWorldRegistryKeys()))
{
if (id.equals(world.getValue()))
{
dim = world;
break;
}
}
if (dim == null)
throw new InternalExpressionException("Incorrect dimension string: "+dimString);
innerSource = outerSource.withWorld(outerSource.getMinecraftServer().getWorld(dim));
}
};
if (innerSource.getWorld() == outerSource.getWorld()) return lv.get(1);
World world = ValueConversions.dimFromValue(dimensionValue, outerSource.getMinecraftServer());
if (world == outerSource.getWorld()) return lv.get(1);
ServerCommandSource innerSource = outerSource.withWorld((ServerWorld)world);
Context newCtx = c.recreate();
((CarpetContext) newCtx).s = innerSource;
newCtx.variables = c.variables;
@@ -61,7 +61,9 @@ import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.GameMode;
import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
@@ -354,6 +356,20 @@ public class EntityValue extends Value
}
return Value.NULL;
});
put("spawn_point", (e, a) -> {
if (e instanceof ServerPlayerEntity)
{
ServerPlayerEntity spe = (ServerPlayerEntity)e;
if (spe.getSpawnPointPosition() == null) return Value.FALSE;
return ListValue.of(
ValueConversions.fromPos(spe.getSpawnPointPosition()),
ValueConversions.dimName(spe.getSpawnPointDimension()),
new NumericValue(spe.getSpawnAngle()),
new NumericValue(spe.isSpawnPointSet()) // true if forced spawn point
);
}
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);
@@ -1004,6 +1020,54 @@ public class EntityValue extends Value
}
}); //requires mixing
put("spawn_point", (e, a) -> {
if (!(e instanceof ServerPlayerEntity)) return;
ServerPlayerEntity spe = (ServerPlayerEntity)e;
if (a == null)
{
spe.setSpawnPoint(null, null, 0, false, false);
}
else if (a instanceof ListValue)
{
List<Value> params= ((ListValue) a).getItems();
Vector3Argument blockLocator = Vector3Argument.findIn(params, 0, false);
BlockPos pos = new BlockPos(blockLocator.vec);
RegistryKey<World> world = spe.getEntityWorld().getRegistryKey();
float angle = spe.getHeadYaw();
boolean forced = false;
if (params.size() > blockLocator.offset)
{
Value worldValue = params.get(blockLocator.offset+0);
world = ValueConversions.dimFromValue(worldValue, spe.getServer()).getRegistryKey();
if (params.size() > blockLocator.offset+1)
{
angle = NumericValue.asNumber(params.get(blockLocator.offset+1), "angle").getFloat();
if (params.size() > blockLocator.offset+2)
{
forced = params.get(blockLocator.offset+2).getBoolean();
}
}
}
spe.setSpawnPoint(world, pos, angle, forced, false);
}
else if (a instanceof BlockValue)
{
BlockValue bv= (BlockValue)a;
if (bv.getPos()==null || bv.getWorld() == null)
throw new InternalExpressionException("block for spawn modification should be localised in the world");
spe.setSpawnPoint(bv.getWorld().getRegistryKey(), bv.getPos(), e.yaw, true, false);
}
else if (a.isNull())
{
spe.setSpawnPoint(null, null, 0, false, false);
}
else
{
throw new InternalExpressionException("modifying player respawn point requires a block position, optional world, optional angle, and optional force");
}
});
put("pickup_delay", (e, v) ->
{
if (e instanceof ItemEntity)
@@ -1,11 +1,13 @@
package carpet.script.value;
import carpet.script.exception.InternalExpressionException;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ai.brain.LookTarget;
import net.minecraft.entity.ai.brain.WalkTarget;
import net.minecraft.entity.ai.pathing.Path;
import net.minecraft.entity.ai.pathing.PathNode;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.structure.StructurePiece;
@@ -36,6 +38,12 @@ public class ValueConversions
return ListValue.of(new NumericValue(pos.getX()), new NumericValue(pos.getY()), new NumericValue(pos.getZ()));
}
public static Value fromPosOptional(BlockPos pos)
{
if (pos == null) return Value.NULL;
return ListValue.of(new NumericValue(pos.getX()), new NumericValue(pos.getY()), new NumericValue(pos.getZ()));
}
public static Value fromVec(Vec3d vec)
{
return ListValue.of(new NumericValue(vec.x), new NumericValue(vec.y), new NumericValue(vec.z));
@@ -46,6 +54,57 @@ public class ValueConversions
return ofId(world.getRegistryKey().getValue());
}
public static World dimFromValue(Value dimensionValue, MinecraftServer server)
{
if (dimensionValue instanceof EntityValue)
{
return ((EntityValue)dimensionValue).getEntity().getEntityWorld();
}
else if (dimensionValue instanceof BlockValue)
{
BlockValue bv = (BlockValue)dimensionValue;
if (bv.getWorld() != null)
{
return bv.getWorld();
}
else
{
throw new InternalExpressionException("dimension argument accepts only world-localized block arguments");
}
}
else
{
String dimString = dimensionValue.getString().toLowerCase(Locale.ROOT);
switch (dimString)
{
case "nether":
case "the_nether":
return server.getWorld(World.NETHER);
case "end":
case "the_end":
return server.getWorld(World.END);
case "overworld":
case "over_world":
return server.getWorld(World.OVERWORLD);
default:
RegistryKey<World> dim = null;
Identifier id = new Identifier(dimString);
// not using RegistryKey.of since that one creates on check
for (RegistryKey<World> world : (server.getWorldRegistryKeys()))
{
if (id.equals(world.getValue()))
{
dim = world;
break;
}
}
if (dim == null)
throw new InternalExpressionException("Incorrect dimension string: "+dimString);
return server.getWorld(dim);
}
}
}
public static Value dimName(RegistryKey<World> dim)
{
return ofId(dim.getValue());