Merge branch 'master' into 1.17
# Conflicts: # src/main/java/carpet/script/api/Entities.java
This commit is contained in:
commit
02a25c0c99
16 files changed
+187
-31
No files matched your search
+31
-5
@@ -1757,7 +1757,8 @@ Here is the gist of the Minecraft related functions. Otherwise the CarpetScript
|
|||||||
## App structure
|
## App structure
|
||||||
|
|
||||||
The main delivery method for scarpet programs into the game is in the form of apps in `*.sc` files located in the world `scripts`
|
The main delivery method for scarpet programs into the game is in the form of apps in `*.sc` files located in the world `scripts`
|
||||||
folder. In singleplayer, you can also save apps in `.minecraft/config/carpet/scripts` for them to be available in any world.
|
folder, flat. In singleplayer, you can also save apps in `.minecraft/config/carpet/scripts` for them to be available in any world,
|
||||||
|
and here you can actually organize them in folders.
|
||||||
When loaded (via `/script load` command, etc.), the game will run the content of the app once, regardless of its scope
|
When loaded (via `/script load` command, etc.), the game will run the content of the app once, regardless of its scope
|
||||||
(more about the app scopes below), without executing of any functions, unless called directly, and with the exception of the
|
(more about the app scopes below), without executing of any functions, unless called directly, and with the exception of the
|
||||||
`__config()` function, if present, which will be executed once. Loading the app will also bind specific
|
`__config()` function, if present, which will be executed once. Loading the app will also bind specific
|
||||||
@@ -2919,6 +2920,8 @@ to the `regular` group.
|
|||||||
* `monster`, `creature`, `ambient`, `water_creature`, `water_ambient`, `misc` - another categorization of
|
* `monster`, `creature`, `ambient`, `water_creature`, `water_ambient`, `misc` - another categorization of
|
||||||
living entities based on their spawn group. Negative descriptor resolves to all living types that don't belong to that
|
living entities based on their spawn group. Negative descriptor resolves to all living types that don't belong to that
|
||||||
category.
|
category.
|
||||||
|
* All entity tags including those provided with datapacks. Built-in entity tags include: `skeletons`, `raiders`,
|
||||||
|
`beehive_inhabitors` (bee, duh), `arrows` and `impact_projectiles`.
|
||||||
* Any of the following standard entity types (equivalent to selection from `/summon` vanilla command:
|
* Any of the following standard entity types (equivalent to selection from `/summon` vanilla command:
|
||||||
`area_effect_cloud`, `armor_stand`, `arrow`, `bat`, `bee`, `blaze`, `boat`, `cat`, `cave_spider`, `chest_minecart`,
|
`area_effect_cloud`, `armor_stand`, `arrow`, `bat`, `bee`, `blaze`, `boat`, `cat`, `cave_spider`, `chest_minecart`,
|
||||||
`chicken`, `cod`, `command_block_minecart`, `cow`, `creeper`, `dolphin`, `donkey`, `dragon_fireball`, `drowned`,
|
`chicken`, `cod`, `command_block_minecart`, `cow`, `creeper`, `dolphin`, `donkey`, `dragon_fireball`, `drowned`,
|
||||||
@@ -3076,13 +3079,21 @@ List of entities riding the entity.
|
|||||||
|
|
||||||
Entity that `e` rides.
|
Entity that `e` rides.
|
||||||
|
|
||||||
### `query(e, 'tags')`
|
### `query(e, 'scoreboard_tags')`, `query(e, 'tags')`(deprecated)
|
||||||
|
|
||||||
List of entity's tags.
|
List of entity's scoreboard tags.
|
||||||
|
|
||||||
### `query(e, 'has_tag',tag)`
|
### `query(e, 'has_scoreboard_tag',tag)`, `query(e, 'has_tag',tag)`(deprecated)
|
||||||
|
|
||||||
Boolean, true if the entity is marked with `tag`.
|
Boolean, true if the entity is marked with a `tag` scoreboad tag.
|
||||||
|
|
||||||
|
### `query(e, 'entity_tags')`
|
||||||
|
|
||||||
|
List of entity tags assigned to the type this entity represents.
|
||||||
|
|
||||||
|
### `query(e, 'has_entity_tag', tag)`
|
||||||
|
|
||||||
|
Returns `true` if the entity matches that entity tag, `false` if it doesn't, and `null` if the tag is not valid.
|
||||||
|
|
||||||
### `query(e, 'is_burning')`
|
### `query(e, 'is_burning')`
|
||||||
|
|
||||||
@@ -3744,6 +3755,14 @@ an inventory, all API functions typically do nothing and return null.
|
|||||||
|
|
||||||
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
||||||
|
|
||||||
|
### item_list(tag?)
|
||||||
|
|
||||||
|
With no arguments, returns a list of all items in the game. With an item tag provided, list items matching the tag, or `null` if tag is not valid.
|
||||||
|
|
||||||
|
### item_tags(item, tag?)
|
||||||
|
|
||||||
|
Returns list of tags the item belongs to, or, if tag is provided, `true` if an item maches the tag, `false` if it doesn't and `null` if that's not a valid tag
|
||||||
|
|
||||||
### `stack_limit(item)`
|
### `stack_limit(item)`
|
||||||
|
|
||||||
Returns number indicating what is the stack limit for the item. Its typically 1 (non-stackable), 16 (like buckets),
|
Returns number indicating what is the stack limit for the item. Its typically 1 (non-stackable), 16 (like buckets),
|
||||||
@@ -3940,6 +3959,13 @@ if it accepts required number of parameters.
|
|||||||
Global events will be handled once per app that is with `'global'` scope. With `player` scoped apps, each player instance
|
Global events will be handled once per app that is with `'global'` scope. With `player` scoped apps, each player instance
|
||||||
is responsible independently from handling their events, so a global event may be executed multiple times for each player.
|
is responsible independently from handling their events, so a global event may be executed multiple times for each player.
|
||||||
|
|
||||||
|
### `__on_server_starts()`
|
||||||
|
Event triggers after world is loaded and after all startup apps have started. It won't be triggered with `/reload`.
|
||||||
|
|
||||||
|
### `__on_server_shuts_down()`
|
||||||
|
Event triggers when the server started the shutdown process, before `__on_close()` is executed. Unlike `__on_close()`, it doesn't
|
||||||
|
trigger with `/reload`.
|
||||||
|
|
||||||
### `__on_tick()`
|
### `__on_tick()`
|
||||||
Event triggers at the beginning of each tick, located in the overworld. You can use `in_dimension()`
|
Event triggers at the beginning of each tick, located in the overworld. You can use `in_dimension()`
|
||||||
to access other dimensions from there.
|
to access other dimensions from there.
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ to the `regular` group.
|
|||||||
* `monster`, `creature`, `ambient`, `water_creature`, `water_ambient`, `misc` - another categorization of
|
* `monster`, `creature`, `ambient`, `water_creature`, `water_ambient`, `misc` - another categorization of
|
||||||
living entities based on their spawn group. Negative descriptor resolves to all living types that don't belong to that
|
living entities based on their spawn group. Negative descriptor resolves to all living types that don't belong to that
|
||||||
category.
|
category.
|
||||||
|
* All entity tags including those provided with datapacks. Built-in entity tags include: `skeletons`, `raiders`,
|
||||||
|
`beehive_inhabitors` (bee, duh), `arrows` and `impact_projectiles`.
|
||||||
* Any of the following standard entity types (equivalent to selection from `/summon` vanilla command:
|
* Any of the following standard entity types (equivalent to selection from `/summon` vanilla command:
|
||||||
`area_effect_cloud`, `armor_stand`, `arrow`, `bat`, `bee`, `blaze`, `boat`, `cat`, `cave_spider`, `chest_minecart`,
|
`area_effect_cloud`, `armor_stand`, `arrow`, `bat`, `bee`, `blaze`, `boat`, `cat`, `cave_spider`, `chest_minecart`,
|
||||||
`chicken`, `cod`, `command_block_minecart`, `cow`, `creeper`, `dolphin`, `donkey`, `dragon_fireball`, `drowned`,
|
`chicken`, `cod`, `command_block_minecart`, `cow`, `creeper`, `dolphin`, `donkey`, `dragon_fireball`, `drowned`,
|
||||||
@@ -209,13 +211,21 @@ List of entities riding the entity.
|
|||||||
|
|
||||||
Entity that `e` rides.
|
Entity that `e` rides.
|
||||||
|
|
||||||
### `query(e, 'tags')`
|
### `query(e, 'scoreboard_tags')`, `query(e, 'tags')`(deprecated)
|
||||||
|
|
||||||
List of entity's tags.
|
List of entity's scoreboard tags.
|
||||||
|
|
||||||
### `query(e, 'has_tag',tag)`
|
### `query(e, 'has_scoreboard_tag',tag)`, `query(e, 'has_tag',tag)`(deprecated)
|
||||||
|
|
||||||
Boolean, true if the entity is marked with `tag`.
|
Boolean, true if the entity is marked with a `tag` scoreboad tag.
|
||||||
|
|
||||||
|
### `query(e, 'entity_tags')`
|
||||||
|
|
||||||
|
List of entity tags assigned to the type this entity represents.
|
||||||
|
|
||||||
|
### `query(e, 'has_entity_tag', tag)`
|
||||||
|
|
||||||
|
Returns `true` if the entity matches that entity tag, `false` if it doesn't, and `null` if the tag is not valid.
|
||||||
|
|
||||||
### `query(e, 'is_burning')`
|
### `query(e, 'is_burning')`
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,13 @@ if it accepts required number of parameters.
|
|||||||
Global events will be handled once per app that is with `'global'` scope. With `player` scoped apps, each player instance
|
Global events will be handled once per app that is with `'global'` scope. With `player` scoped apps, each player instance
|
||||||
is responsible independently from handling their events, so a global event may be executed multiple times for each player.
|
is responsible independently from handling their events, so a global event may be executed multiple times for each player.
|
||||||
|
|
||||||
|
### `__on_server_starts()`
|
||||||
|
Event triggers after world is loaded and after all startup apps have started. It won't be triggered with `/reload`.
|
||||||
|
|
||||||
|
### `__on_server_shuts_down()`
|
||||||
|
Event triggers when the server started the shutdown process, before `__on_close()` is executed. Unlike `__on_close()`, it doesn't
|
||||||
|
trigger with `/reload`.
|
||||||
|
|
||||||
### `__on_tick()`
|
### `__on_tick()`
|
||||||
Event triggers at the beginning of each tick, located in the overworld. You can use `in_dimension()`
|
Event triggers at the beginning of each tick, located in the overworld. You can use `in_dimension()`
|
||||||
to access other dimensions from there.
|
to access other dimensions from there.
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ an inventory, all API functions typically do nothing and return null.
|
|||||||
|
|
||||||
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
||||||
|
|
||||||
|
### item_list(tag?)
|
||||||
|
|
||||||
|
With no arguments, returns a list of all items in the game. With an item tag provided, list items matching the tag, or `null` if tag is not valid.
|
||||||
|
|
||||||
|
### item_tags(item, tag?)
|
||||||
|
|
||||||
|
Returns list of tags the item belongs to, or, if tag is provided, `true` if an item maches the tag, `false` if it doesn't and `null` if that's not a valid tag
|
||||||
|
|
||||||
### `stack_limit(item)`
|
### `stack_limit(item)`
|
||||||
|
|
||||||
Returns number indicating what is the stack limit for the item. Its typically 1 (non-stackable), 16 (like buckets),
|
Returns number indicating what is the stack limit for the item. Its typically 1 (non-stackable), 16 (like buckets),
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ Here is the gist of the Minecraft related functions. Otherwise the CarpetScript
|
|||||||
## App structure
|
## App structure
|
||||||
|
|
||||||
The main delivery method for scarpet programs into the game is in the form of apps in `*.sc` files located in the world `scripts`
|
The main delivery method for scarpet programs into the game is in the form of apps in `*.sc` files located in the world `scripts`
|
||||||
folder. In singleplayer, you can also save apps in `.minecraft/config/carpet/scripts` for them to be available in any world.
|
folder, flat. In singleplayer, you can also save apps in `.minecraft/config/carpet/scripts` for them to be available in any world,
|
||||||
|
and here you can actually organize them in folders.
|
||||||
When loaded (via `/script load` command, etc.), the game will run the content of the app once, regardless of its scope
|
When loaded (via `/script load` command, etc.), the game will run the content of the app once, regardless of its scope
|
||||||
(more about the app scopes below), without executing of any functions, unless called directly, and with the exception of the
|
(more about the app scopes below), without executing of any functions, unless called directly, and with the exception of the
|
||||||
`__config()` function, if present, which will be executed once. Loading the app will also bind specific
|
`__config()` function, if present, which will be executed once. Loading the app will also bind specific
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ inventory_remove
|
|||||||
inventory_set
|
inventory_set
|
||||||
inventory_size
|
inventory_size
|
||||||
item_category
|
item_category
|
||||||
|
item_list
|
||||||
|
item_tags
|
||||||
last_tick_times
|
last_tick_times
|
||||||
light
|
light
|
||||||
liquid
|
liquid
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
|
|
||||||
player spawn entity_id entity_list entity_area entity_selector query modify entity_event entity_load_handler entity_types
|
player spawn entity_id entity_list entity_area entity_selector query modify entity_event entity_load_handler entity_types
|
||||||
|
|
||||||
stack_limit item_category recipe_data crafting_remaining_item
|
item_list item_tags stack_limit item_category recipe_data crafting_remaining_item
|
||||||
|
|
||||||
inventory_size inventory_has_items inventory_get inventory_set inventory_find inventory_remove drop_item
|
inventory_size inventory_has_items inventory_get inventory_set inventory_find inventory_remove drop_item
|
||||||
|
|
||||||
|
|||||||
@@ -102,9 +102,9 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit
|
|||||||
|
|
||||||
public static void onServerLoadedWorlds(MinecraftServer minecraftServer)
|
public static void onServerLoadedWorlds(MinecraftServer minecraftServer)
|
||||||
{
|
{
|
||||||
|
HopperCounter.resetAll(minecraftServer);
|
||||||
extensions.forEach(e -> e.onServerLoadedWorlds(minecraftServer));
|
extensions.forEach(e -> e.onServerLoadedWorlds(minecraftServer));
|
||||||
scriptServer.initializeForWorld();
|
scriptServer.initializeForWorld();
|
||||||
HopperCounter.resetAll(minecraftServer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick(MinecraftServer server)
|
public static void tick(MinecraftServer server)
|
||||||
@@ -169,9 +169,9 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit
|
|||||||
|
|
||||||
public static void onServerClosed(MinecraftServer server)
|
public static void onServerClosed(MinecraftServer server)
|
||||||
{
|
{
|
||||||
|
if (scriptServer != null) scriptServer.onClose();
|
||||||
ServerNetworkHandler.close();
|
ServerNetworkHandler.close();
|
||||||
currentCommandDispatcher = null;
|
currentCommandDispatcher = null;
|
||||||
if (scriptServer != null) scriptServer.onClose();
|
|
||||||
|
|
||||||
LoggerRegistry.stopLoggers();
|
LoggerRegistry.stopLoggers();
|
||||||
extensions.forEach(e -> e.onServerClosed(server));
|
extensions.forEach(e -> e.onServerClosed(server));
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ public class CarpetSettings
|
|||||||
extra = "if /script is enabled",
|
extra = "if /script is enabled",
|
||||||
category = SCARPET
|
category = SCARPET
|
||||||
)
|
)
|
||||||
public static boolean scriptsAutoload = false;
|
public static boolean scriptsAutoload = true;
|
||||||
|
|
||||||
@Rule(desc = "Enables /player command to control/spawn players", category = COMMAND)
|
@Rule(desc = "Enables /player command to control/spawn players", category = COMMAND)
|
||||||
public static String commandPlayer = "ops";
|
public static String commandPlayer = "ops";
|
||||||
|
|||||||
@@ -309,6 +309,30 @@ public class CarpetEventServer
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Event START = new Event("server_starts", 0, true)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onTick()
|
||||||
|
{
|
||||||
|
handler.call(Collections::emptyList, () ->
|
||||||
|
CarpetServer.minecraft_server.getCommandSource().
|
||||||
|
withWorld(CarpetServer.minecraft_server.getWorld(World.OVERWORLD))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final Event SHUTDOWN = new Event("server_shuts_down", 0, true)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onTick()
|
||||||
|
{
|
||||||
|
handler.call(Collections::emptyList, () ->
|
||||||
|
CarpetServer.minecraft_server.getCommandSource().
|
||||||
|
withWorld(CarpetServer.minecraft_server.getWorld(World.OVERWORLD))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static final Event TICK = new Event("tick", 0, true)
|
public static final Event TICK = new Event("tick", 0, true)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
if (!(ret instanceof MapValue)) return false;
|
if (!(ret instanceof MapValue)) return false;
|
||||||
Map<Value, Value> config = ((MapValue) ret).getMap();
|
Map<Value, Value> config = ((MapValue) ret).getMap();
|
||||||
setPerPlayer(config.getOrDefault(new StringValue("scope"), new StringValue("player")).getString().equalsIgnoreCase("player"));
|
setPerPlayer(config.getOrDefault(new StringValue("scope"), new StringValue("player")).getString().equalsIgnoreCase("player"));
|
||||||
persistenceRequired = config.getOrDefault(new StringValue("stay_loaded"), Value.FALSE).getBoolean();
|
persistenceRequired = config.getOrDefault(new StringValue("stay_loaded"), Value.TRUE).getBoolean();
|
||||||
// read custom arguments
|
// read custom arguments
|
||||||
Value arguments = config.get(StringValue.of("arguments"));
|
Value arguments = config.get(StringValue.of("arguments"));
|
||||||
if (arguments != null)
|
if (arguments != null)
|
||||||
|
|||||||
@@ -122,13 +122,12 @@ public class CarpetScriptServer
|
|||||||
});
|
});
|
||||||
if (CarpetSettings.scriptsAutoload)
|
if (CarpetSettings.scriptsAutoload)
|
||||||
{
|
{
|
||||||
Messenger.m(server.getCommandSource(), "Auto-loading world scarpet apps");
|
|
||||||
for (String moduleName: listAvailableModules(false))
|
for (String moduleName: listAvailableModules(false))
|
||||||
{
|
{
|
||||||
addScriptHost(server.getCommandSource(), moduleName, null, true, true, false);
|
addScriptHost(server.getCommandSource(), moduleName, null, true, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CarpetEventServer.Event.START.onTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Module getModule(String name, boolean allowLibraries)
|
public Module getModule(String name, boolean allowLibraries)
|
||||||
@@ -149,7 +148,7 @@ public class CarpetScriptServer
|
|||||||
{
|
{
|
||||||
Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
||||||
Files.createDirectories(globalFolder);
|
Files.createDirectories(globalFolder);
|
||||||
scriptPath = Files.list(globalFolder)
|
scriptPath = Files.walk(globalFolder)
|
||||||
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
||||||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
|
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
@@ -194,7 +193,7 @@ public class CarpetScriptServer
|
|||||||
try {
|
try {
|
||||||
Path worldScripts = server.getSavePath(WorldSavePath.ROOT).resolve("scripts");
|
Path worldScripts = server.getSavePath(WorldSavePath.ROOT).resolve("scripts");
|
||||||
Files.createDirectories(worldScripts);
|
Files.createDirectories(worldScripts);
|
||||||
Files.walk(worldScripts)
|
Files.list(worldScripts)
|
||||||
.filter(f -> f.toString().endsWith(".sc"))
|
.filter(f -> f.toString().endsWith(".sc"))
|
||||||
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$","").toLowerCase(Locale.ROOT)));
|
.forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$","").toLowerCase(Locale.ROOT)));
|
||||||
|
|
||||||
@@ -490,6 +489,7 @@ public class CarpetScriptServer
|
|||||||
|
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
|
CarpetEventServer.Event.SHUTDOWN.onTick();
|
||||||
for (ScriptHost host : modules.values())
|
for (ScriptHost host : modules.values())
|
||||||
{
|
{
|
||||||
host.onClose();
|
host.onClose();
|
||||||
|
|||||||
@@ -23,6 +23,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.predicate.entity.EntityPredicates;
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
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.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
@@ -34,6 +35,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -183,8 +185,9 @@ public class Entities {
|
|||||||
expression.addLazyFunction("entity_list", 1, (c, t, lv) ->
|
expression.addLazyFunction("entity_list", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
String who = lv.get(0).evalValue(c).getString();
|
String who = lv.get(0).evalValue(c).getString();
|
||||||
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who);
|
ServerCommandSource source = ((CarpetContext)c).s;
|
||||||
List<? extends Entity> entityList = ((CarpetContext)c).s.getWorld().getEntitiesByType(eDesc.directType, eDesc.filteringPredicate);
|
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, source.getMinecraftServer());
|
||||||
|
List<? extends Entity> entityList = source.getWorld().getEntitiesByType(eDesc.directType, eDesc.filteringPredicate);
|
||||||
Value retval = ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
|
Value retval = ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
|
||||||
return (_c, _t ) -> retval;
|
return (_c, _t ) -> retval;
|
||||||
});
|
});
|
||||||
@@ -212,8 +215,8 @@ public class Entities {
|
|||||||
throw new InternalExpressionException("Range of 'entity_area' cannot come from a block argument");
|
throw new InternalExpressionException("Range of 'entity_area' cannot come from a block argument");
|
||||||
Vec3d range = rangeLocator.vec;
|
Vec3d range = rangeLocator.vec;
|
||||||
Box area = centerBox.expand(range.x, range.y, range.z);
|
Box area = centerBox.expand(range.x, range.y, range.z);
|
||||||
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who);
|
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, cc.s.getMinecraftServer());
|
||||||
List<? extends Entity> entityList = ((CarpetContext)c).s.getWorld().getEntitiesByType(eDesc.directType, area,eDesc.filteringPredicate);
|
List<? extends Entity> entityList = cc.s.getWorld().getEntitiesByType(eDesc.directType, area,eDesc.filteringPredicate);
|
||||||
Value retval = ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
|
Value retval = ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
|
||||||
return (_c, _t ) -> retval;
|
return (_c, _t ) -> retval;
|
||||||
});
|
});
|
||||||
@@ -238,7 +241,9 @@ public class Entities {
|
|||||||
Value v = lv.get(0).evalValue(c);
|
Value v = lv.get(0).evalValue(c);
|
||||||
if (!(v instanceof EntityValue))
|
if (!(v instanceof EntityValue))
|
||||||
throw new InternalExpressionException("First argument to query should be an entity");
|
throw new InternalExpressionException("First argument to query should be an entity");
|
||||||
String what = lv.get(1).evalValue(c).getString();
|
String what = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||||
|
if (what.equals("tags"))
|
||||||
|
c.host.issueDeprecation("'tags' for entity querying");
|
||||||
Value retval;
|
Value retval;
|
||||||
if (lv.size()==2)
|
if (lv.size()==2)
|
||||||
retval = ((EntityValue) v).get(what, null);
|
retval = ((EntityValue) v).get(what, null);
|
||||||
@@ -269,11 +274,13 @@ public class Entities {
|
|||||||
return (cc, tt) -> v;
|
return (cc, tt) -> v;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("entity_types", (lv) ->
|
expression.addLazyFunction("entity_types", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
|
|
||||||
if (lv.size() > 1) throw new InternalExpressionException("'entity_types' requires one or no arguments");
|
if (lv.size() > 1) throw new InternalExpressionException("'entity_types' requires one or no arguments");
|
||||||
String desc = (lv.size() == 1)?lv.get(0).getString():"*";
|
String desc = (lv.size() == 1)?lv.get(0).evalValue(c).getString():"*";
|
||||||
return EntityValue.getEntityDescriptor(desc).listValue;
|
Value ret = EntityValue.getEntityDescriptor(desc, ((CarpetContext) c).s.getMinecraftServer()).listValue;
|
||||||
|
return (_c, _t) -> ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addLazyFunction("entity_load_handler", -1, (c, t, lv) ->
|
expression.addLazyFunction("entity_load_handler", -1, (c, t, lv) ->
|
||||||
@@ -285,7 +292,7 @@ public class Entities {
|
|||||||
? ((ListValue) entityValue).getItems().stream().map(Value::getString).collect(Collectors.toList())
|
? ((ListValue) entityValue).getItems().stream().map(Value::getString).collect(Collectors.toList())
|
||||||
: Collections.singletonList(entityValue.getString());
|
: Collections.singletonList(entityValue.getString());
|
||||||
Set<EntityType<? extends Entity>> types = new HashSet<>();
|
Set<EntityType<? extends Entity>> types = new HashSet<>();
|
||||||
descriptors.forEach(s -> types.addAll(EntityValue.getEntityDescriptor(s).typeList));
|
descriptors.forEach(s -> types.addAll(EntityValue.getEntityDescriptor(s, ((CarpetContext) c).s.getMinecraftServer()).typeList));
|
||||||
FunctionArgument<LazyValue> funArg = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
|
FunctionArgument<LazyValue> funArg = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
|
||||||
CarpetEventServer events = ((CarpetScriptHost)c.host).getScriptServer().events;
|
CarpetEventServer events = ((CarpetScriptHost)c.host).getScriptServer().events;
|
||||||
if (funArg.function == null)
|
if (funArg.function == null)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import carpet.script.value.NullValue;
|
|||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
|
import carpet.script.value.ValueConversions;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.command.argument.ItemStackArgument;
|
import net.minecraft.command.argument.ItemStackArgument;
|
||||||
@@ -32,6 +33,7 @@ import net.minecraft.recipe.ShapedRecipe;
|
|||||||
import net.minecraft.recipe.ShapelessRecipe;
|
import net.minecraft.recipe.ShapelessRecipe;
|
||||||
import net.minecraft.recipe.SpecialCraftingRecipe;
|
import net.minecraft.recipe.SpecialCraftingRecipe;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.tag.TagManager;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.InvalidIdentifierException;
|
import net.minecraft.util.InvalidIdentifierException;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
@@ -40,6 +42,7 @@ import net.minecraft.util.registry.Registry;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class Inventories {
|
public class Inventories {
|
||||||
public static void apply(Expression expression)
|
public static void apply(Expression expression)
|
||||||
@@ -60,6 +63,43 @@ public class Inventories {
|
|||||||
return (_c, _t) -> res;
|
return (_c, _t) -> res;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
expression.addLazyFunction("item_list", -1, (c, t, lv) ->
|
||||||
|
{
|
||||||
|
if (lv.size() == 0)
|
||||||
|
{
|
||||||
|
Value res = ListValue.wrap(Registry.ITEM.getIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
|
||||||
|
return (cc, tt) -> res;
|
||||||
|
}
|
||||||
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
TagManager tagManager = cc.s.getMinecraftServer().getTagManager();
|
||||||
|
String tag = lv.get(0).evalValue(c).getString();
|
||||||
|
net.minecraft.tag.Tag<Item> itemTag = tagManager.getItems().getTag(new Identifier(tag));
|
||||||
|
if (itemTag == null) return LazyValue.NULL;
|
||||||
|
Value ret = ListValue.wrap(itemTag.values().stream().map(b -> ValueConversions.of(Registry.ITEM.getId(b))).collect(Collectors.toList()));
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
expression.addLazyFunction("item_tags", -1, (c, t, lv) ->
|
||||||
|
{
|
||||||
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
TagManager tagManager = cc.s.getMinecraftServer().getTagManager();
|
||||||
|
if (lv.size() == 0)
|
||||||
|
{
|
||||||
|
Value ret = ListValue.wrap(tagManager.getItems().getTagIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
Item item = NBTSerializableValue.parseItem(lv.get(0).evalValue(c).getString()).getItem();
|
||||||
|
if (lv.size() == 1)
|
||||||
|
{
|
||||||
|
Value ret = ListValue.wrap(tagManager.getItems().getTagsFor(item).stream().map(ValueConversions::of).collect(Collectors.toList()));
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
String tag = lv.get(1).evalValue(c).getString();
|
||||||
|
net.minecraft.tag.Tag<Item> itemTag = tagManager.getItems().getTag(new Identifier(tag));
|
||||||
|
if (itemTag == null) return LazyValue.NULL;
|
||||||
|
return item.isIn(itemTag)?LazyValue.TRUE:LazyValue.FALSE;
|
||||||
|
});
|
||||||
|
|
||||||
expression.addLazyFunction("recipe_data", -1, (c, t, lv) ->
|
expression.addLazyFunction("recipe_data", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
CarpetContext cc = (CarpetContext)c;
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
|||||||
@@ -224,10 +224,28 @@ public class EntityValue extends Value
|
|||||||
return entity.hashCode();
|
return entity.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityClassDescriptor getEntityDescriptor(String who)
|
public static EntityClassDescriptor getEntityDescriptor(String who, MinecraftServer server)
|
||||||
{
|
{
|
||||||
EntityClassDescriptor eDesc = EntityClassDescriptor.byName.get(who);
|
EntityClassDescriptor eDesc = EntityClassDescriptor.byName.get(who);
|
||||||
if (eDesc == null) throw new InternalExpressionException(who+" is not a valid entity descriptor");
|
if (eDesc == null)
|
||||||
|
{
|
||||||
|
boolean positive = true;
|
||||||
|
if (who.startsWith("!"))
|
||||||
|
{
|
||||||
|
positive = false;
|
||||||
|
who = who.substring(1);
|
||||||
|
}
|
||||||
|
net.minecraft.tag.Tag<EntityType<?>> eTag = server.getTagManager().getEntityTypes().getTag(new Identifier(who));
|
||||||
|
if (eTag == null) throw new InternalExpressionException(who+" is not a valid entity descriptor");
|
||||||
|
if (positive)
|
||||||
|
{
|
||||||
|
return new EntityClassDescriptor(null, e -> eTag.contains(e.getType()) && e.isAlive(), eTag.values().stream());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new EntityClassDescriptor(null, e -> !eTag.contains(e.getType()) && e.isAlive(), Registry.ENTITY_TYPE.stream().filter(et -> !eTag.contains(et)));
|
||||||
|
}
|
||||||
|
}
|
||||||
return eDesc;
|
return eDesc;
|
||||||
//TODO add more here like search by tags, or type
|
//TODO add more here like search by tags, or type
|
||||||
//if (who.startsWith('tag:'))
|
//if (who.startsWith('tag:'))
|
||||||
@@ -416,8 +434,21 @@ public class EntityValue extends Value
|
|||||||
put("passengers", (e, a) -> ListValue.wrap(e.getPassengerList().stream().map(EntityValue::new).collect(Collectors.toList())));
|
put("passengers", (e, a) -> ListValue.wrap(e.getPassengerList().stream().map(EntityValue::new).collect(Collectors.toList())));
|
||||||
put("mount", (e, a) -> (e.getVehicle()!=null)?new EntityValue(e.getVehicle()):Value.NULL);
|
put("mount", (e, a) -> (e.getVehicle()!=null)?new EntityValue(e.getVehicle()):Value.NULL);
|
||||||
put("unmountable", (e, a) -> new NumericValue(((EntityInterface)e).isPermanentVehicle()));
|
put("unmountable", (e, a) -> new NumericValue(((EntityInterface)e).isPermanentVehicle()));
|
||||||
|
// deprecated
|
||||||
put("tags", (e, a) -> ListValue.wrap(e.getScoreboardTags().stream().map(StringValue::new).collect(Collectors.toList())));
|
put("tags", (e, a) -> ListValue.wrap(e.getScoreboardTags().stream().map(StringValue::new).collect(Collectors.toList())));
|
||||||
|
|
||||||
|
put("scoreboard_tags", (e, a) -> ListValue.wrap(e.getScoreboardTags().stream().map(StringValue::new).collect(Collectors.toList())));
|
||||||
|
put("entity_tags", (e, a) -> ListValue.wrap(e.getServer().getTagManager().getEntityTypes().getTagsFor(e.getType()).stream().map(ValueConversions::of).collect(Collectors.toList())));
|
||||||
|
// deprecated
|
||||||
put("has_tag", (e, a) -> new NumericValue(e.getScoreboardTags().contains(a.getString())));
|
put("has_tag", (e, a) -> new NumericValue(e.getScoreboardTags().contains(a.getString())));
|
||||||
|
|
||||||
|
put("has_scoreboard_tag", (e, a) -> new NumericValue(e.getScoreboardTags().contains(a.getString())));
|
||||||
|
put("has_entity_tag", (e, a) -> {
|
||||||
|
net.minecraft.tag.Tag<EntityType<?>> tag = e.getServer().getTagManager().getEntityTypes().getTag(new Identifier(a.getString()));
|
||||||
|
if (tag == null) return Value.NULL;
|
||||||
|
return new NumericValue(e.getType().isIn(tag));
|
||||||
|
});
|
||||||
|
|
||||||
put("yaw", (e, a)-> new NumericValue(e.yaw));
|
put("yaw", (e, a)-> new NumericValue(e.yaw));
|
||||||
put("head_yaw", (e, a)-> {
|
put("head_yaw", (e, a)-> {
|
||||||
if (e instanceof LivingEntity)
|
if (e instanceof LivingEntity)
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String,ItemStackArgument> itemCache = new HashMap<>();
|
private static final Map<String,ItemStackArgument> itemCache = new HashMap<>();
|
||||||
|
|
||||||
public static ItemStackArgument parseItem(String itemString)
|
public static ItemStackArgument parseItem(String itemString)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user