Merge branch 'master' into future
# Conflicts: # gradle.properties # src/main/java/carpet/script/annotation/AnnotationParser.java # src/main/java/carpet/script/utils/BiomeInfo.java # src/main/resources/fabric.mod.json
This commit is contained in:
commit
529a5b358d
38 files changed
+247
-381
No files matched your search
@@ -2483,6 +2483,9 @@ is only effective if you set it at y=0, and affects the entire column of. In the
|
|||||||
specific Y coordinate of the biome you want to change, and it affects roughly 4x4x4 area (give or take some random
|
specific Y coordinate of the biome you want to change, and it affects roughly 4x4x4 area (give or take some random
|
||||||
noise).
|
noise).
|
||||||
|
|
||||||
|
This changed again in 1.18. The overworld behaves like the nether now, the biome must be set
|
||||||
|
for individual y coordinates.
|
||||||
|
|
||||||
Throws `unknown_biome` if the `biome_name` doesn't exist.
|
Throws `unknown_biome` if the `biome_name` doesn't exist.
|
||||||
|
|
||||||
### `update(pos)`
|
### `update(pos)`
|
||||||
@@ -2675,8 +2678,8 @@ With block, or name, returns the name of the biome in that position, or throws `
|
|||||||
Note: Have to pass all 6 of the mentioned noise types and only these noise types for it to evaluate a biome.
|
Note: Have to pass all 6 of the mentioned noise types and only these noise types for it to evaluate a biome.
|
||||||
|
|
||||||
With an optional feature, it returns value for the specified attribute for that biome. Available and queryable features include:
|
With an optional feature, it returns value for the specified attribute for that biome. Available and queryable features include:
|
||||||
* `'top_material'`: unlocalized block representing the top surface material
|
* `'top_material'`: unlocalized block representing the top surface material (1.17.1 and below only)
|
||||||
* `'under_material'`: unlocalized block representing what sits below topsoil
|
* `'under_material'`: unlocalized block representing what sits below topsoil (1.17.1 and below only)
|
||||||
* `'category'`: the parent biome this biome is derived from. Possible values include:
|
* `'category'`: the parent biome this biome is derived from. Possible values include:
|
||||||
`'none'`, `'taiga'`, `'extreme_hills'`, `'jungle'`, `'mesa'`, `'plains'`, `'savanna'`,
|
`'none'`, `'taiga'`, `'extreme_hills'`, `'jungle'`, `'mesa'`, `'plains'`, `'savanna'`,
|
||||||
`'icy'`, `'the_end'`, `'beach'`, `'forest'`, `'ocean'`, `'desert'`, `'river'`,
|
`'icy'`, `'the_end'`, `'beach'`, `'forest'`, `'ocean'`, `'desert'`, `'river'`,
|
||||||
|
|||||||
@@ -252,6 +252,8 @@ Decorators (listed as extra argument after the component they would affect):
|
|||||||
* `'^<format> <text>'` - hover over tooltip text, appearing when hovering with your mouse over the text below.
|
* `'^<format> <text>'` - hover over tooltip text, appearing when hovering with your mouse over the text below.
|
||||||
* `'?<suggestion>` - command suggestion - a message that will be pasted to chat when text below it is clicked.
|
* `'?<suggestion>` - command suggestion - a message that will be pasted to chat when text below it is clicked.
|
||||||
* `'!<message>'` - a chat message that will be executed when the text below it is clicked.
|
* `'!<message>'` - a chat message that will be executed when the text below it is clicked.
|
||||||
|
* `'@<url>'` - a URL that will be opened when the text below it is clicked.
|
||||||
|
* `'&<text>'` - a text that will be copied to clipboard when the text below it is clicked.
|
||||||
|
|
||||||
Both suggestions and messages can contain a command, which will be executed as a player that clicks it.
|
Both suggestions and messages can contain a command, which will be executed as a player that clicks it.
|
||||||
|
|
||||||
@@ -681,13 +683,13 @@ Fetches the value of a system property or returns all inforation as a map when c
|
|||||||
fetch various information, mostly not changing, or only available via low level
|
fetch various information, mostly not changing, or only available via low level
|
||||||
system calls. In all circumstances, these are only provided as read-only.
|
system calls. In all circumstances, these are only provided as read-only.
|
||||||
|
|
||||||
Available options in the scarpet app space:
|
##### Available options in the scarpet app space:
|
||||||
* `app_name` - current app name or `null` if its a default app
|
* `app_name` - current app name or `null` if its a default app
|
||||||
* `app_list` - list of all loaded apps excluding default commandline app
|
* `app_list` - list of all loaded apps excluding default commandline app
|
||||||
* `app_scope` - scope of the global variables and function. Available options is `player` and `global`
|
* `app_scope` - scope of the global variables and function. Available options is `player` and `global`
|
||||||
* `app_player` - returns a player list that have app run under them. For `global` apps, the list is always empty
|
* `app_players` - returns a player list that have app run under them. For `global` apps, the list is always empty
|
||||||
|
|
||||||
Relevant world related properties
|
##### Relevant world related properties
|
||||||
* `world_name` - name of the world
|
* `world_name` - name of the world
|
||||||
* `world_seed` - a numeric seed of the world
|
* `world_seed` - a numeric seed of the world
|
||||||
* `world_dimensions` - a list of dimensions in the world
|
* `world_dimensions` - a list of dimensions in the world
|
||||||
@@ -700,9 +702,10 @@ Available options in the scarpet app space:
|
|||||||
* `world_top` - Returns current dimensions' topmost Y value where one can place blocks.
|
* `world_top` - Returns current dimensions' topmost Y value where one can place blocks.
|
||||||
* `world_bottom` - Returns current dimensions' bottommost Y value where one can place blocks.
|
* `world_bottom` - Returns current dimensions' bottommost Y value where one can place blocks.
|
||||||
* `world_center` - Returns coordinates of the center of the world with respect of the world border
|
* `world_center` - Returns coordinates of the center of the world with respect of the world border
|
||||||
* `world_size` - Returns size of the world where at this distance from `world_center` world border appears.
|
* `world_size` - Returns radius of world border for current dimension.
|
||||||
|
* `world_max_size` - Returns maximum possible radius of world border for current dimension.
|
||||||
*
|
*
|
||||||
Relevant gameplay related properties
|
##### Relevant gameplay related properties
|
||||||
* `game_difficulty` - current difficulty of the game: `'peaceful'`, `'easy'`, `'normal'`, or `'hard'`
|
* `game_difficulty` - current difficulty of the game: `'peaceful'`, `'easy'`, `'normal'`, or `'hard'`
|
||||||
* `game_hardcore` - boolean whether the game is in hardcore mode
|
* `game_hardcore` - boolean whether the game is in hardcore mode
|
||||||
* `game_storage_format` - format of the world save files, either `'McRegion'` or `'Anvil'`
|
* `game_storage_format` - format of the world save files, either `'McRegion'` or `'Anvil'`
|
||||||
@@ -713,13 +716,13 @@ Available options in the scarpet app space:
|
|||||||
* `game_version` - base version of the game
|
* `game_version` - base version of the game
|
||||||
* `game_target` - target release version
|
* `game_target` - target release version
|
||||||
* `game_major_target` - major release target. For 1.12.2, that would be 12
|
* `game_major_target` - major release target. For 1.12.2, that would be 12
|
||||||
* `game_minor_reease` - minor release target. For 1.12.2, that woudl be 2
|
* `game_minor_release` - minor release target. For 1.12.2, that would be 2
|
||||||
* `game_protocol` - protocol version number
|
* `game_protocol` - protocol version number
|
||||||
* `game_pack_version` - datapack version number
|
* `game_pack_version` - datapack version number
|
||||||
* `game_data_version` - data version of the game. Returns an integer, so it can be compared.
|
* `game_data_version` - data version of the game. Returns an integer, so it can be compared.
|
||||||
* `game_stable` - indicating if its a production release or a snapshot
|
* `game_stable` - indicating if its a production release or a snapshot
|
||||||
|
|
||||||
Server related properties
|
##### Server related properties
|
||||||
* `server_motd` - the motd of the server visible when joining
|
* `server_motd` - the motd of the server visible when joining
|
||||||
* `server_ip` - IP adress of the game hosted
|
* `server_ip` - IP adress of the game hosted
|
||||||
* `server_whitelisted` - boolean indicating whether the access to the server is only for whitelisted players
|
* `server_whitelisted` - boolean indicating whether the access to the server is only for whitelisted players
|
||||||
@@ -734,7 +737,21 @@ list may refer to the previous tick performance. In this case the last entry (ti
|
|||||||
tick. For all intent and purpose, `system_info('last_tick_times'):0` should be used as last tick execution time, but
|
tick. For all intent and purpose, `system_info('last_tick_times'):0` should be used as last tick execution time, but
|
||||||
individual tick times may vary greatly, and these need to be taken with the little grain of averaging.
|
individual tick times may vary greatly, and these need to be taken with the little grain of averaging.
|
||||||
|
|
||||||
System related properties
|
##### Source related properties
|
||||||
|
|
||||||
|
The source is what is the cause of the code running, with Carpet using it same way as Minecraft commands use to run. Those are used in
|
||||||
|
some API functions that interact with the game or with commands, and can be manipulated if the execution is caused by an `execute` command, modified
|
||||||
|
by some functions or ran in non-standard ways. This section provides useful information from these cases (like running from a command
|
||||||
|
block, right clicking a sign, etc)
|
||||||
|
* `source_entity` - The entity associated with the execution. This is usually a player (in which case `player()` would get the entity from this),
|
||||||
|
but it may also be a different entity or `null` if the execution comes from the server console or a command block.
|
||||||
|
* `source_position` - The position associated with the execution. This is usually the position of the entity, but it may have been manipulated or
|
||||||
|
it could come from a command block (no entity then). If this call comes from the server console, it will be the world spawn.
|
||||||
|
* `source_dimension` - The dimension associated with the execution. Execution from the server console provides `overworld` as the dimension.
|
||||||
|
This can be manipulated by running code inside `in_dimension()`.
|
||||||
|
* `source_rotation` - The rotation associated with the execution. Usually `[0, 0]` in non-standard situations, the rotation of the entity otherwise.
|
||||||
|
|
||||||
|
##### System related properties
|
||||||
* `java_max_memory` - maximum allowed memory accessible by JVM
|
* `java_max_memory` - maximum allowed memory accessible by JVM
|
||||||
* `java_allocated_memory` - currently allocated memory by JVM
|
* `java_allocated_memory` - currently allocated memory by JVM
|
||||||
* `java_used_memory` - currently used memory by JVM
|
* `java_used_memory` - currently used memory by JVM
|
||||||
@@ -744,7 +761,7 @@ individual tick times may vary greatly, and these need to be taken with the litt
|
|||||||
* `java_system_cpu_load` - current percentage of CPU used by the system
|
* `java_system_cpu_load` - current percentage of CPU used by the system
|
||||||
* `java_process_cpu_load` - current percentage of CPU used by JVM
|
* `java_process_cpu_load` - current percentage of CPU used by JVM
|
||||||
|
|
||||||
Scarpet related properties
|
##### Scarpet related properties
|
||||||
* `scarpet_version` - returns the version of the carpet your scarpet comes with.
|
* `scarpet_version` - returns the version of the carpet your scarpet comes with.
|
||||||
|
|
||||||
## NBT Storage
|
## NBT Storage
|
||||||
|
|||||||
@@ -157,12 +157,11 @@ Throws `unknown_poi` if the provided point of interest doesn't exist
|
|||||||
### `set_biome(pos, biome_name, update=true)`
|
### `set_biome(pos, biome_name, update=true)`
|
||||||
|
|
||||||
Changes the biome at that block position. if update is specified and false, then chunk will not be refreshed
|
Changes the biome at that block position. if update is specified and false, then chunk will not be refreshed
|
||||||
on the clients. Biome changes can only be send to clients with the entire data from the chunk.
|
on the clients. Biome changes can only be sent to clients with the entire data from the chunk.
|
||||||
|
|
||||||
Setting a biome is now (as of 1.16) dimension specific. In the overworld and the end changing the biome
|
Be aware that depending on the MC version and dimension settings biome can be set either in a 1x1x256
|
||||||
is only effective if you set it at y=0, and affects the entire column of. In the nether - you have to use the
|
column or 4x4x4 hyperblock, so for some versions Y will be ignored and for some precision of biome
|
||||||
specific Y coordinate of the biome you want to change, and it affects roughly 4x4x4 area (give or take some random
|
setting is less than 1x1x1 block.
|
||||||
noise).
|
|
||||||
|
|
||||||
Throws `unknown_biome` if the `biome_name` doesn't exist.
|
Throws `unknown_biome` if the `biome_name` doesn't exist.
|
||||||
|
|
||||||
@@ -356,8 +355,8 @@ With block, or name, returns the name of the biome in that position, or throws `
|
|||||||
Note: Have to pass all 6 of the mentioned noise types and only these noise types for it to evaluate a biome.
|
Note: Have to pass all 6 of the mentioned noise types and only these noise types for it to evaluate a biome.
|
||||||
|
|
||||||
With an optional feature, it returns value for the specified attribute for that biome. Available and queryable features include:
|
With an optional feature, it returns value for the specified attribute for that biome. Available and queryable features include:
|
||||||
* `'top_material'`: unlocalized block representing the top surface material
|
* `'top_material'`: unlocalized block representing the top surface material (1.17.1 and below only)
|
||||||
* `'under_material'`: unlocalized block representing what sits below topsoil
|
* `'under_material'`: unlocalized block representing what sits below topsoil (1.17.1 and below only)
|
||||||
* `'category'`: the parent biome this biome is derived from. Possible values include:
|
* `'category'`: the parent biome this biome is derived from. Possible values include:
|
||||||
`'none'`, `'taiga'`, `'extreme_hills'`, `'jungle'`, `'mesa'`, `'plains'`, `'savanna'`,
|
`'none'`, `'taiga'`, `'extreme_hills'`, `'jungle'`, `'mesa'`, `'plains'`, `'savanna'`,
|
||||||
`'icy'`, `'the_end'`, `'beach'`, `'forest'`, `'ocean'`, `'desert'`, `'river'`,
|
`'icy'`, `'the_end'`, `'beach'`, `'forest'`, `'ocean'`, `'desert'`, `'river'`,
|
||||||
|
|||||||
@@ -202,13 +202,19 @@ List of entities riding the entity.
|
|||||||
|
|
||||||
Entity that `e` rides.
|
Entity that `e` rides.
|
||||||
|
|
||||||
### `query(e, 'scoreboard_tags')` and
|
### `(deprecated) query(e, 'tags')`
|
||||||
### `query(e, 'tags')`(deprecated)
|
|
||||||
|
Deprecated by `query(e, 'scoreboard_tags')`
|
||||||
|
|
||||||
|
### `query(e, 'scoreboard_tags')`
|
||||||
|
|
||||||
List of entity's scoreboard tags.
|
List of entity's scoreboard tags.
|
||||||
|
|
||||||
### `query(e, 'has_scoreboard_tag',tag)` and
|
### `(deprecated) query(e, 'has_tag',tag)`
|
||||||
### `query(e, 'has_tag',tag)`(deprecated)
|
|
||||||
|
Deprecated by `query(e, 'has_scoreboard_tag',tag)`
|
||||||
|
|
||||||
|
### `query(e, 'has_scoreboard_tag',tag)`
|
||||||
|
|
||||||
Boolean, true if the entity is marked with a `tag` scoreboad tag.
|
Boolean, true if the entity is marked with a `tag` scoreboad tag.
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ in a list and contain of map-like resources descriptors, looking like
|
|||||||
or a relative location in the same folder as the app in question (the relative location directly).
|
or a relative location in the same folder as the app in question (the relative location directly).
|
||||||
`'target'` points to the path in app data, or shared app data folder. If not specified it will place the app into the main data folder with the name it has.
|
`'target'` points to the path in app data, or shared app data folder. If not specified it will place the app into the main data folder with the name it has.
|
||||||
if `'shared'` is specified and `true`. When re-downloading the app, all resources will be re-downloaded as well.
|
if `'shared'` is specified and `true`. When re-downloading the app, all resources will be re-downloaded as well.
|
||||||
Currently, app resources are only downloaded when using `/carpet download` command.
|
Currently, app resources are only downloaded when using `/script download` command.
|
||||||
* `libraries` - list of libraries or apps to be downloaded when installing the app from the app store. It needs to be a list of map-like resource
|
* `libraries` - list of libraries or apps to be downloaded when installing the app from the app store. It needs to be a list of map-like resource
|
||||||
descriptors, like the above `resources` field.
|
descriptors, like the above `resources` field.
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ Or an example to find if a player has specific enchantment on a held axe (either
|
|||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
global_get_enchantment(p, ench) -> (
|
global_get_enchantment(p, ench) -> (
|
||||||
$ for(['main','offhand'],
|
$ for(['mainhand','offhand'],
|
||||||
$ holds = query(p, 'holds', _);
|
$ holds = query(p, 'holds', _);
|
||||||
$ if( holds,
|
$ if( holds,
|
||||||
$ [what, count, nbt] = holds;
|
$ [what, count, nbt] = holds;
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 41 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 105 KiB |
+1
-1
@@ -6,7 +6,7 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
# or better: https://modmuss50.me/fabric.html
|
# or better: https://modmuss50.me/fabric.html
|
||||||
minecraft_version=1.18
|
minecraft_version=1.18
|
||||||
yarn_mappings=1.18+build.1
|
yarn_mappings=1.18+build.1
|
||||||
loader_version=0.12.6
|
loader_version=0.12.12
|
||||||
fabric_version=0.43.1+1.18
|
fabric_version=0.43.1+1.18
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
|
|||||||
@@ -299,6 +299,9 @@ public class PlayerCommand
|
|||||||
{
|
{
|
||||||
// Force override flying to true for spectator players, or they will fell out of the world.
|
// Force override flying to true for spectator players, or they will fell out of the world.
|
||||||
flying = true;
|
flying = true;
|
||||||
|
} else if(mode.isSurvivalLike()){
|
||||||
|
// Force override flying to false for survival-like players, or they will fly too
|
||||||
|
flying = false;
|
||||||
}
|
}
|
||||||
String playerName = StringArgumentType.getString(context, "player");
|
String playerName = StringArgumentType.getString(context, "player");
|
||||||
if (playerName.length()>maxPlayerLength(source.getServer()))
|
if (playerName.length()>maxPlayerLength(source.getServer()))
|
||||||
|
|||||||
@@ -51,10 +51,10 @@ public class TickCommand
|
|||||||
then(literal("deep").executes( (c)-> setFreeze(c.getSource(), true, true)))).
|
then(literal("deep").executes( (c)-> setFreeze(c.getSource(), true, true)))).
|
||||||
then(literal("off").executes( (c) -> setFreeze(c.getSource(), false, false)))).
|
then(literal("off").executes( (c) -> setFreeze(c.getSource(), false, false)))).
|
||||||
then(literal("step").
|
then(literal("step").
|
||||||
executes((c) -> step(1)).
|
executes((c) -> step(c.getSource(), 1)).
|
||||||
then(argument("ticks", integer(1,72000)).
|
then(argument("ticks", integer(1,72000)).
|
||||||
suggests( (c, b) -> suggestMatching(new String[]{"20"},b)).
|
suggests( (c, b) -> suggestMatching(new String[]{"20"},b)).
|
||||||
executes((c) -> step(getInteger(c,"ticks"))))).
|
executes((c) -> step(c.getSource(), getInteger(c,"ticks"))))).
|
||||||
then(literal("superHot").executes( (c)-> toggleSuperHot(c.getSource()))).
|
then(literal("superHot").executes( (c)-> toggleSuperHot(c.getSource()))).
|
||||||
then(literal("health").
|
then(literal("health").
|
||||||
executes( (c) -> healthReport(c.getSource(), 100)).
|
executes( (c) -> healthReport(c.getSource(), 100)).
|
||||||
@@ -130,9 +130,10 @@ public class TickCommand
|
|||||||
return setFreeze(source, isDeep, !TickSpeed.isPaused());
|
return setFreeze(source, isDeep, !TickSpeed.isPaused());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int step(int advance)
|
private static int step(ServerCommandSource source, int advance)
|
||||||
{
|
{
|
||||||
TickSpeed.add_ticks_to_run_in_pause(advance);
|
TickSpeed.add_ticks_to_run_in_pause(advance);
|
||||||
|
Messenger.m(source, "gi Stepping " + advance + " tick" + (advance != 1 ? "s" : ""));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package carpet.fakes;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface BiomeEffectsInterface
|
|
||||||
{
|
|
||||||
int getCMFogColor();
|
|
||||||
Optional<Integer> getCMFoliageColor();
|
|
||||||
int getCMSkyColor();
|
|
||||||
int getCMWaterColor();
|
|
||||||
int getCMWaterFogColor();
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package carpet.fakes;
|
|
||||||
|
|
||||||
import net.minecraft.entity.ai.brain.Memory;
|
|
||||||
import net.minecraft.entity.ai.brain.MemoryModuleType;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface BrainInterface
|
|
||||||
{
|
|
||||||
Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> getMobMemories();
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,5 @@ package carpet.fakes;
|
|||||||
|
|
||||||
public interface ItemEntityInterface
|
public interface ItemEntityInterface
|
||||||
{
|
{
|
||||||
int getAgeCM();
|
|
||||||
int getPickupDelayCM();
|
int getPickupDelayCM();
|
||||||
}
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package carpet.fakes;
|
|
||||||
|
|
||||||
public interface MemoryInterface
|
|
||||||
{
|
|
||||||
long getScarpetExpiry();
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package carpet.mixins;
|
|
||||||
|
|
||||||
import carpet.fakes.BiomeEffectsInterface;
|
|
||||||
import net.minecraft.world.biome.BiomeEffects;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Mixin(BiomeEffects.class)
|
|
||||||
public class BiomeEffects_scarpetMixin implements BiomeEffectsInterface
|
|
||||||
{
|
|
||||||
@Shadow @Final private int fogColor;
|
|
||||||
|
|
||||||
@Shadow @Final private Optional<Integer> foliageColor;
|
|
||||||
|
|
||||||
@Shadow @Final private int skyColor;
|
|
||||||
|
|
||||||
@Shadow @Final private int waterColor;
|
|
||||||
|
|
||||||
@Shadow @Final private int waterFogColor;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCMFogColor()
|
|
||||||
{
|
|
||||||
return fogColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Integer> getCMFoliageColor()
|
|
||||||
{
|
|
||||||
return foliageColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCMSkyColor()
|
|
||||||
{
|
|
||||||
return skyColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCMWaterColor()
|
|
||||||
{
|
|
||||||
return waterColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCMWaterFogColor()
|
|
||||||
{
|
|
||||||
return waterFogColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package carpet.mixins;
|
|
||||||
|
|
||||||
import carpet.fakes.BrainInterface;
|
|
||||||
import net.minecraft.entity.ai.brain.Brain;
|
|
||||||
import net.minecraft.entity.ai.brain.Memory;
|
|
||||||
import net.minecraft.entity.ai.brain.MemoryModuleType;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Mixin(Brain.class)
|
|
||||||
public class Brain_Mixin implements BrainInterface
|
|
||||||
{
|
|
||||||
|
|
||||||
@Shadow @Final private Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> memories;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> getMobMemories()
|
|
||||||
{
|
|
||||||
return memories;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -42,11 +42,6 @@ public abstract class ItemEntityMixin extends Entity implements ItemEntityInterf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAgeCM() {
|
|
||||||
return this.itemAge;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPickupDelayCM() {
|
public int getPickupDelayCM() {
|
||||||
return this.pickupDelay;
|
return this.pickupDelay;
|
||||||
@@ -105,7 +100,7 @@ public abstract class ItemEntityMixin extends Entity implements ItemEntityInterf
|
|||||||
self.setStack(selfStack);
|
self.setStack(selfStack);
|
||||||
|
|
||||||
this.pickupDelay = Math.max(((ItemEntityInterface)other).getPickupDelayCM(), this.pickupDelay);
|
this.pickupDelay = Math.max(((ItemEntityInterface)other).getPickupDelayCM(), this.pickupDelay);
|
||||||
this.itemAge = Math.min(((ItemEntityInterface)other).getAgeCM(), this.itemAge);
|
this.itemAge = Math.min(other.getItemAge(), this.itemAge);
|
||||||
|
|
||||||
otherStack.decrement(amount);
|
otherStack.decrement(amount);
|
||||||
if (otherStack.isEmpty())
|
if (otherStack.isEmpty())
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package carpet.mixins;
|
|
||||||
|
|
||||||
import carpet.fakes.MemoryInterface;
|
|
||||||
import net.minecraft.entity.ai.brain.Memory;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
@Mixin(Memory.class)
|
|
||||||
public class Memory_scarpetMixin implements MemoryInterface
|
|
||||||
{
|
|
||||||
@Shadow private long expiry;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getScarpetExpiry()
|
|
||||||
{
|
|
||||||
return expiry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.fakes.BrainInterface;
|
|
||||||
import carpet.fakes.MemoryInterface;
|
|
||||||
import carpet.helpers.ParticleDisplay;
|
import carpet.helpers.ParticleDisplay;
|
||||||
import carpet.utils.Messenger;
|
import carpet.utils.Messenger;
|
||||||
import carpet.utils.MobAI;
|
import carpet.utils.MobAI;
|
||||||
@@ -65,14 +63,14 @@ public abstract class VillagerEntity_aiMixin extends MerchantEntity
|
|||||||
if (MobAI.isTracking(this, MobAI.TrackingType.IRON_GOLEM_SPAWNING))
|
if (MobAI.isTracking(this, MobAI.TrackingType.IRON_GOLEM_SPAWNING))
|
||||||
{
|
{
|
||||||
long time;
|
long time;
|
||||||
Optional<? extends Memory<?>> last_seen = ((BrainInterface)this.brain).getMobMemories().get(MemoryModuleType.GOLEM_DETECTED_RECENTLY);
|
Optional<? extends Memory<?>> last_seen = this.brain.getMemories().get(MemoryModuleType.GOLEM_DETECTED_RECENTLY);
|
||||||
if (!last_seen.isPresent())
|
if (!last_seen.isPresent())
|
||||||
{
|
{
|
||||||
time = 0;
|
time = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
time = ((MemoryInterface)last_seen.get()).getScarpetExpiry();
|
time = last_seen.get().getExpiry();
|
||||||
}
|
}
|
||||||
boolean recentlySeen = time > 0;
|
boolean recentlySeen = time > 0;
|
||||||
Optional<Long> optional_11 = this.brain.getOptionalMemory(MemoryModuleType.LAST_SLEPT);
|
Optional<Long> optional_11 = this.brain.getOptionalMemory(MemoryModuleType.LAST_SLEPT);
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class CarpetExpression
|
|||||||
public Value scriptRunCommand(ScriptHost host, BlockPos pos)
|
public Value scriptRunCommand(ScriptHost host, BlockPos pos)
|
||||||
{
|
{
|
||||||
if (CarpetServer.scriptServer.stopAll)
|
if (CarpetServer.scriptServer.stopAll)
|
||||||
throw new CarpetExpressionException("SCRIPTING PAUSED", null);
|
throw new CarpetExpressionException("SCRIPTING PAUSED (unpause with /script resume)", null);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Context context = new CarpetContext(host, source, origin).
|
Context context = new CarpetContext(host, source, origin).
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import carpet.script.exception.ExpressionException;
|
|||||||
import carpet.script.exception.IntegrityException;
|
import carpet.script.exception.IntegrityException;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.exception.InvalidCallbackException;
|
import carpet.script.exception.InvalidCallbackException;
|
||||||
|
import carpet.script.exception.LoadException;
|
||||||
import carpet.script.utils.AppStoreManager;
|
import carpet.script.utils.AppStoreManager;
|
||||||
import carpet.script.value.EntityValue;
|
import carpet.script.value.EntityValue;
|
||||||
import carpet.script.value.FunctionValue;
|
import carpet.script.value.FunctionValue;
|
||||||
@@ -37,6 +38,7 @@ import net.fabricmc.loader.api.ModContainer;
|
|||||||
import net.fabricmc.loader.api.SemanticVersion;
|
import net.fabricmc.loader.api.SemanticVersion;
|
||||||
import net.fabricmc.loader.api.Version;
|
import net.fabricmc.loader.api.Version;
|
||||||
import net.fabricmc.loader.api.VersionParsingException;
|
import net.fabricmc.loader.api.VersionParsingException;
|
||||||
|
import net.fabricmc.loader.api.metadata.version.VersionPredicate;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.nbt.NbtElement;
|
import net.minecraft.nbt.NbtElement;
|
||||||
@@ -60,7 +62,6 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -119,8 +120,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
String code = module.getCode();
|
String code = module.getCode();
|
||||||
if (code == null)
|
if (code == null)
|
||||||
{
|
{
|
||||||
Messenger.m(source, "r Unable to load "+module.getName()+" app - code not found");
|
throw new LoadException("Code not found");
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
host.setChatErrorSnooper(source);
|
host.setChatErrorSnooper(source);
|
||||||
CarpetExpression ex = new CarpetExpression(host.main, code, source, new BlockPos(0, 0, 0));
|
CarpetExpression ex = new CarpetExpression(host.main, code, source, new BlockPos(0, 0, 0));
|
||||||
@@ -131,13 +131,12 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
catch (CarpetExpressionException e)
|
catch (CarpetExpressionException e)
|
||||||
{
|
{
|
||||||
host.handleErrorWithStack("Error while evaluating expression", e);
|
host.handleErrorWithStack("Error while evaluating expression", e);
|
||||||
host.resetErrorSnooper();
|
throw new LoadException();
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
catch (ArithmeticException ae)
|
catch (ArithmeticException ae) // is this branch ever reached? Seems like arithmetic exceptions are converted to CEEs earlier
|
||||||
{
|
{
|
||||||
host.handleErrorWithStack("Math doesn't compute", ae);
|
host.handleErrorWithStack("Math doesn't compute", ae);
|
||||||
return null;
|
throw new LoadException();
|
||||||
}
|
}
|
||||||
catch (StackOverflowError soe)
|
catch (StackOverflowError soe)
|
||||||
{
|
{
|
||||||
@@ -314,7 +313,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
Value reqResult = callNow((FunctionValue) loadRequirements, Collections.emptyList());
|
Value reqResult = callNow((FunctionValue) loadRequirements, Collections.emptyList());
|
||||||
if (reqResult.getBoolean()) // != false or null
|
if (reqResult.getBoolean()) // != false or null
|
||||||
throw new InternalExpressionException(reqResult.getString());
|
throw new LoadException(reqResult.getString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -422,20 +421,6 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
return addLegacyCommand(notifier);
|
return addLegacyCommand(notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefixes based on FLoader's SemanticVersionPredicateParser's class prefixes under Apache 2.0, since that's not public API
|
|
||||||
private static final Map<String, BiPredicate<SemanticVersion, SemanticVersion>> VERSION_PREFIXES = new HashMap<String, BiPredicate<SemanticVersion, SemanticVersion>>() {{
|
|
||||||
put(">=", (target, source) -> source.compareTo(target) >= 0);
|
|
||||||
put("<=", (target, source) -> source.compareTo(target) <= 0);
|
|
||||||
put(">", (target, source) -> source.compareTo(target) > 0);
|
|
||||||
put("<", (target, source) -> source.compareTo(target) < 0);
|
|
||||||
put("=", (target, source) -> source.compareTo(target) == 0);
|
|
||||||
put("~", (target, source) -> source.compareTo(target) >= 0
|
|
||||||
&& source.getVersionComponent(0) == target.getVersionComponent(0)
|
|
||||||
&& source.getVersionComponent(1) == target.getVersionComponent(1));
|
|
||||||
put("^", (target, source) -> source.compareTo(target) >= 0
|
|
||||||
&& source.getVersionComponent(0) == target.getVersionComponent(0));
|
|
||||||
}};
|
|
||||||
|
|
||||||
public void checkModVersionRequirements(Value reqs) {
|
public void checkModVersionRequirements(Value reqs) {
|
||||||
if (reqs == null)
|
if (reqs == null)
|
||||||
return;
|
return;
|
||||||
@@ -446,58 +431,25 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
Map<Value, Value> requirements = ((MapValue)reqs).getMap();
|
Map<Value, Value> requirements = ((MapValue)reqs).getMap();
|
||||||
for (Entry<Value, Value> requirement : requirements.entrySet())
|
for (Entry<Value, Value> requirement : requirements.entrySet())
|
||||||
{
|
{
|
||||||
boolean successful = false;
|
|
||||||
String requiredModId = requirement.getKey().getString();
|
String requiredModId = requirement.getKey().getString();
|
||||||
String requirementString = requirement.getValue().getString();
|
String stringPredicate = requirement.getValue().getString();
|
||||||
|
VersionPredicate predicate;
|
||||||
|
try {
|
||||||
|
predicate = VersionPredicate.parse(stringPredicate);
|
||||||
|
} catch (VersionParsingException e) {
|
||||||
|
throw new InternalExpressionException("Failed to parse version conditions for '" + requiredModId + "' in 'requires': " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
ModContainer mod = FabricLoader.getInstance().getModContainer(requiredModId).orElse(null);
|
ModContainer mod = FabricLoader.getInstance().getModContainer(requiredModId).orElse(null);
|
||||||
if (mod != null)
|
if (mod != null)
|
||||||
{
|
{
|
||||||
if (requirementString.equals("*"))
|
|
||||||
continue;
|
|
||||||
Version presentVersion = mod.getMetadata().getVersion();
|
Version presentVersion = mod.getMetadata().getVersion();
|
||||||
BiPredicate<SemanticVersion, SemanticVersion> tester = null;
|
if (predicate.test(presentVersion) || (FabricLoader.getInstance().isDevelopmentEnvironment() && !(presentVersion instanceof SemanticVersion)))
|
||||||
String remainingRequirementString = requirementString;
|
{ // in a dev env, mod version is usually replaced with ${version}, and that isn't semantic
|
||||||
for (Entry<String, BiPredicate<SemanticVersion, SemanticVersion>> s : VERSION_PREFIXES.entrySet())
|
continue;
|
||||||
{
|
|
||||||
if (requirementString.startsWith(s.getKey()))
|
|
||||||
{
|
|
||||||
tester = s.getValue();
|
|
||||||
remainingRequirementString = requirementString.substring(s.getKey().length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tester == null)
|
|
||||||
tester = VERSION_PREFIXES.get("=");
|
|
||||||
if (presentVersion instanceof SemanticVersion)
|
|
||||||
{
|
|
||||||
SemanticVersion requiredVersion = null;
|
|
||||||
try {
|
|
||||||
requiredVersion = SemanticVersion.parse(remainingRequirementString);
|
|
||||||
}
|
|
||||||
catch (VersionParsingException e)
|
|
||||||
{
|
|
||||||
throw new InternalExpressionException("Failed to parse semantic version for '" + requiredModId + "' in 'requires': " + e.getMessage());
|
|
||||||
}
|
|
||||||
if (tester.test(requiredVersion, (SemanticVersion) presentVersion))
|
|
||||||
successful = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (FabricLoader.getInstance().isDevelopmentEnvironment())
|
|
||||||
successful = true; // Autoversioning breaks semver in dev (loads as ${version})
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(tester == VERSION_PREFIXES.get("=")))
|
|
||||||
throw new InternalExpressionException("Mod '"+requiredModId+"' doesn't use semversion, thus can only check version equality");
|
|
||||||
if (presentVersion.getFriendlyString().equals(remainingRequirementString))
|
|
||||||
successful = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!successful)
|
throw new LoadException(String.format("%s requires a version of mod '%s' matching '%s', which is missing!", getName(), requiredModId, stringPredicate));
|
||||||
{
|
|
||||||
throw new InternalExpressionException(getName()+" requires " + requiredModId + " version " + requirementString + " in order to load");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,10 +684,10 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
public Value callLegacy(ServerCommandSource source, String call, List<Integer> coords, String arg)
|
public Value callLegacy(ServerCommandSource source, String call, List<Integer> coords, String arg)
|
||||||
{
|
{
|
||||||
if (CarpetServer.scriptServer.stopAll)
|
if (CarpetServer.scriptServer.stopAll)
|
||||||
throw new CarpetExpressionException("SCARPET PAUSED", null);
|
throw new CarpetExpressionException("SCARPET PAUSED (unpause with /script resume)", null);
|
||||||
FunctionValue function = getFunction(call);
|
FunctionValue function = getFunction(call);
|
||||||
if (function == null)
|
if (function == null)
|
||||||
throw new CarpetExpressionException("UNDEFINED", null);
|
throw new CarpetExpressionException("Couldn't find function '" + call + "' in app '" + this.getName() + "'", null);
|
||||||
List<LazyValue> argv = new ArrayList<>();
|
List<LazyValue> argv = new ArrayList<>();
|
||||||
if (coords != null)
|
if (coords != null)
|
||||||
for (Integer i: coords)
|
for (Integer i: coords)
|
||||||
@@ -832,7 +784,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
public Value call(ServerCommandSource source, FunctionValue function, List<Value> argv)
|
public Value call(ServerCommandSource source, FunctionValue function, List<Value> argv)
|
||||||
{
|
{
|
||||||
if (CarpetServer.scriptServer.stopAll)
|
if (CarpetServer.scriptServer.stopAll)
|
||||||
throw new CarpetExpressionException("SCARPET PAUSED", null);
|
throw new CarpetExpressionException("SCARPET PAUSED (unpause with /script resume)", null);
|
||||||
|
|
||||||
List<String> args = function.getArguments();
|
List<String> args = function.getArguments();
|
||||||
if (argv.size() != args.size())
|
if (argv.size() != args.size())
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import carpet.CarpetServer;
|
|||||||
import carpet.script.bundled.FileModule;
|
import carpet.script.bundled.FileModule;
|
||||||
import carpet.script.bundled.Module;
|
import carpet.script.bundled.Module;
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
|
import carpet.script.exception.LoadException;
|
||||||
import carpet.script.language.Arithmetic;
|
import carpet.script.language.Arithmetic;
|
||||||
import carpet.script.language.ControlFlow;
|
import carpet.script.language.ControlFlow;
|
||||||
import carpet.script.language.DataStructures;
|
import carpet.script.language.DataStructures;
|
||||||
@@ -256,10 +257,14 @@ public class CarpetScriptServer
|
|||||||
Messenger.m(source, "r Failed to add "+name+" app");
|
Messenger.m(source, "r Failed to add "+name+" app");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CarpetScriptHost newHost = CarpetScriptHost.create(this, module, perPlayer, source, commandValidator, isRuleApp, installer);
|
CarpetScriptHost newHost;
|
||||||
if (newHost == null)
|
try
|
||||||
{
|
{
|
||||||
Messenger.m(source, "r Failed to add "+name+" app");
|
newHost = CarpetScriptHost.create(this, module, perPlayer, source, commandValidator, isRuleApp, installer);
|
||||||
|
}
|
||||||
|
catch (LoadException e)
|
||||||
|
{
|
||||||
|
Messenger.m(source, "r Failed to add " + name + " app" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// config needs to be read as we load the app since some events use that info
|
// config needs to be read as we load the app since some events use that info
|
||||||
|
|||||||
@@ -481,9 +481,9 @@ public class Expression
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addLazyFunction(String name, int num_params, TriFunction<Context, Context.Type, List<LazyValue>, LazyValue> fun)
|
public void addLazyFunction(String name, int numParams, TriFunction<Context, Context.Type, List<LazyValue>, LazyValue> fun)
|
||||||
{
|
{
|
||||||
functions.put(name, new AbstractLazyFunction(num_params, name)
|
functions.put(name, new AbstractLazyFunction(numParams, name)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public boolean pure() {
|
public boolean pure() {
|
||||||
@@ -499,8 +499,11 @@ public class Expression
|
|||||||
public LazyValue lazyEval(Context c, Context.Type i, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
public LazyValue lazyEval(Context c, Context.Type i, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||||
{
|
{
|
||||||
ILazyFunction.checkInterrupts();
|
ILazyFunction.checkInterrupts();
|
||||||
if (num_params >= 0 && lazyParams.size() != num_params)
|
if (numParams >= 0 && lazyParams.size() != numParams)
|
||||||
throw new InternalExpressionException("'"+name+"' requires "+num_params+" parameters, "+lazyParams.size()+" provided.");
|
{
|
||||||
|
String error = "Function '"+name+"' requires "+numParams+" arguments, got "+lazyParams.size()+". ";
|
||||||
|
throw new InternalExpressionException(error + (fun instanceof Fluff.UsageProvider up ? up.getUsage() : ""));
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ public abstract class Fluff
|
|||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface SexFunction<A, B, C, D, E, F, R> { R apply(A a, B b, C c, D d, E e, F f);}
|
public interface SexFunction<A, B, C, D, E, F, R> { R apply(A a, B b, C c, D d, E e, F f);}
|
||||||
|
|
||||||
|
public interface UsageProvider { String getUsage();}
|
||||||
|
|
||||||
public interface EvalNode
|
public interface EvalNode
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import carpet.script.Context;
|
|||||||
import carpet.script.Expression;
|
import carpet.script.Expression;
|
||||||
import carpet.script.Fluff.AbstractLazyFunction;
|
import carpet.script.Fluff.AbstractLazyFunction;
|
||||||
import carpet.script.Fluff.TriFunction;
|
import carpet.script.Fluff.TriFunction;
|
||||||
|
import carpet.script.Fluff.UsageProvider;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.LazyValue;
|
import carpet.script.LazyValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
@@ -73,6 +74,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|||||||
*/
|
*/
|
||||||
public final class AnnotationParser
|
public final class AnnotationParser
|
||||||
{
|
{
|
||||||
|
static final int UNDEFINED_PARAMS = -2;
|
||||||
private static final List<ParsedFunction> functionList = new ArrayList<>();
|
private static final List<ParsedFunction> functionList = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,8 +92,8 @@ public final class AnnotationParser
|
|||||||
* {@link InternalExpressionException}).
|
* {@link InternalExpressionException}).
|
||||||
* Basically, it's fine as long as you don't add a {@code throws} declaration to your methods.</li>
|
* Basically, it's fine as long as you don't add a {@code throws} declaration to your methods.</li>
|
||||||
* <li>Varargs (or effectively varargs) annotated methods must explicitly declare a maximum number of parameters to ingest in the {@link ScarpetFunction}
|
* <li>Varargs (or effectively varargs) annotated methods must explicitly declare a maximum number of parameters to ingest in the {@link ScarpetFunction}
|
||||||
* annotation. They can still declare an unlimited amount by setting that maximum to {@code -1}. "Effectively varargs" means a function that has
|
* annotation. They can still declare an unlimited amount by setting that maximum to {@link ScarpetFunction#UNLIMITED_PARAMS}. "Effectively varargs"
|
||||||
* a parameter using/requiring a {@link ValueConverter} that has declared {@link ValueConverter#consumesVariableArgs()}.</li>
|
* means a function that has at least a parameter requiring a {@link ValueConverter} that has declared {@link ValueConverter#consumesVariableArgs()}.</li>
|
||||||
* <li>Annotated methods must not have a parameter with generics as the varargs parameter. This is just because it was painful for me (altrisi) and
|
* <li>Annotated methods must not have a parameter with generics as the varargs parameter. This is just because it was painful for me (altrisi) and
|
||||||
* didn't want to support it. Those will crash with a {@code ClassCastException}</li>
|
* didn't want to support it. Those will crash with a {@code ClassCastException}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
@@ -141,7 +143,7 @@ public final class AnnotationParser
|
|||||||
expr.addLazyFunction(function.name, function.scarpetParamCount, function);
|
expr.addLazyFunction(function.name, function.scarpetParamCount, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ParsedFunction implements TriFunction<Context, Context.Type, List<LazyValue>, LazyValue>
|
private static class ParsedFunction implements TriFunction<Context, Context.Type, List<LazyValue>, LazyValue>, UsageProvider
|
||||||
{
|
{
|
||||||
private final String name;
|
private final String name;
|
||||||
private final boolean isMethodVarArgs;
|
private final boolean isMethodVarArgs;
|
||||||
@@ -186,10 +188,10 @@ public final class AnnotationParser
|
|||||||
if (this.isEffectivelyVarArgs)
|
if (this.isEffectivelyVarArgs)
|
||||||
{
|
{
|
||||||
maxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
|
maxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
|
||||||
if (maxParams == -2)
|
if (maxParams == UNDEFINED_PARAMS)
|
||||||
throw new IllegalArgumentException("No maximum number of params specified for " + name + ", use -1 for unlimited. "
|
throw new IllegalArgumentException("No maximum number of params specified for " + name + ", use ScarpetFunction.UNLIMITED_PARAMS for unlimited. "
|
||||||
+ "Provided in " + instance.getClass());
|
+ "Provided in " + instance.getClass());
|
||||||
if (maxParams == -1)
|
if (maxParams == ScarpetFunction.UNLIMITED_PARAMS)
|
||||||
maxParams = Integer.MAX_VALUE;
|
maxParams = Integer.MAX_VALUE;
|
||||||
if (maxParams < this.minParams)
|
if (maxParams < this.minParams)
|
||||||
throw new IllegalArgumentException("Provided maximum number of params for " + name + " is smaller than method's param count."
|
throw new IllegalArgumentException("Provided maximum number of params for " + name + " is smaller than method's param count."
|
||||||
@@ -293,7 +295,8 @@ public final class AnnotationParser
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUsage()
|
@Override
|
||||||
|
public String getUsage()
|
||||||
{
|
{
|
||||||
// Possibility: More descriptive messages using param.getName()? Would need changing gradle setup to keep those
|
// Possibility: More descriptive messages using param.getName()? Would need changing gradle setup to keep those
|
||||||
StringBuilder builder = new StringBuilder("Usage: '");
|
StringBuilder builder = new StringBuilder("Usage: '");
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ import carpet.script.value.Value;
|
|||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
public @interface ScarpetFunction
|
public @interface ScarpetFunction
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* <p>Used to define that this {@link ScarpetFunction} can accept an unlimited number of parameters</p>
|
||||||
|
*/
|
||||||
|
public static final int UNLIMITED_PARAMS = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>If the function can accept a variable number of parameters, either by declaring its last parameter as a varargs parameter or by having one
|
* <p>If the function can accept a variable number of parameters, either by declaring its last parameter as a varargs parameter or by having one
|
||||||
* of their parameters use a converter that consumes a variable number of arguments, this must define the maximum number of parameters this
|
* of their parameters use a converter that consumes a variable number of arguments, this must define the maximum number of parameters this
|
||||||
@@ -65,11 +70,11 @@ public @interface ScarpetFunction
|
|||||||
* consider that those can take either a single triple of values or 3 independent values, that would be counted in the maximum number of
|
* consider that those can take either a single triple of values or 3 independent values, that would be counted in the maximum number of
|
||||||
* parameters.</p>
|
* parameters.</p>
|
||||||
*
|
*
|
||||||
* <p>Use -1 to specify an unlimited number of parameters.</p>
|
* <p>Use {@link ScarpetFunction#UNLIMITED_PARAMS} to allow an unlimited number of parameters.</p>
|
||||||
*
|
*
|
||||||
* @return The maximum number of parameters this function can accept
|
* @return The maximum number of parameters this function can accept
|
||||||
*/
|
*/
|
||||||
int maxParams() default -2;
|
int maxParams() default AnnotationParser.UNDEFINED_PARAMS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Defines the Context Type that will be used when evaluating arguments to annotated methods.</p>
|
* <p>Defines the Context Type that will be used when evaluating arguments to annotated methods.</p>
|
||||||
|
|||||||
@@ -162,13 +162,13 @@ public interface ValueConverter<R>
|
|||||||
* constraints as {@link #convert(Value)}</p>
|
* constraints as {@link #convert(Value)}</p>
|
||||||
* @param valueIterator An {@link Iterator} holding the {@link Value} to convert in next position
|
* @param valueIterator An {@link Iterator} holding the {@link Value} to convert in next position
|
||||||
* @param context The {@link Context} this function has been called with. This was used when this passed lazy values instead in order to
|
* @param context The {@link Context} this function has been called with. This was used when this passed lazy values instead in order to
|
||||||
* evaluate, now it's used to get the context. It is now ignored by the default implementation
|
* evaluate, now it's used to get the context
|
||||||
* @param theLazyT The {@code t} that the original function was called with. It is ignored by the default implementation.
|
* @param contextType The {@link Context.Type} that the original function was called with
|
||||||
* @return The next {@link Value} (s) converted to the type {@code <R>} of this {@link ValueConverter}
|
* @return The next {@link Value} (s) converted to the type {@code <R>} of this {@link ValueConverter}
|
||||||
* @implNote This method's default implementation runs the {@link #convert(Value)} function in the next {@link Value} ignoring {@link Context} and
|
* @implNote This method's default implementation runs the {@link #convert(Value)} function in the next {@link Value} ignoring {@link Context} and
|
||||||
* {@code theLazyT}.
|
* {@code theLazyT}.
|
||||||
*/
|
*/
|
||||||
default public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
default public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type contextType)
|
||||||
{
|
{
|
||||||
if (!valueIterator.hasNext())
|
if (!valueIterator.hasNext())
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -676,7 +676,7 @@ public class Auxiliary {
|
|||||||
expression.addContextFunction("last_tick_times", -1, (c, t, lv) ->
|
expression.addContextFunction("last_tick_times", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
c.host.issueDeprecation("last_tick_times()");
|
c.host.issueDeprecation("last_tick_times()");
|
||||||
return SystemInfo.get("last_tick_times", (CarpetContext)c);
|
return SystemInfo.get("server_last_tick_times", (CarpetContext)c);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -736,6 +736,7 @@ public class Auxiliary {
|
|||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Should this be deprecated for system_info('source_dimension')?
|
||||||
expression.addContextFunction("current_dimension", 0, (c, t, lv) ->
|
expression.addContextFunction("current_dimension", 0, (c, t, lv) ->
|
||||||
ValueConversions.of( ((CarpetContext)c).s.getWorld()));
|
ValueConversions.of( ((CarpetContext)c).s.getWorld()));
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package carpet.script.api;
|
|||||||
import carpet.script.CarpetContext;
|
import carpet.script.CarpetContext;
|
||||||
import carpet.script.CarpetEventServer;
|
import carpet.script.CarpetEventServer;
|
||||||
import carpet.script.CarpetScriptHost;
|
import carpet.script.CarpetScriptHost;
|
||||||
|
import carpet.script.Context;
|
||||||
import carpet.script.Expression;
|
import carpet.script.Expression;
|
||||||
import carpet.script.argument.FunctionArgument;
|
import carpet.script.argument.FunctionArgument;
|
||||||
import carpet.script.argument.Vector3Argument;
|
import carpet.script.argument.Vector3Argument;
|
||||||
@@ -36,9 +37,20 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class Entities {
|
public class Entities {
|
||||||
|
private static ListValue getPlayersFromWorldMatching(Context c, Predicate<ServerPlayerEntity> condition) {
|
||||||
|
List<Value> ret = new ArrayList<>();
|
||||||
|
for (ServerPlayerEntity player: ((CarpetContext) c).s.getWorld().getPlayers()) {
|
||||||
|
if (condition.test(player)) {
|
||||||
|
ret.add(new EntityValue(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ListValue.wrap(ret);
|
||||||
|
}
|
||||||
|
|
||||||
public static void apply(Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
expression.addContextFunction("player", -1, (c, t, lv) ->
|
expression.addContextFunction("player", -1, (c, t, lv) ->
|
||||||
@@ -58,50 +70,26 @@ public class Entities {
|
|||||||
return EntityValue.of(closestPlayer);
|
return EntityValue.of(closestPlayer);
|
||||||
}
|
}
|
||||||
String playerName = lv.get(0).getString();
|
String playerName = lv.get(0).getString();
|
||||||
Value retval = Value.NULL;
|
return switch (playerName) {
|
||||||
if ("all".equalsIgnoreCase(playerName))
|
case "all" -> {
|
||||||
{
|
List<Value> ret = new ArrayList<>();
|
||||||
retval = ListValue.wrap(
|
for (ServerPlayerEntity player: ((CarpetContext)c).s.getServer().getPlayerManager().getPlayerList())
|
||||||
((CarpetContext)c).s.getServer().getPlayerManager().getPlayerList().
|
ret.add(new EntityValue(player));
|
||||||
stream().map(EntityValue::new).collect(Collectors.toList()));
|
yield ListValue.wrap(ret);
|
||||||
}
|
}
|
||||||
else if ("*".equalsIgnoreCase(playerName))
|
case "*" -> getPlayersFromWorldMatching(c, p -> true);
|
||||||
{
|
case "survival" -> getPlayersFromWorldMatching(c, p -> p.interactionManager.isSurvivalLike());
|
||||||
retval = ListValue.wrap(
|
case "creative" -> getPlayersFromWorldMatching(c, PlayerEntity::isCreative);
|
||||||
((CarpetContext)c).s.getWorld().getPlayers().
|
case "spectating" -> getPlayersFromWorldMatching(c, PlayerEntity::isSpectator);
|
||||||
stream().map(EntityValue::new).collect(Collectors.toList()));
|
case "!spectating" -> getPlayersFromWorldMatching(c, p -> !p.isSpectator());
|
||||||
}
|
default -> {
|
||||||
else if ("survival".equalsIgnoreCase(playerName))
|
ServerPlayerEntity player = ((CarpetContext) c).s.getServer().getPlayerManager().getPlayer(playerName);
|
||||||
{
|
if (player != null) {
|
||||||
retval = ListValue.wrap(
|
yield new EntityValue(player);
|
||||||
((CarpetContext)c).s.getWorld().getPlayers((p) -> p.interactionManager.isSurvivalLike()).
|
}
|
||||||
stream().map(EntityValue::new).collect(Collectors.toList()));
|
yield Value.NULL;
|
||||||
}
|
}
|
||||||
else if ("creative".equalsIgnoreCase(playerName))
|
};
|
||||||
{
|
|
||||||
retval = ListValue.wrap(
|
|
||||||
((CarpetContext)c).s.getWorld().getPlayers(PlayerEntity::isCreative).
|
|
||||||
stream().map(EntityValue::new).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
else if ("spectating".equalsIgnoreCase(playerName))
|
|
||||||
{
|
|
||||||
retval = ListValue.wrap(
|
|
||||||
((CarpetContext)c).s.getWorld().getPlayers(PlayerEntity::isSpectator).
|
|
||||||
stream().map(EntityValue::new).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
else if ("!spectating".equalsIgnoreCase(playerName))
|
|
||||||
{
|
|
||||||
retval = ListValue.wrap(
|
|
||||||
((CarpetContext)c).s.getWorld().getPlayers((p) -> !p.isSpectator()).
|
|
||||||
stream().map(EntityValue::new).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ServerPlayerEntity player = ((CarpetContext) c).s.getServer().getPlayerManager().getPlayer(playerName);
|
|
||||||
if (player != null)
|
|
||||||
retval = new EntityValue(player);
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("spawn", -1, (c, t, lv) ->
|
expression.addContextFunction("spawn", -1, (c, t, lv) ->
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package carpet.script.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Scarpet exception that indicates that load of the app has failed.
|
||||||
|
*
|
||||||
|
* Goes up the stack to the point of app load and gets caught there, preventing the app from loading with
|
||||||
|
* the given message.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LoadException extends RuntimeException implements ResolvedException {
|
||||||
|
|
||||||
|
public LoadException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoadException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,9 +8,7 @@ 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 carpet.script.value.ValueConversions;
|
||||||
import net.minecraft.client.color.world.FoliageColors;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||||
@@ -27,11 +25,11 @@ public class BiomeInfo
|
|||||||
//put("under_material", (w, b) -> new BlockValue( b.getGenerationSettings().getSurfaceConfig().getUnderMaterial(), null, null));
|
//put("under_material", (w, b) -> new BlockValue( b.getGenerationSettings().getSurfaceConfig().getUnderMaterial(), null, null));
|
||||||
put("category", (w, b) -> StringValue.of(b.getCategory().getName()));
|
put("category", (w, b) -> StringValue.of(b.getCategory().getName()));
|
||||||
put("temperature", (w, b) -> NumericValue.of(b.getTemperature()));
|
put("temperature", (w, b) -> NumericValue.of(b.getTemperature()));
|
||||||
put("fog_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMFogColor()));
|
put("fog_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getFogColor()));
|
||||||
put("foliage_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMFoliageColor().orElse(4764952))); // client Biome.getDefaultFoliageColor
|
put("foliage_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getFoliageColor().orElse(4764952))); // client Biome.getDefaultFoliageColor
|
||||||
put("sky_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMSkyColor()));
|
put("sky_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getSkyColor()));
|
||||||
put("water_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMWaterColor()));
|
put("water_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getWaterColor()));
|
||||||
put("water_fog_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMWaterFogColor()));
|
put("water_fog_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getWaterFogColor()));
|
||||||
put("humidity", (w, b) -> NumericValue.of(b.getDownfall()));
|
put("humidity", (w, b) -> NumericValue.of(b.getDownfall()));
|
||||||
put("precipitation", (w, b) -> StringValue.of(b.getPrecipitation().getName()));
|
put("precipitation", (w, b) -> StringValue.of(b.getPrecipitation().getName()));
|
||||||
//put("depth", (w, b) -> NumericValue.of(b.getDepth()));
|
//put("depth", (w, b) -> NumericValue.of(b.getDepth()));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import carpet.CarpetSettings;
|
|||||||
import carpet.script.CarpetContext;
|
import carpet.script.CarpetContext;
|
||||||
import carpet.script.CarpetScriptHost;
|
import carpet.script.CarpetScriptHost;
|
||||||
import carpet.script.value.BooleanValue;
|
import carpet.script.value.BooleanValue;
|
||||||
|
import carpet.script.value.EntityValue;
|
||||||
import carpet.script.value.ListValue;
|
import carpet.script.value.ListValue;
|
||||||
import carpet.script.value.MapValue;
|
import carpet.script.value.MapValue;
|
||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
@@ -17,11 +18,9 @@ import com.sun.management.OperatingSystemMXBean;
|
|||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.fabricmc.loader.api.ModContainer;
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.WorldSavePath;
|
import net.minecraft.util.WorldSavePath;
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
import net.minecraft.util.math.Vec2f;
|
||||||
import net.minecraft.world.GameRules;
|
import net.minecraft.world.GameRules;
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.WorldProperties;
|
import net.minecraft.world.WorldProperties;
|
||||||
import net.minecraft.world.border.WorldBorder;
|
import net.minecraft.world.border.WorldBorder;
|
||||||
|
|
||||||
@@ -74,7 +73,9 @@ public class SystemInfo {
|
|||||||
return ListValue.fromTriple(worldBorder.getCenterX(), 0, worldBorder.getCenterZ());
|
return ListValue.fromTriple(worldBorder.getCenterX(), 0, worldBorder.getCenterZ());
|
||||||
});
|
});
|
||||||
|
|
||||||
put("world_size", c-> new NumericValue( c.s.getWorld().getWorldBorder().getMaxRadius()));
|
put("world_size", c -> new NumericValue(c.s.getWorld().getWorldBorder().getSize() / 2));
|
||||||
|
|
||||||
|
put("world_max_size", c-> new NumericValue( c.s.getWorld().getWorldBorder().getMaxRadius()));
|
||||||
|
|
||||||
put("world_time", c -> new NumericValue(c.s.getWorld().getTime()));
|
put("world_time", c -> new NumericValue(c.s.getWorld().getTime()));
|
||||||
|
|
||||||
@@ -199,6 +200,15 @@ public class SystemInfo {
|
|||||||
});
|
});
|
||||||
return MapValue.wrap(rules);
|
return MapValue.wrap(rules);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
put("source_entity", c -> EntityValue.of(c.s.getEntity()));
|
||||||
|
put("source_position", c -> ValueConversions.of(c.s.getPosition()));
|
||||||
|
put("source_dimension", c -> ValueConversions.of(c.s.getWorld()));
|
||||||
|
put("source_rotation", c -> {
|
||||||
|
Vec2f rotation = c.s.getRotation();
|
||||||
|
return ListValue.of(new NumericValue(rotation.x), new NumericValue(rotation.y));
|
||||||
|
});
|
||||||
|
|
||||||
put("scarpet_version", c -> StringValue.of(CarpetSettings.carpetVersion));
|
put("scarpet_version", c -> StringValue.of(CarpetSettings.carpetVersion));
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
import carpet.fakes.BrainInterface;
|
|
||||||
import carpet.fakes.EntityInterface;
|
import carpet.fakes.EntityInterface;
|
||||||
import carpet.fakes.ItemEntityInterface;
|
import carpet.fakes.ItemEntityInterface;
|
||||||
import carpet.fakes.LivingEntityInterface;
|
import carpet.fakes.LivingEntityInterface;
|
||||||
import carpet.fakes.MemoryInterface;
|
|
||||||
import carpet.fakes.MobEntityInterface;
|
import carpet.fakes.MobEntityInterface;
|
||||||
import carpet.fakes.ServerPlayerEntityInterface;
|
import carpet.fakes.ServerPlayerEntityInterface;
|
||||||
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
||||||
@@ -633,11 +631,11 @@ public class EntityValue extends Value
|
|||||||
if (e instanceof LivingEntity livingEntity)
|
if (e instanceof LivingEntity livingEntity)
|
||||||
{
|
{
|
||||||
Brain<?> brain = livingEntity.getBrain();
|
Brain<?> brain = livingEntity.getBrain();
|
||||||
Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> memories = ((BrainInterface)brain).getMobMemories();
|
Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> memories = brain.getMemories();
|
||||||
Optional<? extends Memory<?>> optmemory = memories.get(moduleType);
|
Optional<? extends Memory<?>> optmemory = memories.get(moduleType);
|
||||||
if (optmemory==null || !optmemory.isPresent()) return Value.NULL;
|
if (optmemory==null || !optmemory.isPresent()) return Value.NULL;
|
||||||
Memory<?> memory = optmemory.get();
|
Memory<?> memory = optmemory.get();
|
||||||
return ValueConversions.fromTimedMemory(e, ((MemoryInterface)memory).getScarpetExpiry(), memory.getValue());
|
return ValueConversions.fromTimedMemory(e, memory.getExpiry(), memory.getValue());
|
||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
});
|
});
|
||||||
@@ -1584,7 +1582,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("absorption", (e, v) -> {
|
put("absorption", (e, v) -> {
|
||||||
if (e instanceof PlayerEntity) ((PlayerEntity) e).setAbsorptionAmount((float) NumericValue.asNumber(v, "absorbtion").getLong());
|
if (e instanceof PlayerEntity) ((PlayerEntity) e).setAbsorptionAmount(NumericValue.asNumber(v, "absorbtion").getFloat());
|
||||||
});
|
});
|
||||||
|
|
||||||
put("add_xp", (e, v) -> {
|
put("add_xp", (e, v) -> {
|
||||||
|
|||||||
@@ -19,18 +19,29 @@ public class ThreadValue extends Value
|
|||||||
private final long id;
|
private final long id;
|
||||||
private static long sequence = 0L;
|
private static long sequence = 0L;
|
||||||
|
|
||||||
|
public ThreadValue(CompletableFuture<Value> taskFuture)
|
||||||
|
{
|
||||||
|
this.taskFuture = taskFuture;
|
||||||
|
this.id = sequence++;
|
||||||
|
}
|
||||||
|
|
||||||
public ThreadValue(Value pool, FunctionValue function, Expression expr, Tokenizer.Token token, Context ctx, List<Value> args)
|
public ThreadValue(Value pool, FunctionValue function, Expression expr, Tokenizer.Token token, Context ctx, List<Value> args)
|
||||||
{
|
{
|
||||||
id = sequence++;
|
this(getCompletableFutureFromFunction(pool, function, expr, token, ctx, args));
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompletableFuture<Value> getCompletableFutureFromFunction(Value pool, FunctionValue function, Expression expr, Tokenizer.Token token, Context ctx, List<Value> args)
|
||||||
|
{
|
||||||
ExecutorService executor = ctx.host.getExecutor(pool);
|
ExecutorService executor = ctx.host.getExecutor(pool);
|
||||||
if (executor == null)
|
if (executor == null)
|
||||||
{
|
{
|
||||||
// app is shutting down - no more threads can be spawned.
|
// app is shutting down - no more threads can be spawned.
|
||||||
taskFuture = CompletableFuture.completedFuture(Value.NULL);
|
return CompletableFuture.completedFuture(Value.NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
taskFuture = CompletableFuture.supplyAsync(
|
return CompletableFuture.supplyAsync(
|
||||||
() ->
|
() ->
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -52,7 +63,6 @@ public class ThreadValue extends Value
|
|||||||
ctx.host.getExecutor(pool)
|
ctx.host.getExecutor(pool)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Thread.yield();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -103,23 +103,18 @@ public class Messenger
|
|||||||
}
|
}
|
||||||
public static String creatureTypeColor(SpawnGroup type)
|
public static String creatureTypeColor(SpawnGroup type)
|
||||||
{
|
{
|
||||||
switch (type)
|
return switch (type)
|
||||||
{
|
{
|
||||||
case MONSTER:
|
case MONSTER -> "n";
|
||||||
return "n";
|
case CREATURE -> "e";
|
||||||
case CREATURE:
|
case AMBIENT -> "f";
|
||||||
return "e";
|
case WATER_CREATURE -> "v";
|
||||||
case AMBIENT:
|
case WATER_AMBIENT -> "q";
|
||||||
return "f";
|
default -> "w"; // missing MISC and UNDERGROUND_WATER_CREATURE
|
||||||
case WATER_CREATURE:
|
};
|
||||||
return "v";
|
|
||||||
case WATER_AMBIENT:
|
|
||||||
return "q";
|
|
||||||
}
|
|
||||||
return "w";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BaseText _getChatComponentFromDesc(String message, BaseText previous_message)
|
private static BaseText getChatComponentFromDesc(String message, BaseText previousMessage)
|
||||||
{
|
{
|
||||||
if (message.equalsIgnoreCase(""))
|
if (message.equalsIgnoreCase(""))
|
||||||
{
|
{
|
||||||
@@ -127,7 +122,7 @@ public class Messenger
|
|||||||
}
|
}
|
||||||
if (Character.isWhitespace(message.charAt(0)))
|
if (Character.isWhitespace(message.charAt(0)))
|
||||||
{
|
{
|
||||||
message = "w"+message;
|
message = "w" + message;
|
||||||
}
|
}
|
||||||
int limit = message.indexOf(' ');
|
int limit = message.indexOf(' ');
|
||||||
String desc = message;
|
String desc = message;
|
||||||
@@ -137,52 +132,37 @@ public class Messenger
|
|||||||
desc = message.substring(0, limit);
|
desc = message.substring(0, limit);
|
||||||
str = message.substring(limit+1);
|
str = message.substring(limit+1);
|
||||||
}
|
}
|
||||||
if (desc.charAt(0) == '/') // deprecated
|
if (previousMessage == null) {
|
||||||
{
|
BaseText text = new LiteralText(str);
|
||||||
if (previous_message != null)
|
text.setStyle(parseStyle(desc));
|
||||||
previous_message.setStyle(
|
return text;
|
||||||
previous_message.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, message))
|
|
||||||
);
|
|
||||||
return previous_message;
|
|
||||||
}
|
}
|
||||||
if (desc.charAt(0) == '?')
|
Style previousStyle = previousMessage.getStyle();
|
||||||
{
|
BaseText ret = previousMessage;
|
||||||
if (previous_message != null)
|
previousMessage.setStyle(switch (desc.charAt(0)) {
|
||||||
previous_message.setStyle(
|
case '?' -> previousStyle.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, message.substring(1)));
|
||||||
previous_message.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, message.substring(1)))
|
case '!' -> previousStyle.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, message.substring(1)));
|
||||||
);
|
case '^' -> previousStyle.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, c(message.substring(1))));
|
||||||
return previous_message;
|
case '@' -> previousStyle.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, message.substring(1)));
|
||||||
}
|
case '&' -> previousStyle.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, message.substring(1)));
|
||||||
if (desc.charAt(0) == '!')
|
default -> { // Create a new component
|
||||||
{
|
ret = new LiteralText(str);
|
||||||
if (previous_message != null)
|
ret.setStyle(parseStyle(desc));
|
||||||
previous_message.setStyle(
|
yield previousStyle; // no op for the previous style
|
||||||
previous_message.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, message.substring(1)))
|
}
|
||||||
);
|
});
|
||||||
return previous_message;
|
return ret;
|
||||||
}
|
|
||||||
if (desc.charAt(0) == '^')
|
|
||||||
{
|
|
||||||
if (previous_message != null)
|
|
||||||
previous_message.setStyle(
|
|
||||||
previous_message.getStyle().withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, c(message.substring(1))))
|
|
||||||
);
|
|
||||||
return previous_message;
|
|
||||||
}
|
|
||||||
BaseText txt = new LiteralText(str);
|
|
||||||
txt.setStyle(parseStyle(desc));
|
|
||||||
return txt;
|
|
||||||
}
|
}
|
||||||
public static BaseText tp(String desc, Vec3d pos) { return tp(desc, pos.x, pos.y, pos.z); }
|
public static BaseText tp(String desc, Vec3d pos) { return tp(desc, pos.x, pos.y, pos.z); }
|
||||||
public static BaseText tp(String desc, BlockPos pos) { return tp(desc, pos.getX(), pos.getY(), pos.getZ()); }
|
public static BaseText tp(String desc, BlockPos pos) { return tp(desc, pos.getX(), pos.getY(), pos.getZ()); }
|
||||||
public static BaseText tp(String desc, double x, double y, double z) { return tp(desc, (float)x, (float)y, (float)z);}
|
public static BaseText tp(String desc, double x, double y, double z) { return tp(desc, (float)x, (float)y, (float)z);}
|
||||||
public static BaseText tp(String desc, float x, float y, float z)
|
public static BaseText tp(String desc, float x, float y, float z)
|
||||||
{
|
{
|
||||||
return _getCoordsTextComponent(desc, x, y, z, false);
|
return getCoordsTextComponent(desc, x, y, z, false);
|
||||||
}
|
}
|
||||||
public static BaseText tp(String desc, int x, int y, int z)
|
public static BaseText tp(String desc, int x, int y, int z)
|
||||||
{
|
{
|
||||||
return _getCoordsTextComponent(desc, (float)x, (float)y, (float)z, true);
|
return getCoordsTextComponent(desc, (float)x, (float)y, (float)z, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// to be continued
|
/// to be continued
|
||||||
@@ -232,7 +212,7 @@ public class Messenger
|
|||||||
return c(components.toArray(new Object[0]));
|
return c(components.toArray(new Object[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BaseText _getCoordsTextComponent(String style, float x, float y, float z, boolean isInt)
|
private static BaseText getCoordsTextComponent(String style, float x, float y, float z, boolean isInt)
|
||||||
{
|
{
|
||||||
String text;
|
String text;
|
||||||
String command;
|
String command;
|
||||||
@@ -266,19 +246,19 @@ public class Messenger
|
|||||||
public static BaseText c(Object ... fields)
|
public static BaseText c(Object ... fields)
|
||||||
{
|
{
|
||||||
BaseText message = new LiteralText("");
|
BaseText message = new LiteralText("");
|
||||||
BaseText previous_component = null;
|
BaseText previousComponent = null;
|
||||||
for (Object o: fields)
|
for (Object o: fields)
|
||||||
{
|
{
|
||||||
if (o instanceof BaseText)
|
if (o instanceof BaseText)
|
||||||
{
|
{
|
||||||
message.append((BaseText)o);
|
message.append((BaseText)o);
|
||||||
previous_component = (BaseText)o;
|
previousComponent = (BaseText)o;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String txt = o.toString();
|
String txt = o.toString();
|
||||||
BaseText comp = _getChatComponentFromDesc(txt,previous_component);
|
BaseText comp = getChatComponentFromDesc(txt, previousComponent);
|
||||||
if (comp != previous_component) message.append(comp);
|
if (comp != previousComponent) message.append(comp);
|
||||||
previous_component = comp;
|
previousComponent = comp;
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,8 +67,6 @@
|
|||||||
"EntityTrackerEntry_leashFixMixin",
|
"EntityTrackerEntry_leashFixMixin",
|
||||||
|
|
||||||
"VillagerEntity_aiMixin",
|
"VillagerEntity_aiMixin",
|
||||||
"Brain_Mixin",
|
|
||||||
"Memory_scarpetMixin",
|
|
||||||
|
|
||||||
"PlayerEntity_fakePlayersMixin",
|
"PlayerEntity_fakePlayersMixin",
|
||||||
"ThrownEnderpearlEntity_fakePlayersMixin",
|
"ThrownEnderpearlEntity_fakePlayersMixin",
|
||||||
@@ -190,7 +188,6 @@
|
|||||||
"Team_scarpetMixin",
|
"Team_scarpetMixin",
|
||||||
"TradeOutputSlot_scarpetEventMixin",
|
"TradeOutputSlot_scarpetEventMixin",
|
||||||
|
|
||||||
"BiomeEffects_scarpetMixin",
|
|
||||||
"ChunkTicketManager_scarpetMixin",
|
"ChunkTicketManager_scarpetMixin",
|
||||||
"PointOfInterest_scarpetMixin",
|
"PointOfInterest_scarpetMixin",
|
||||||
"ServerWorld_scarpetMixin",
|
"ServerWorld_scarpetMixin",
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
"depends": {
|
"depends": {
|
||||||
"minecraft": "1.18.x",
|
"minecraft": "1.18.x",
|
||||||
"fabricloader": ">=0.11.6",
|
"fabricloader": ">=0.12.8",
|
||||||
"java": ">=17"
|
"java": ">=17"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user