diff --git a/gradle.properties b/gradle.properties index d5a3f651..17fa2a32 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.4.8+build.155 # Mod Properties - mod_version = 1.0.0+v190714 + mod_version = 1.0.0+v190721 maven_group = carpet archives_base_name = fabric-carpet diff --git a/src/main/java/carpet/commands/CameraModeCommand.java b/src/main/java/carpet/commands/CameraModeCommand.java index ab2af25f..1fb69827 100644 --- a/src/main/java/carpet/commands/CameraModeCommand.java +++ b/src/main/java/carpet/commands/CameraModeCommand.java @@ -4,11 +4,13 @@ import carpet.settings.CarpetSettings; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.client.network.packet.EntityVelocityUpdateS2CPacket; +import net.minecraft.client.network.packet.RemoveEntityEffectS2CPacket; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.command.arguments.EntityArgumentType; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.world.GameMode; import static net.minecraft.server.command.CommandManager.argument; @@ -35,7 +37,7 @@ public class CameraModeCommand dispatcher.register(camera); dispatcher.register(survival); } - private static boolean iCanHasPermissions(ServerCommandSource source, PlayerEntity player) + private static boolean iCanHasPermissions(ServerCommandSource source, ServerPlayerEntity player) { try { @@ -46,19 +48,23 @@ public class CameraModeCommand return true; // shoudn't happen because server has all permissions anyways } } - private static int cameraMode(ServerCommandSource source, PlayerEntity player) + private static int cameraMode(ServerCommandSource source, ServerPlayerEntity player) { if (!(iCanHasPermissions(source, player))) return 0; player.setGameMode(GameMode.SPECTATOR); + player.addVelocity(0,0.1,0); + player.networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(player)); player.addPotionEffect(new StatusEffectInstance(StatusEffects.NIGHT_VISION, 999999, 0, false, false)); player.addPotionEffect(new StatusEffectInstance(StatusEffects.CONDUIT_POWER, 999999, 0, false, false)); return 1; } - private static int survivalMode(ServerCommandSource source, PlayerEntity player) + private static int survivalMode(ServerCommandSource source, ServerPlayerEntity player) { if (!(iCanHasPermissions(source, player))) return 0; player.setGameMode(GameMode.SURVIVAL); + player.networkHandler.sendPacket(new RemoveEntityEffectS2CPacket(player.getEntityId(), StatusEffects.NIGHT_VISION)); player.removePotionEffect(StatusEffects.NIGHT_VISION); + player.networkHandler.sendPacket(new RemoveEntityEffectS2CPacket(player.getEntityId(), StatusEffects.CONDUIT_POWER)); player.removePotionEffect(StatusEffects.CONDUIT_POWER); return 1; } diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 8b3b4482..523e1dd2 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -307,6 +307,46 @@ public class CarpetExpression } } + public boolean tryBreakBlock_copy_from_ServerPlayerInteractionManager(ServerPlayerEntity player, BlockPos blockPos_1) + { + //this could be done little better, by hooking up event handling not in try_break_block but wherever its called + // so we can safely call it here + // but that woudl do for now. + BlockState blockState_1 = player.world.getBlockState(blockPos_1); + if (!player.getMainHandStack().getItem().canMine(blockState_1, player.world, blockPos_1, player)) { + return false; + } else { + BlockEntity blockEntity_1 = player.world.getBlockEntity(blockPos_1); + Block block_1 = blockState_1.getBlock(); + if ((block_1 instanceof CommandBlock || block_1 instanceof StructureBlock || block_1 instanceof JigsawBlock) && !player.isCreativeLevelTwoOp()) { + player.world.updateListeners(blockPos_1, blockState_1, blockState_1, 3); + return false; + } else if (player.method_21701(player.world, blockPos_1, player.interactionManager.getGameMode())) { + return false; + } else { + block_1.onBreak(player.world, blockPos_1, blockState_1, player); + boolean boolean_1 = player.world.clearBlockState(blockPos_1, false); + if (boolean_1) { + block_1.onBroken(player.world, blockPos_1, blockState_1); + } + + if (player.isCreative()) { + return true; + } else { + ItemStack itemStack_1 = player.getMainHandStack(); + boolean boolean_2 = player.isUsingEffectiveTool(blockState_1); + itemStack_1.postMine(player.world, blockState_1, blockPos_1, player); + if (boolean_1 && boolean_2) { + ItemStack itemStack_2 = itemStack_1.isEmpty() ? ItemStack.EMPTY : itemStack_1.copy(); + block_1.afterBreak(player.world, player, blockPos_1, blockState_1, blockEntity_1, itemStack_2); + } + + return true; + } + } + } + } + /** *
random_tick(pos)Causes a random tick at position.
*destroy(pos), destroy(pos, -1), destroy(pos, <N>)Destroys the block like it was harvest by a player. Add -1 for silk touch, and positive number for fortune level.
+ *Destroys the block like it was mined by a player. Add -1 for silk touch, and positive number for fortune level. + * This function, unlike harvest, will affect all kinds of blocks
*harvest(player, pos)Causes a block to be harvested by a specified player entity. Honors player item enchantments, as well as damages the - * tool if applicable. If the entity is not a valid player, no block gets destroyed.
- * + * tool if applicable. If the entity is not a valid player, no block gets destroyed. If a player is not allowed to + * break that block, a block doesn't get destroyed either. * *block_properties(pos)Returns a list of available block properties for a particular block. If a block has no properties, returns an empty list.
*property(pos, name)Returns property of block at pos, or specified by block argument. If a block doesn't
* have that property, null value is returned. Returned values are always strings. It is expected from
@@ -438,19 +481,19 @@ public class CarpetExpression
*
blast_resistance(pos)Numeric function, indicating blast_resistance of a block.
- *top(type, x, z)Returns the Y value of the topmost block at given x, z coords, according to the + *
top(type, pos)Returns the Y value of the topmost block at given x, z coords (y value of a block is not important), according to the
* heightmap specified by type. Valid options are:
light: topmost light blocking blocklight: topmost light blocking block (1.13 only)motion: topmost motion blocking blockterrain: topmost motion blocking block except leavesocean_floor: topmost non-water blocksurface: topmost surface block
- * top('motion', x, z) => 63
- * top('ocean_floor', x, z) => 41
+ * top('motion', x, y, z) => 63
+ * top('ocean_floor', x, y, z) => 41
*
* loaded(pos)Boolean function, true if the block is loaded. Normally scarpet doesn't check if operates on
@@ -857,39 +900,16 @@ public class CarpetExpression
if (!(e instanceof ServerPlayerEntity))
return (c_, t_) -> Value.FALSE;
ServerPlayerEntity player = (ServerPlayerEntity)e;
-
BlockValue.LocatorResult locator = BlockValue.fromParams(cc, lv, 1);
- BlockState state = locator.block.getBlockState();
BlockPos where = locator.block.getPos();
- BlockEntity be = world.getBlockEntity(where);
+ BlockState state = locator.block.getBlockState();
Block block = state.getBlock();
- if ((block instanceof CommandBlock || block instanceof StructureBlock || block instanceof JigsawBlock) && !player.isCreativeLevelTwoOp())
- return LazyValue.FALSE;
- if ((block instanceof BedrockBlock || block instanceof BarrierBlock) && player.interactionManager.isSurvivalLike())
- return LazyValue.FALSE;
- if (player.method_21701(world, where, player.interactionManager.getGameMode()))
- return LazyValue.FALSE;
-
- state.getBlock().onBreak(world,where, state, player);
-
- boolean removedActualBlock = world.clearBlockState(where, false);
- if (removedActualBlock)
- {
- block.onBroken(world, where, state);
- }
- world.playLevelEvent(null, 2001, where, Block.getRawIdFromState(state));
- if (player.interactionManager.isCreative())
- return LazyValue.TRUE;
-
- ItemStack itemStack_1 = player.getMainHandStack();
- boolean couldMineIt = player.isUsingEffectiveTool(state);
- itemStack_1.postMine(world, state, where, player);
- if (removedActualBlock && couldMineIt)
- {
- ItemStack itemStack_2 = itemStack_1.isEmpty() ? ItemStack.EMPTY : itemStack_1.copy();
- block.afterBreak(world, player, where, state, be, itemStack_2);
- }
- return LazyValue.TRUE;
+ boolean success = false;
+ if (!((block instanceof BedrockBlock || block instanceof BarrierBlock) && player.interactionManager.isSurvivalLike()))
+ success = tryBreakBlock_copy_from_ServerPlayerInteractionManager(player, where);
+ if (success)
+ world.playLevelEvent(null, 2001, where, Block.getRawIdFromState(state));
+ return success ? LazyValue.TRUE : LazyValue.FALSE;
});
this.expr.addLazyFunction("place_item", -1, (c, t, lv) ->
@@ -1362,6 +1382,11 @@ public class CarpetExpression
*
Returns entities satisfying given vanilla entity selector. Most complex among all the methods of selecting * entities, but the most capable. Selectors are cached so should be as fast as other methods of selecting entities.
* + *spawn(name, pos, nbt?)Spawns and places an entity in world, like /summon vanilla command.
+ * Requires a position to spawn, and optional extra nbt data to merge with the entity. What makes it different from calling
+ * run('summon ...'), is the fact that you get the entity back as a return value, which is swell.
Unlike with blocks, that use plethora of vastly different querying functions, entities are queried with @@ -1394,6 +1419,8 @@ public class CarpetExpression *
Respective entity coordinate
*query(e,'pitch'), query(e,'yaw')Pitch and Yaw or where entity is looking.
+ *query(e,'look')Returns a 3d vector where the entity is looking.
*query(e,'motion')Triple of entity motion vector, l(motion_x, motion_y, motion_z)
query(e,'motion_x'), query(e,'motion_y'), query(e,'motion_z')query(e,'health')Number indicating remaining entity health, or null if not applicable.
query(e,'holds',slot?)Returns triple of short name, stack count, and NBT of item held in slot.
* Available options for slot are:
query(e,'facing', order?)Returns where the entity is facing. optional order (number from 0 to 5, and negative), indicating * primary directions where entity is looking at. From most prominent (order 0) to opposite (order 5, or -1)
- * + *query(e,'trace', reach?, options?...)Returns the result of ray tracing from entity perspective, indicating what it is looking at. Default reach is 4.5
+ * blocks (5 for creative players), and by default it traces for blocks and entities, identical to player attack tracing action.
+ * This can be customized with options, use 'blocks' to trace for blocks only, 'liquids' to include liquid blocks
+ * as possible results, and 'entities' to trace entities as well.
Regardless of the options selected, the result could be null if nothing is in reach, entity, if look
+ * targets an antity, and block value if block is in reach. Tracing always hits blocks. Even if an entity tracing is requested
+ * and there is a block in the way - the block will be returned.
query(e,'nbt',path?)Returns full NBT of the entity. If path is specified, it fetches only that portion of the NBT,
* that corresponds to the path. For specification of path attribute, consult
@@ -1523,8 +1558,7 @@ public class CarpetExpression
*
modify(e, 'accelerate', x, y, z), modify(e, 'accelerate', l(x, y, z) )Adds a vector to the motion vector. Most realistic way to apply a force to an entity.
*modify(e, 'custom_name'), modify(e, 'custom_name', name )Sets a custom name for an entity. No argument sets it empty, not removes it. Vanilla doesn't allow removing - * of attributes.
+ *Sets a custom name for an entity. Removes a custom name if the argument is null
modify(e, 'dismount')Dismounts riding entity.
*modify(e, 'mount', other)particle_rect(name, pos, pos2, density?)Renders a cuboid of particles between point pos to pos2 with supplied density.
nbt(expr)Treats the argument as a nbt serializable string and returns its nbt value. + * In case nbt is not in a correct nbt compound tag format, the execution of a script will stop with an error, + * whenever that tag is used.
*print(expr)Displays the result of the expression to the chat. Overrides default scarpet behaviour of
* sending everyting to stderr.
/script load / unload <module> (shared?), /script in <module> commandsload / unload commands allow for very conventient way of writing your code, providing it to the game
+ * and distribute with your worlds without the need of use of commandblocks. Just place your scarpet code in the /scripts
+ * folder of your world files and make sure it ends with .sc extension. The good thing about editing that
+ * code is that you can no only use normal editing without the need of marking of newlines, but you can also use
+ * comments in your code.
a comment is anything that starts with a double slash, and continues to the end of the line:
+ *+ * foo = 1; + * //This is a comment + * bar = 2; + * // This never worked, so I commented it out + * // baz = foo() + *+ * + *
/script load/unload <module> (?shared) Loading operation will load that script code from disk and execute it right away. You would probably use it to
+ * load some stored procedures to be used for later. To reload the module, just type /script load again.
+ * Reloading removes all the current global state (globals and functions) that were added later by the module.
Loading a module, if it contains a __command() method, will attempt to registed a command with that
+ * module name, and register all public (no underscore) functions available in the module as subcommands. It will also
+ * bind specific events to the event system (check Events section for details).
Unloading a module removes all of its state from the game, disables commands, and removes bounded events
+ *Scripts can be loaded in shared and player mode. Default is player, so all globals and stored functions are
+ * individual for each player, meaning scripts don't need to worry about making sure they store some intermittent data
+ * for each player independently. In shared mode - all global values and stored functions are shared among all players.
+ * To access specific player data with commandblocks, use /execute as (player) run script in (module) run ...
+ * To access global/server state, you need to disown the command from any player, so use a commandblock, or any arbitrary
+ * entity: /execute as @e[type=bat,limit=1] run script in (module) globals for instance.
+ *
/script in <module> ... Allows to run normal /script commands in a specific module, like run, invoke,..., globals etc...
Provides the ability to execute specific function whenever an event occurs. The functions to be registered
+ * need to conform with the arguments to the event specification. When loading module functions, each function that
+ * starts with __on_... and has the required arguments, will be bound automatically.
+ * In case of player specific modules, all player action events will be directed to the appropriate player space, and
+ * all tick events will be executed in the global context, so its not a good idea to mix these two, so use either of these,
+ * or use commands to call tick events directly, or handle player specific data inside a module.
Here is a list of events that can be handled by scarpet. This list includes prefixes required by modules to + * autoload them, but you can add any function to any event if it had required parameters:
+ *+ * __on_tick() // can access blocks and entities in the overworld + * __on_tick_nether() // can access blocks and entities in the nether + * __on_tick_ender() // can access blocks and entities in the end + * // player specific callbacks + * __on_player_jumps(player) + * __on_player_deploys_elytra(player) + * __on_player_wakes_up(player) + * __on_player_rides(player, forward, strafe, jumping, sneaking) + * __on_player_uses_item(player, item_tuple, hand) + * __on_player_clicks_block(player, block, face) + * __on_player_right_clicks_block(player, item_tuple, hand, block, face, hitvec) + * __on_player_breaks_block(player, block) + * __on_player_interacts_with_entity(player, entity, hand) + * __on_player_attacks_entity(player, entity) + * __on_player_starts_sneaking(player) + * __on_player_stops_sneaking(player) + * __on_player_starts_sprinting(player) + * __on_player_stops_sprinting(player) + *+ *
/script event commandused to display current events and bounded functions. use add_to ro register new event, or remove_from
+ * to unbind a specific function from an event.
This specification is divided into two sections: this one is agnostic - * to any Minecraft related features and could function on its own, and {@see carpet.script.CarpetExpression} for + * to any Minecraft related features and could function on its own, and CarpetExpression for * Minecraft specific routines and world manipulation functions.
* *or an overly complex example:
*
* /script run
- * block_check(x1, y1, z1, x2, y2, z2, block_to_check) ->
+ * block_check(x1, y1, z1, x2, y2, z2, block_to_check) ->
* (
* l(minx, maxx) = sort(l(x1, x2));
* l(miny, maxy) = sort(l(y1, y2));
@@ -100,7 +100,7 @@ import static java.lang.Math.min;
* );
* total_count
* );
- * check_area_around_closest_player_for_block(block_to_check) ->
+ * check_area_around_closest_player_for_block(block_to_check) ->
* (
* closest_player = player();
* l(posx, posy, posz) = query(closest_player, 'pos');
@@ -1638,15 +1638,19 @@ public class Expression implements Cloneable
* range(20, 10, -2) => [20, 18, 16, 14, 12]
*
*
- * get(list, index), element(list, index)(deprecated)Returns the value at index element from the list.
- * use negative numbers to reach elements from the end of the list. get
+ *
get(value, address), element(value, address)(deprecated)Returns the value at address element from the value.
+ * For lists it indicates an index, use negative numbers to reach elements from the end of the list. get
* call will always be able to find the index. In case there is few items, it will loop over
[Minecraft specific usecase]: In case value is of nbt type, uses addess as the nbt path to query,
+ * returning null, if path is not found, one value if there was one match, or list of values if result is a list.
+ * Returned elements can be of numerical type, string texts, or another compound nbt tags
* get(l(range(10)), 5) => 5
* get(l(range(10)), -1) => 9
* get(l(range(10)), 10) => 0
* get(l(range(10)), 93) => 3
+ * get(player() ~ 'nbt', 'Health') => 20 // inefficient way to get player health
*
*
* put(list, index, values ...), put(list, null, values ...)type(expr)Returns the string value indicating type of the expression. Possible outcomes are
+ * null, number, string, list, iterator, as well as minecraft related concepts like
+ * block, entity, nbt
bool(expr)Returns a boolean context of the expression. Note that there are no true/false values in
* scarpet. true is alias of 1, and false is 0. Bool is also interpreting
diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java
index 8ba290a6..0b5dab95 100644
--- a/src/main/java/carpet/script/value/EntityValue.java
+++ b/src/main/java/carpet/script/value/EntityValue.java
@@ -193,6 +193,10 @@ public class EntityValue extends Value
put("has_tag", (e, a) -> new NumericValue(e.getScoreboardTags().contains(a.getString())));
put("yaw", (e, a)-> new NumericValue(e.yaw));
put("pitch", (e, a)-> new NumericValue(e.pitch));
+ put("look", (e, a) -> {
+ Vec3d look = e.getRotationVector();
+ return ListValue.of(new NumericValue(look.x),new NumericValue(look.y),new NumericValue(look.z));
+ });
put("is_burning", (e, a) -> new NumericValue(e.isOnFire()));
//put("fire", (e, a) -> new NumericValue(e.getFire())); needs mixing
put("silent", (e, a)-> new NumericValue(e.isSilent()));
diff --git a/src/main/java/carpet/script/value/StringValue.java b/src/main/java/carpet/script/value/StringValue.java
index 3db05b75..eba0cd16 100644
--- a/src/main/java/carpet/script/value/StringValue.java
+++ b/src/main/java/carpet/script/value/StringValue.java
@@ -28,6 +28,6 @@ public class StringValue extends Value
@Override
public String getTypeString()
{
- return "number";
+ return "string";
}
}
diff --git a/src/main/java/carpet/settings/CarpetSettings.java b/src/main/java/carpet/settings/CarpetSettings.java
index 842498e3..96767a49 100644
--- a/src/main/java/carpet/settings/CarpetSettings.java
+++ b/src/main/java/carpet/settings/CarpetSettings.java
@@ -26,7 +26,7 @@ import static carpet.settings.RuleCategory.SURVIVAL;
public class CarpetSettings
{
- public static final String carpetVersion = "v190714";
+ public static final String carpetVersion = "1.0.0-v190721";
public static final Logger LOG = LogManager.getLogger();
public static boolean skipGenerationChecks = false;
public static boolean impendingFillSkipUpdates = false;