From 435794569e9f9fa6008eee051f1973a7811dada9 Mon Sep 17 00:00:00 2001 From: gnembon Date: Fri, 11 Oct 2019 01:47:04 -0300 Subject: [PATCH] build in script load from resources, fixed entity value position errors, added 2 more events, added event test --- ...PlayNetworkHandler_scarpetEventsMixin.java | 25 ++ .../java/carpet/script/CarpetEventServer.java | 25 +- .../java/carpet/script/CarpetExpression.java | 41 ++- .../carpet/script/CarpetScriptServer.java | 5 +- .../carpet/script/bundled/BundledModule.java | 39 ++ .../script/bundled/CameraPathModule.java | 334 ------------------ .../java/carpet/script/value/EntityValue.java | 4 +- .../resources/assets/carpet/scripts/camera.sc | 265 ++++++++++++++ .../assets/carpet/scripts/event_test.sc | 116 ++++++ 9 files changed, 511 insertions(+), 343 deletions(-) create mode 100644 src/main/java/carpet/script/bundled/BundledModule.java delete mode 100644 src/main/java/carpet/script/bundled/CameraPathModule.java create mode 100644 src/main/resources/assets/carpet/scripts/camera.sc create mode 100644 src/main/resources/assets/carpet/scripts/event_test.sc diff --git a/src/main/java/carpet/mixins/ServerPlayNetworkHandler_scarpetEventsMixin.java b/src/main/java/carpet/mixins/ServerPlayNetworkHandler_scarpetEventsMixin.java index b62d34f7..1c20a85e 100644 --- a/src/main/java/carpet/mixins/ServerPlayNetworkHandler_scarpetEventsMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayNetworkHandler_scarpetEventsMixin.java @@ -22,6 +22,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import static carpet.script.CarpetEventServer.Event.PLAYER_ATTACKS_ENTITY; import static carpet.script.CarpetEventServer.Event.PLAYER_CLICKS_BLOCK; import static carpet.script.CarpetEventServer.Event.PLAYER_DEPLOYS_ELYTRA; +import static carpet.script.CarpetEventServer.Event.PLAYER_DROPS_ITEM; +import static carpet.script.CarpetEventServer.Event.PLAYER_DROPS_STACK; import static carpet.script.CarpetEventServer.Event.PLAYER_INERACTSW_WITH_ENTITY; import static carpet.script.CarpetEventServer.Event.PLAYER_RELEASED_ITEM; import static carpet.script.CarpetEventServer.Event.PLAYER_RIDES; @@ -49,6 +51,29 @@ public class ServerPlayNetworkHandler_scarpetEventsMixin } } + @Inject(method = "onPlayerAction", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerEntity;dropSelectedItem(Z)Z", + ordinal = 0, + shift = At.Shift.BEFORE + )) + private void onQItem(PlayerActionC2SPacket playerActionC2SPacket_1, CallbackInfo ci) + { + PLAYER_DROPS_ITEM.onPlayerEvent(player); + } + + @Inject(method = "onPlayerAction", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerPlayerEntity;dropSelectedItem(Z)Z", + ordinal = 1, + shift = At.Shift.BEFORE + )) + private void onCtrlQItem(PlayerActionC2SPacket playerActionC2SPacket_1, CallbackInfo ci) + { + PLAYER_DROPS_STACK.onPlayerEvent(player); + } + + @Inject(method = "onPlayerMove", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;jump()V" diff --git a/src/main/java/carpet/script/CarpetEventServer.java b/src/main/java/carpet/script/CarpetEventServer.java index 754216f7..54ab74f1 100644 --- a/src/main/java/carpet/script/CarpetEventServer.java +++ b/src/main/java/carpet/script/CarpetEventServer.java @@ -301,7 +301,7 @@ public class CarpetEventServer @Override public void onPlayerEvent(ServerPlayerEntity player) { - handler.call( () -> Arrays.asList(((c, t) -> new EntityValue(player))), player::getCommandSource); + handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource); } }, PLAYER_STOPS_SNEAKING("player_stops_sneaking",new CallbackList(1)) @@ -309,7 +309,7 @@ public class CarpetEventServer @Override public void onPlayerEvent(ServerPlayerEntity player) { - handler.call( () -> Arrays.asList(((c, t) -> new EntityValue(player))), player::getCommandSource); + handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource); } }, PLAYER_STARTS_SPRINTING("player_starts_sprinting",new CallbackList(1)) @@ -317,7 +317,7 @@ public class CarpetEventServer @Override public void onPlayerEvent(ServerPlayerEntity player) { - handler.call( () -> Arrays.asList(((c, t) -> new EntityValue(player))), player::getCommandSource); + handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource); } }, PLAYER_STOPS_SPRINTING("player_stops_sprinting",new CallbackList(1)) @@ -325,7 +325,7 @@ public class CarpetEventServer @Override public void onPlayerEvent(ServerPlayerEntity player) { - handler.call( () -> Arrays.asList(((c, t) -> new EntityValue(player))), player::getCommandSource); + handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource); } }, @@ -360,7 +360,24 @@ public class CarpetEventServer ); }, player::getCommandSource); } + }, + PLAYER_DROPS_ITEM("player_drops_item", new CallbackList(1)) + { + @Override + public void onPlayerEvent(ServerPlayerEntity player) + { + handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource); + } + }, + PLAYER_DROPS_STACK("player_drops_stack", new CallbackList(1)) + { + @Override + public void onPlayerEvent(ServerPlayerEntity player) + { + handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource); + } }; + // on projectile thrown (arrow from bows, crossbows, tridents, snoballs, e-pearls public String name; diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 958e8e6b..19958448 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -32,6 +32,7 @@ import net.minecraft.block.CommandBlock; import net.minecraft.block.JigsawBlock; import net.minecraft.block.StructureBlock; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.client.network.packet.GuiSlotUpdateS2CPacket; import net.minecraft.client.network.packet.PlaySoundIdS2CPacket; import net.minecraft.command.arguments.ItemStackArgument; import net.minecraft.command.arguments.ParticleArgumentType; @@ -46,10 +47,14 @@ import net.minecraft.entity.SpawnType; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventory; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.item.NetworkSyncedItem; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.Packet; import net.minecraft.particle.ParticleEffect; import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.server.MinecraftServer; @@ -1053,6 +1058,13 @@ public class CarpetExpression * stack_limit('ender_pearl') => 16 * stack_limit('stone') => 64 * + *

item_category(item)

+ *

Returns the string representing the category of a given item, like `building_blocks`, `combat`, or `tools`.

+ *
+     *     item_category('wooden_axe') => tools
+     *     item_category('ender_pearl') => misc
+     *     item_category('stone') => building_blocks
+     * 
*

inventory_size(inventory)

*

Returns the size of the inventory for the entity or block in question. Returns null if the block or entity * don't have an inventory

@@ -1122,6 +1134,15 @@ public class CarpetExpression return (_c, _t) -> res; }); + this.expr.addLazyFunction("item_category", 1, (c, t, lv) -> + { + ItemStackArgument item = NBTSerializableValue.parseItem(lv.get(0).evalValue(c).getString()); + Value res = new StringValue(item.getItem().getGroup().getName()); + return (_c, _t) -> res; + }); + + + this.expr.addLazyFunction("inventory_size", -1, (c, t, lv) -> { CarpetContext cc = (CarpetContext) c; @@ -1175,6 +1196,7 @@ public class CarpetExpression { // clear slot ItemStack removedStack = inventoryLocator.inventory.removeInvStack(slot); + syncPlayerInventory(inventoryLocator, slot); //Value res = ListValue.fromItemStack(removedStack); // that tuple will be read only but cheaper if noone cares return (_c, _t) -> ListValue.fromItemStack(removedStack); } @@ -1184,6 +1206,7 @@ public class CarpetExpression ItemStack newStack = previousStack.copy(); newStack.setCount(count); inventoryLocator.inventory.setInvStack(slot, newStack); + syncPlayerInventory(inventoryLocator, slot); return (_c, _t) -> ListValue.fromItemStack(previousStack); } CompoundTag nbt = null; // skipping one argument @@ -1206,6 +1229,7 @@ public class CarpetExpression try { inventoryLocator.inventory.setInvStack(slot, newitem.createStack(count, false)); + syncPlayerInventory(inventoryLocator, slot); } catch (CommandSyntaxException e) { @@ -1281,11 +1305,13 @@ public class CarpetExpression { stack.setCount(left); inventoryLocator.inventory.setInvStack(i, stack); + syncPlayerInventory(inventoryLocator, i); return (_c, _t) -> Value.TRUE; } else { inventoryLocator.inventory.removeInvStack(i); + syncPlayerInventory(inventoryLocator, i); amount -= stack.getCount(); } } @@ -1346,11 +1372,22 @@ public class CarpetExpression item.setToDefaultPickupDelay(); cc.s.getWorld().spawnEntity(item); } - inventoryLocator.inventory.markDirty(); Value res = new NumericValue(item.getStack().getCount()); return (_c, _t) -> res; }); } + private void syncPlayerInventory(NBTSerializableValue.InventoryLocator inventory, int int_1) + { + if (inventory.owner instanceof ServerPlayerEntity) + { + ServerPlayerEntity player = (ServerPlayerEntity) inventory.owner; + player.networkHandler.sendPacket(new GuiSlotUpdateS2CPacket( + -2, + int_1, + inventory.inventory.getInvStack(int_1) + )); + } + } /** @@ -3107,6 +3144,8 @@ public class CarpetExpression * __on_player_stops_sneaking(player) * __on_player_starts_sprinting(player) * __on_player_stops_sprinting(player) + * __on_player_drops_item(player) + * __on_player_drops_stack(player) * *

/script event command

*

used to display current events and bounded functions. use add_to ro register new event, or remove_from diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index d4a29872..c03d67bb 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -1,8 +1,8 @@ package carpet.script; +import carpet.script.bundled.BundledModule; import carpet.settings.CarpetSettings; import carpet.CarpetServer; -import carpet.script.bundled.CameraPathModule; import carpet.script.bundled.FileModule; import carpet.script.bundled.ModuleInterface; import carpet.script.exception.CarpetExpressionException; @@ -40,7 +40,8 @@ public class CarpetScriptServer public CarpetEventServer events; public static List bundledModuleData = new ArrayList(){{ - add(new CameraPathModule()); + add(new BundledModule("camera")); + add(new BundledModule("event_test")); }}; public CarpetScriptServer() diff --git a/src/main/java/carpet/script/bundled/BundledModule.java b/src/main/java/carpet/script/bundled/BundledModule.java new file mode 100644 index 00000000..57771824 --- /dev/null +++ b/src/main/java/carpet/script/bundled/BundledModule.java @@ -0,0 +1,39 @@ +package carpet.script.bundled; + +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class BundledModule implements ModuleInterface +{ + private String name; + private String code; + public BundledModule(String scriptName) + { + try + { + name = scriptName; + code = IOUtils.toString( + getClass().getClassLoader().getResourceAsStream("assets/carpet/scripts/"+scriptName+".sc"), + StandardCharsets.UTF_8 + ); + } + catch ( NullPointerException | IOException e) + { + name = null; + code = null; + } + } + @Override + public String getName() + { + return name; + } + + @Override + public String getCode() + { + return code; + } +} diff --git a/src/main/java/carpet/script/bundled/CameraPathModule.java b/src/main/java/carpet/script/bundled/CameraPathModule.java deleted file mode 100644 index f2aca079..00000000 --- a/src/main/java/carpet/script/bundled/CameraPathModule.java +++ /dev/null @@ -1,334 +0,0 @@ -package carpet.script.bundled; - -public class CameraPathModule implements ModuleInterface -{ - @Override - public String getName() - { - return "camera"; - } - - @Override - public String getCode() - { - return " __command() ->\n" + - " (\n" + - " print('Camera path module.');\n" + - " print('-------------------');\n" + - " print(' \"/camera start\" - set the starting point');\n" + - " print('');\n" + - " print(' \"/camera add \" - add another point frames later');\n" + - " print('');\n" + - " print(' \"/camera select_interpolation < linear | gauss_? >\"');\n" + - " print(' Select interpolation between points:');\n" + - " print(' - linear: straight paths between points.');\n" + - " print(' - gauss_auto: automatic smooth transitions.');\n" + - " print(' - gauss_: custom fixed variance ');\n" + - " print(' (in points) for special effects.');\n" + - " print('');\n" + - " print(' \"/camera repeat \" - ');\n" + - " print(' Repeat existing points configuration n-times');\n" + - " print(' using points to link path ends');\n" + - " print('');\n" + - " print(' \"/camera speed - ');\n" + - " print(' Change number of frames between points');\n" + - " print(' from 25 -> 4 times faster (less points),');\n" + - " print(' to 400 -> 4 times slower (more points)');\n" + - " print('');\n" + - " print(' \"/camera play : run a path with a player');\n" + - " print(' needs to be multiples of 20, (20 tps)');\n" + - " print('');\n" + - " print(' \"/camera show\": shows current path for a moment');\n" + - " print('');\n" + - " print(' \"/script in camera invoke _show_path_tick \":');\n" + - " print(' place this in a repeating commandblock');\n" + - " print(' to display path continuously');\n" + - " print(' with set particle and number of particles per tick');\n" + - " print(' example: \\'dust 0.9 0.1 0.1 1\\' 100 ');\n" + - " ''\n" + - " );\n" + - " start() -> \n" + - "(\n" + - " p = player();\n" + - " global_points = l(l(l(p~'x',p~'y',p~'z',p~'yaw',p~'pitch'),0,'sharp'));\n" + - " undef('global_path_precalculated');\n" + - " str('Started path at %.1f %.1f %.1f', p~'x', p~'y', p~'z')\n" + - ");\n" + - "\n" + - " add(delay) -> \n" + - "( \n" + - " p = player(); \n" + - " mode = 'sharp';\n" + - " 'mode is currently unused, run_path does always sharp, gauss interpolator is always smooth';\n" + - " ' but this option could be used could be used at some point by more robust interpolators';\n" + - " vector = l(p~'x',p~'y',p~'z', p~'yaw', p~'pitch');\n" + - " __add_path_segment(vector, delay, mode);\n" + - " str('Added point %d: %.1f %.1f %.1f', length(global_points), p~'x', p~'y', p~'z')\n" + - ");\n" + - "\n" + - " __add_path_segment(vector, duration, mode) -> \n" + - "(\n" + - " undef('global_path_precalculated');\n" + - " if ( (l('sharp','smooth') ~ mode) == null, exit('use smooth or sharp point')); \n" + - " if(!global_points, exit('Cannot add point to path that didn\\'t started yet!'));\n" + - " l(v, end_time, m) = element(global_points, -1);\n" + - " put(vector,-2, __adjusted_rot(element(v, -2), element(vector, -2)));\n" + - " global_points += l(vector, end_time+duration, mode)\n" + - ");\n" + - "\n" + - "'adjusts current rotation so we don\\'t spin around like crazy';\n" + - " __adjusted_rot(previous_rot, current_rot) -> \n" + - "(\n" + - " while( abs(previous_rot-current_rot) > 180, 1000,\n" + - " current_rot += if(previous_rot < current_rot, -360, 360)\n" + - " );\n" + - " current_rot\n" + - ");\n" + - "\n" + - "\n" + - " repeat(times, last_section_duration) -> \n" + - "(\n" + - " undef('global_path_precalculated');\n" + - " positions = map(global_points, k = element(_, 0));\n" + - " modes = map(global_points, element(_, -1));\n" + - " durations = map(global_points, element(element(global_points, _i+1), 1)-element(_, 1));\n" + - " put(durations, -1, last_section_duration);\n" + - " loop(times,\n" + - " loop( length(positions),\n" + - " __add_path_segment(element(positions, _), element(durations, _), element(modes, _))\n" + - " )\n" + - " );\n" + - " str('Add %d points %d times', length(positions), times)\n" + - ");\n" + - "\n" + - " speed(percentage) ->\n" + - "(\n" + - " undef('global_path_precalculated');\n" + - " if (percentage < 25 || percentage > 400, \n" + - " exit('path speed can only be speed, or slowed down 4 times. Recall command for larger changes')\n" + - " );\n" + - " ratio = percentage/100;\n" + - " previous_path_length = element(element(global_points, -1),1);\n" + - " for(global_points, put(_, 1, element(_, 1)*ratio ) );\n" + - " undef('global_path_precalculated');\n" + - " str('path %s from %d to %d ticks',\n" + - " if(ratio<1,'shortened','extended'),\n" + - " previous_path_length,\n" + - " element(element(global_points, -1),1)\n" + - " )\n" + - ");\n" + - "\n" + - " select_interpolation(method) ->\n" + - "(\n" + - " undef('global_path_precalculated');\n" + - " __prepare_path_if_needed() -> __prepare_path_if_needed_generic();\n" + - " 'each supported method needs to specify its __find_position_for_point to trace the path';\n" + - " 'accepting segment number, and position in the segment';\n" + - " 'or optionally __prepare_path_if_needed, if path is inefficient to compute point by point';\n" + - " if (\n" + - " method == 'linear',\n" + - " (\n" + - " __find_position_for_point(s, p) -> __find_position_for_linear(s, p)\n" + - " ),\n" + - " method ~ '^gauss_',\n" + - " (\n" + - " type = method - 'gauss_';\n" + - " global_interpol_option = if(type=='auto',0,number(type));\n" + - " __find_position_for_point(s, p) -> __find_position_for_gauss(s, p)\n" + - " ),\n" + - " method ~ '^bungee_',\n" + - " (\n" + - " exit('unsupported / planned');\n" + - " type = method - 'bungee_';\n" + - " global_interpol_option = if(type=='auto',80,number(type));\n" + - " __prepare_path_if_needed() -> __prepare_path_if_needed_bungee()\n" + - " ),\n" + - " \n" + - " exit('Choose one of the following methods: linear, gauss:auto, gauss:')\n" + - " );\n" + - " 'Ok'\n" + - ");\n" + - "\n" + - " select_interpolation('linear');\n" + - "\n" + - " __assert_valid_for_motion() ->\n" + - "(\n" + - " if(!global_points, exit('Path not defined yet'));\n" + - " if(length(global_points)<2, exit('Path not complete - add more points'));\n" + - " null \n" + - ");\n" + - "\n" + - " __get_path_at(segment, start, index) ->\n" + - "(\n" + - " v = element(global_path_precalculated, start+index);\n" + - " if(v == null,\n" + - " v = __find_position_for_point(segment, index);\n" + - " put(global_path_precalculated, start+index, v)\n" + - " );\n" + - " v\n" + - ");\n" + - "\n" + - " __invalidate_points_cache() -> global_path_precalculated = map(range(element(element(global_points, -1),1)), null);\n" + - "\n" + - " show() -> \n" + - "(\n" + - " loop(100,\n" + - " _show_path_tick('dust 0.9 0.1 0.1 1', 100);\n" + - " game_tick(50)\n" + - " );\n" + - " 'Done!'\n" + - ");\n" + - "\n" + - " __play(fps) -> \n" + - "(\n" + - " p = player();\n" + - " __assert_valid_for_motion();\n" + - " __prepare_path_if_needed();\n" + - " loop( length(global_points)-1,\n" + - " segment = _;\n" + - " start = element(element(global_points, segment),1);\n" + - " end = element(element(global_points, segment+1),1);\n" + - " loop(end-start,\n" + - " v = __get_path_at(segment, start, _);\n" + - " modify(p, 'location', v);\n" + - " game_tick(1000/fps)\n" + - " )\n" + - " );\n" + - " game_tick(1000);\n" + - " 'Done!'\n" + - ");\n" + - "\n" + - " play(fps) -> \n" + - "(\n" + - " p = player();\n" + - " __assert_valid_for_motion();\n" + - " __prepare_path_if_needed();\n" + - " if ((fps % 20 != 0) || fps < 20, exit('FPS needs to be multiples of 20') );\n" + - "\ttpt = round(fps / 20);\n" + - " mspt = 50 / tpt; \n" + - " start_time = time();\n" + - " point = 0;\n" + - " loop( length(global_points)-1,\n" + - " segment = _;\n" + - " start = element(element(global_points, segment),1);\n" + - " end = element(element(global_points, segment+1),1);\n" + - " loop(end-start,\n" + - " v = __get_path_at(segment, start, _);\n" + - " modify(p, 'location', v);\n" + - " point += 1;\n" + - " if ((point % tpt == 0), game_tick());\n" + - " end_time = time();\n" + - " took = end_time - start_time;\n" + - " if (took < mspt, sleep(mspt-took));\n" + - " start_time = time()\n" + - " )\n" + - " );\n" + - " game_tick(1000);\n" + - " 'Done!'\n" + - ");\n" + - "\n" + - " _show_path_tick(particle_type, total) -> (\n" + - " __assert_valid_for_motion();\n" + - " __prepare_path_if_needed();\n" + - " loop(total,\n" + - " segment = floor(rand(length(global_points)-1));\n" + - " start = element(element(global_points, segment),1);\n" + - " end = element(element(global_points, segment+1),1);\n" + - " index = floor(rand(end-start));\n" + - " l(x, y, z) = slice(__get_path_at(segment, start, index), 0, 3);\n" + - " particle(particle_type, x, y, z, 1, 0, 0)\n" + - " );\n" + - " null\n" + - ");\n" + - "\n" + - " __prepare_path_if_needed_generic() ->\n" + - "(\n" + - " if(!global_path_precalculated, __invalidate_points_cache())\n" + - ");\n" + - "\n" + - "__find_position_for_linear(segment, point) ->\n" + - "(\n" + - " l(va, start, mode_a) = element(global_points,segment);\n" + - " l(vb, end, mode_b) = element(global_points,segment+1);\n" + - " section = end-start;\n" + - " dt = point/section;\n" + - " dt*vb+(1-dt)*va\n" + - ");\n" + - "\n" + - "\n" + - "'(1/sqrt(2*pi*d*d))*euler^(-((x-miu)^2)/(2*d*d)) ';\n" + - " 'but we will be normalizing anyways, so who cares';\n" + - " __norm_prob(x, miu, d) -> euler^(-((x-miu)^2)/(2*d*d));\n" + - "\n" + - " __find_position_for_gauss(from_index, point) -> \n" + - "(\n" + - " dev = global_interpol_option;\n" + - " components = l();\n" + - " path_point = element(element(global_points, from_index),1);\n" + - " \n" + - " try(\n" + - " for(range(from_index+1, length(global_points)),\n" + - " l(v,ptime,mode) = element(global_points, _);\n" + - " dev = if (global_interpol_option > 0, global_interpol_option, \n" + - " devs = l();\n" + - " if (_+1 < length(global_points), devs += element(element(global_points, _+1),1)-ptime);\n" + - " if (_-1 >= 0, devs += ptime-element(element(global_points, _-1),1));\n" + - " 0.6*reduce(devs, _a+_, 0)/length(devs)\n" + - " );\n" + - " impact = __norm_prob(path_point+point, ptime, dev);\n" + - " if(rtotal && impact < 0.000001*rtotal, throw(null));\n" + - " components += l(v, impact);\n" + - " rtotal += impact\n" + - " )\n" + - " ,null\n" + - " );\n" + - " try(\n" + - " for(range(from_index, -1, -1),\n" + - " l(v,ptime,mode) = element(global_points, _);\n" + - " dev = if (global_interpol_option > 0, global_interpol_option, \n" + - " devs = l();\n" + - " if (_+1 < length(global_points), devs += element(element(global_points, _+1),1)-ptime);\n" + - " if (_-1 >= 0, devs += ptime-element(element(global_points, _-1),1));\n" + - " 0.6*reduce(devs, _a+_, 0)/length(devs)\n" + - " );\n" + - " impact = __norm_prob(path_point+point, ptime, dev);\n" + - " if(ltotal && impact < 0.000001*ltotal, throw(null));\n" + - " components += l(v, impact);\n" + - " ltotal += impact\n" + - " )\n" + - " ,null\n" + - " );\n" + - " total = rtotal+ltotal;\n" + - " reduce(components, _a+element(_,0)*(element(_,1)/total), l(0,0,0,0,0))\n" + - ");\n" + - " __prepare_path_if_needed_bungee(fps) ->\n" + - "(\n" + - " exit('not ready!');\n" + - " if(!global_points, exit('Cannot show path that doesn\\'t exist'));\n" + - " if(length(global_points)<2, exit('Path not complete - add more points'));\n" + - " v = element(element(global_points, 0),0);\n" + - " modify(p, 'pos', slice(v,0,3));\n" + - " modify(p, 'yaw', element(v,3));\n" + - " modify(p, 'pitch', element(v,4));\n" + - " current_target = element(element(global_points, 1),0);\n" + - " current_hook = 1;\n" + - " loop(length(global_points)-1, \n" + - " current_base = _;\n" + - " l(va, start, mode_a) = element(global_points,_);\n" + - " l(vb, end, mode_b) = element(global_points,_+1);\n" + - " section = end-start;\n" + - " loop(section,\n" + - " dt = _/section;\n" + - "\n" + - " v = dt*vb+(1-dt)*va;\n" + - " modify(p, 'pos', slice(v,0,3));\n" + - " modify(p, 'yaw', element(v,3));\n" + - " modify(p, 'pitch', element(v,4));\n" + - " game_tick(1000/fps)\n" + - " )\n" + - " );\n" + - " game_tick(1000);\n" + - " 'Done!'\n" + - ")\n"; - } -} diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index f1e2487e..e40ce531 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -183,8 +183,8 @@ public class EntityValue extends Value put("pos", (e, a) -> ListValue.of(new NumericValue(e.method_23317()), new NumericValue(e.method_23318()), new NumericValue(e.method_23321()))); put("location", (e, a) -> ListValue.of(new NumericValue(e.method_23317()), new NumericValue(e.method_23318()), new NumericValue(e.method_23321()), new NumericValue(e.yaw), new NumericValue(e.pitch))); put("x", (e, a) -> new NumericValue(e.method_23317())); - put("y", (e, a) -> new NumericValue(e.method_23317())); - put("z", (e, a) -> new NumericValue(e.method_23317())); + put("y", (e, a) -> new NumericValue(e.method_23318())); + put("z", (e, a) -> new NumericValue(e.method_23321())); put("motion", (e, a) -> { Vec3d velocity = e.getVelocity(); diff --git a/src/main/resources/assets/carpet/scripts/camera.sc b/src/main/resources/assets/carpet/scripts/camera.sc new file mode 100644 index 00000000..3275dde6 --- /dev/null +++ b/src/main/resources/assets/carpet/scripts/camera.sc @@ -0,0 +1,265 @@ +__command() -> +( + print('camera_path module.'); + print('-------------------'); + print(' "/camera_path start" - set the starting point'); + print(''); + print(' "/camera_path add " - add another point frames later'); + print(''); + print(' "/camera_path select_interpolation < linear | gauss_? >"'); + print(' Select interpolation between points:'); + print(' - linear: straight paths between points.'); + print(' - gauss_auto: automatic smooth transitions.'); + print(' - gauss_: custom fixed variance '); + print(' (in points) for special effects.'); + print(''); + print(' "/camera_path repeat " - '); + print(' Repeat existing points configuration n-times'); + print(' using points to link path ends'); + print(''); + print(' "/camera_path speed - '); + print(' Change number of frames between points'); + print(' from 25 -> 4 times faster (less points),'); + print(' to 400 -> 4 times slower (more points)'); + print(''); + print(' "/camera_path play : run a path with a player'); + print(' needs to be multiples of 20, (20 tps)'); + print(''); + print(' "/camera_path show": shows current path for a moment'); + print(''); + print(' "/script in camera_path invoke _show_path_tick ":'); + print(' place this in a repeating commandblock'); + print(' to display path continuously'); + print(' with set particle and number of particles per tick'); + print(' example: \'dust 0.9 0.1 0.1 1\' 100 '); + '' +); + +start() -> +( + p = player(); + global_points = l(l(p ~ 'location', 0,'sharp')); + undef('global_path_precalculated'); + str('Started path at %.1f %.1f %.1f', p~'x', p~'y', p~'z') +); + +add(delay) -> +( + p = player(); + mode = 'sharp'; + //mode is currently unused, run_path does always sharp, gauss interpolator is always smooth + // but this option could be used could be used at some point by more robust interpolators + __add_path_segment(p ~ 'location', delay, mode); + str('Added point %d: %.1f %.1f %.1f', length(global_points), p~'x', p~'y', p~'z') +); + +__add_path_segment(vector, duration, mode) -> +( + undef('global_path_precalculated'); + if ( (l('sharp','smooth') ~ mode) == null, exit('use smooth or sharp point')); + if(!global_points, exit('Cannot add point to path that didn\'t started yet!')); + l(v, end_time, m) = get(global_points, -1); + put(vector,-2, __adjusted_rot(get(v, -2), get(vector, -2))); + global_points += l(vector, end_time+duration, mode) +); + +// adjusts current rotation so we don\'t spin around like crazy +__adjusted_rot(previous_rot, current_rot) -> +( + while( abs(previous_rot-current_rot) > 180, 1000, + current_rot += if(previous_rot < current_rot, -360, 360) + ); + current_rot +); + + +repeat(times, last_section_duration) -> +( + undef('global_path_precalculated'); + positions = map(global_points, k = get(_, 0)); + modes = map(global_points, get(_, -1)); + durations = map(global_points, get(get(global_points, _i+1), 1)-get(_, 1)); + put(durations, -1, last_section_duration); + loop(times, + loop( length(positions), + __add_path_segment(get(positions, _), get(durations, _), get(modes, _)) + ) + ); + str('Add %d points %d times', length(positions), times) +); + +speed(percentage) -> +( + undef('global_path_precalculated'); + if (percentage < 25 || percentage > 400, + exit('path speed can only be speed, or slowed down 4 times. Recall command for larger changes') + ); + ratio = percentage/100; + previous_path_length = get(get(global_points, -1),1); + for(global_points, put(_, 1, get(_, 1)*ratio ) ); + undef('global_path_precalculated'); + str('path %s from %d to %d ticks', + if(ratio<1,'shortened','extended'), + previous_path_length, + get(get(global_points, -1),1) + ) +); + +select_interpolation(method) -> +( + undef('global_path_precalculated'); + __prepare_path_if_needed() -> __prepare_path_if_needed_generic(); + // each supported method needs to specify its __find_position_for_point to trace the path + // accepting segment number, and position in the segment + // or optionally __prepare_path_if_needed, if path is inefficient to compute point by point + if ( + method == 'linear', + ( + __find_position_for_point(s, p) -> __find_position_for_linear(s, p) + ), + method ~ '^gauss_', + ( + type = method - 'gauss_'; + global_interpol_option = if(type=='auto',0,number(type)); + __find_position_for_point(s, p) -> __find_position_for_gauss(s, p) + ), + + exit('Choose one of the following methods: linear, gauss:auto, gauss:') + ); + 'Ok' +); + +select_interpolation('gauss_auto'); + +__assert_valid_for_motion() -> +( + if(!global_points, exit('Path not defined yet')); + if(length(global_points)<2, exit('Path not complete - add more points')); + null +); + +__get_path_at(segment, start, index) -> +( + v = get(global_path_precalculated, start+index); + if(v == null, + v = __find_position_for_point(segment, index); + put(global_path_precalculated, start+index, v) + ); + v +); + +__invalidate_points_cache() -> global_path_precalculated = map(range(get(get(global_points, -1),1)), null); + +show() -> +( + loop(100, + _show_path_tick('dust 0.9 0.1 0.1 1', 100); + game_tick(50) + ); + 'Done!' +); + +play(fps) -> +( + p = player(); + __assert_valid_for_motion(); + __prepare_path_if_needed(); + if ((fps % 20 != 0) || fps < 20, exit('FPS needs to be multiples of 20') ); + tpt = round(fps / 20); + mspt = 50 / tpt; + start_time = time(); + point = 0; + loop( length(global_points)-1, + segment = _; + start = get(get(global_points, segment),1); + end = get(get(global_points, segment+1),1); + loop(end-start, + v = __get_path_at(segment, start, _); + modify(p, 'location', v); + point += 1; + if ((point % tpt == 0), game_tick()); + end_time = time(); + took = end_time - start_time; + if (took < mspt, sleep(mspt-took)); + start_time = time() + ) + ); + game_tick(1000); + 'Done!' +); + +_show_path_tick(particle_type, total) -> +( + __assert_valid_for_motion(); + __prepare_path_if_needed(); + loop(total, + segment = floor(rand(length(global_points)-1)); + start = get(get(global_points, segment),1); + end = get(get(global_points, segment+1),1); + index = floor(rand(end-start)); + l(x, y, z) = slice(__get_path_at(segment, start, index), 0, 3); + particle(particle_type, x, y, z, 1, 0, 0) + ); + null +); + +__prepare_path_if_needed_generic() -> +( + if(!global_path_precalculated, __invalidate_points_cache()) +); + +__find_position_for_linear(segment, point) -> +( + l(va, start, mode_a) = get(global_points,segment); + l(vb, end, mode_b) = get(global_points,segment+1); + section = end-start; + dt = point/section; + dt*vb+(1-dt)*va +); + + +//(1/sqrt(2*pi*d*d))*euler^(-((x-miu)^2)/(2*d*d)) +// but we will be normalizing anyways, so who cares +__norm_prob(x, miu, d) -> euler^(-((x-miu)^2)/(2*d*d)); + +__find_position_for_gauss(from_index, point) -> +( + dev = global_interpol_option; + components = l(); + path_point = get(get(global_points, from_index),1); + + try( + for(range(from_index+1, length(global_points)), + l(v,ptime,mode) = get(global_points, _); + dev = if (global_interpol_option > 0, global_interpol_option, + devs = l(); + if (_+1 < length(global_points), devs += get(get(global_points, _+1),1)-ptime); + if (_-1 >= 0, devs += ptime-get(get(global_points, _-1),1)); + 0.6*reduce(devs, _a+_, 0)/length(devs) + ); + impact = __norm_prob(path_point+point, ptime, dev); + if(rtotal && impact < 0.000001*rtotal, throw(null)); + components += l(v, impact); + rtotal += impact + ) + ,null + ); + try( + for(range(from_index, -1, -1), + l(v,ptime,mode) = get(global_points, _); + dev = if (global_interpol_option > 0, global_interpol_option, + devs = l(); + if (_+1 < length(global_points), devs += get(get(global_points, _+1),1)-ptime); + if (_-1 >= 0, devs += ptime-get(get(global_points, _-1),1)); + 0.6*reduce(devs, _a+_, 0)/length(devs) + ); + impact = __norm_prob(path_point+point, ptime, dev); + if(ltotal && impact < 0.000001*ltotal, throw(null)); + components += l(v, impact); + ltotal += impact + ) + ,null + ); + total = rtotal+ltotal; + reduce(components, _a+get(_,0)*(get(_,1)/total), l(0,0,0,0,0)) +) \ No newline at end of file diff --git a/src/main/resources/assets/carpet/scripts/event_test.sc b/src/main/resources/assets/carpet/scripts/event_test.sc new file mode 100644 index 00000000..318ea352 --- /dev/null +++ b/src/main/resources/assets/carpet/scripts/event_test.sc @@ -0,0 +1,116 @@ + +__on_player_jumps(player) -> print('Player '+player+' jumps.'); + +__on_player_deploys_elytra(player) -> print('Player '+player+' deploys elytra.'); + +__on_player_wakes_up(player) -> print('Player '+player+' wakes up. Lemme know when this starts working'); + +__on_player_rides(player, forward, strafe, jumping, sneaking) -> +( + print(''); + print('player rides a vehicle:'); + print(' - player: '+player); + print(' - forward/backward: '+forward); + print(' - strafing: '+strafe); + print(' - jumping: '+jumping); + print(' - sneaking: '+sneaking) +); + +__on_player_uses_item(player, item_tuple, hand) -> +( + l(item, count, nbt) = item_tuple || l('None', 0, null); + print(''); + print('player uses an item:'); + print(' - player: '+player); + print(' - item:'); + print(' > name: '+item); + print(' > count: '+count); + print(' > nbt: '+nbt); + print(' - hand: '+hand) +); + +__on_player_clicks_block(player, block, face) -> +( + print(''); + print('player clicks an item:'); + print(' - player: '+player); + print(' - block: '+block+' at '+map(pos(block), str('%.2f',_))); + print(' - face: '+face) +); + + +__on_player_right_clicks_block(player, item_tuple, hand, block, face, hitvec) -> +( + l(item, count, nbt) = item_tuple || l('None', 0, null); + print(''); + print('block right clicked by player:'); + print(' - player: '+player); + print(' - item: '+item); + print(' - hand: '+hand); + print(' - block: '+block+' at '+map(pos(block), str('%.2f',_))); + print(' - face: '+face); + print(' - hitvec: '+map(hitvec, str('%.2f',_))) +); + +__on_player_breaks_block(player, block) -> +( + print(''); + print('player breaks block:'); + print(' - player: '+player); + print(' - block: '+block+' at '+map(pos(block), str('%.2f',_))) +); + +__on_player_interacts_with_entity(player, entity, hand) -> +( + print(''); + print('player interacts with entity:'); + print(' - player: '+player); + print(' - entity: '+entity+' at '+map(pos(entity), str('%.2f',_))); + print(' - hand: '+hand) +); + +__on_player_attacks_entity(player, entity) -> +( + print(''); + print('player attacks entity:'); + print(' - player: '+player); + print(' - entity: '+entity+' at '+map(pos(entity), str('%.2f',_))) +); + +__on_player_starts_sneaking(player) -> print('Player '+player+' starts sneaking.'); + +__on_player_stops_sneaking(player) -> print('Player '+player+' stops sneaking.'); + +__on_player_starts_sprinting(player) -> print('Player '+player+' starts sprinting.'); + +__on_player_stops_sprinting(player) -> print('Player '+player+' stops sprinting.'); + +__on_player_releases_item(player, item_tuple, hand) -> +( + l(item, count, nbt) = item_tuple || l('None', 0, null); + print(''); + print('player releases an item:'); + print(' - player: '+player); + print(' - item:'); + print(' > name: '+item); + print(' > count: '+count); + print(' > nbt: '+nbt); + print(' - hand: '+hand) +); + +__on_player_finishes_using_item(player, item_tuple, hand) -> +( + l(item, count, nbt) = item_tuple || l('None', 0, null); + print(''); + print('player finishes using an item:'); + print(' - player: '+player); + print(' - item:'); + print(' > name: '+item); + print(' > count: '+count); + print(' > nbt: '+nbt); + print(' - hand: '+hand) +); + +__on_player_drops_item(player) -> print('Player '+player+' drops current item.'); + +__on_player_drops_stack(player) -> print('Player '+player+' drops current stack.');