From 8e369c2549f9b6fa392dab300ac4657d42385bb7 Mon Sep 17 00:00:00 2001 From: gnembon Date: Sun, 21 Jul 2019 16:55:30 -0300 Subject: [PATCH] fix harvest --- gradle.properties | 2 +- .../carpet/commands/CameraModeCommand.java | 14 +- .../java/carpet/script/CarpetExpression.java | 214 ++++++++++++++---- src/main/java/carpet/script/Expression.java | 20 +- .../java/carpet/script/value/EntityValue.java | 4 + .../java/carpet/script/value/StringValue.java | 2 +- .../java/carpet/settings/CarpetSettings.java | 2 +- 7 files changed, 204 insertions(+), 54 deletions(-) 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; + } + } + } + } + /** *

Blocks / World API

*
@@ -373,11 +413,12 @@ public class CarpetExpression *

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 and World querying

* @@ -390,6 +431,8 @@ public class CarpetExpression * pos(players()) => l(12.3, 45.6, 32.05) * pos(block('stone')) => Error: Cannot fetch position of an unrealized block * + *

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:

* *
-     * 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.

+ * *

Entity Manipulation

* *

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')

@@ -1471,6 +1498,7 @@ public class CarpetExpression * *

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:

@@ -1488,7 +1516,14 @@ public class CarpetExpression *

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)

@@ -2221,6 +2255,10 @@ public class CarpetExpression *

particle_rect(name, pos, pos2, density?)

*

Renders a cuboid of particles between point pos to pos2 with supplied density.

*

System function

+ *

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.

@@ -2533,6 +2571,14 @@ public class CarpetExpression return (_cc, _tt) -> new NumericValue(finalTotal); }); + this.expr.addLazyFunction("nbt", 1, (c, t, lv) -> { + Value v = lv.get(0).evalValue(c); + if (v instanceof NBTSerializableValue) + return (cc, tt) -> v; + Value ret = new NBTSerializableValue(v.getString()); + return (cc, tt) -> ret; + }); + //"overridden" native call that prints to stderr this.expr.addLazyFunction("print", 1, (c, t, lv) -> { @@ -2826,4 +2872,90 @@ public class CarpetExpression { return "Yeah"; } + + /** + *

/script load / unload <module> (shared?), /script in <module> commands

+ *
+ *

load / 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...

+ *
+ * @return . + */ + public static String loadScriptsFromFilesCommand() + { + return "Yeah"; + } + + /** + *

Scarpet events system

+ *
+ *

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.

+ *

+ *

Event list

+ *

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 command

+ *

used 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.

+ *
+ * @return . + */ + public static String gameEventsSystem() + { + return "Yeah"; + } } diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index d5679c6f..dec37f55 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -64,7 +64,7 @@ import static java.lang.Math.min; * repository

* *

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.

* *

Synopsis

@@ -75,7 +75,7 @@ import static java.lang.Math.min; *

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 ...)

@@ -2220,6 +2224,10 @@ public class Expression implements Cloneable *

System functions

*
*

Type conversion functions

+ *

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;