t1546542
本帖最后由 t1546542 于 2020-1-9 22:09 编辑

版本:1.14.4
如题
为什么
  1. execute as @e[type=sheep] at @s rotated as @p run tp ~ ~ ~
复制代码
可以改变羊的朝向

  1. execute as @e[type=sheep] at @s rotated as @p run tp @s ~ ~ ~
复制代码
却不行呢
@Chelove_C60 @SPGoding

纱夜
本帖最后由 阴阳师元素祭祀 于 2020-1-9 18:44 编辑

tp ~ ~ ~ [~ ~]
[ ]为默认参数(也就是rotated as时的样子
tp @s ~ ~ ~ []
表示不改变视角(不确定)
也许你可以试试
tp @s ~ ~ ~ ~ ~
//???
以上是乱猜
建议看mc代码

tp .. x y z 视角 视角

SPGoding
这题这么简单,怎么没人答呢?


太长不看

代码:

  1. tp ~ ~ ~
完全等价于

代码:

  1. tp @s ~ ~ ~ ~ ~
不等价于

代码:

  1. tp @s ~ ~ ~
前两者会把命令执行者的朝向修改为当前上下文中的朝向,最后一者不会。





相关漏洞:MC-169660





引入
首先引入一个概念,上下文(context)。所有的命令在执行的时候都有一个上下文,这个上下文中包含了命令的执行者、执行坐标、朝向等。execute 命令中 as、at、positioned、rotated 等子命令的原理就是更改上下文中的对应的内容为指定的值。


当我们的 tp 命令执行时,由前面的一串 execute 命令修改过后的上下文中的关键内容是这样的(下文将用带颜色的字表示是上下文中的内容):

代码:

  1. execute as @e[type=sheep] at @s rotated as @p run ...
执行者
坐 标羊的坐标
朝 向@p 的朝向


下面分别叙述两种 tp 写法的大体技术细节,简化了一堆无关内容。


tp @s ~ ~ ~
该种写法在执行时,有关朝向的部分是这样处理的:

代码:

  1. if (rotation == null) {
  2.    teleport(... entity.yaw, entity.pitch ...);
  3. } else {
  4.    teleport(... rotation.y, rotation.x ...);
  5. }
如果没有在命令里写朝向,就把实体的朝向设置为该实体原先的朝向(即不变);
如果写了,则把实体的朝向设置为你指定的。


最终 tp @s ~ ~ ~ 的执行效果为:
执行者的坐标设置为坐标执行者的朝向设置为执行者的朝向。
替换一下:
的坐标设置为羊的坐标的朝向设置为的朝向。即什么都不变,转向失败


tp ~ ~ ~
通常认为,tp ~ ~ ~ 和 tp @s ~ ~ ~ 完全等价。这是在胡扯。让我们康康 tp ~ ~ ~ 这一命令是怎么注册的:

代码:

  1. .then(...(...(...(..., DefaultPosArgument.zero(), null))))
简单明了,我们一眼就能发现,它设置了一个 DefaultPosArgument.zero() 的参数作为朝向!这一参数是一个偏移为 0 的相对坐标,相当于我们在命令里写的 ~ ~。这使得

代码:

  1. tp ~ ~ ~
完全等价于

代码:

  1. tp @s ~ ~ ~ ~ ~

我们上面说过,游戏会根据 rotation 是否为 null 来有不同的做法。此处,由于 rotation 被设置为了 ~ ~ 而不是 null,因此走的是下面的那一条分支:

代码:

  1. teleport(... rotation.y, rotation.x ...);

我们还需要有一个常识:相对坐标永远是根据当前上下文中的对应内容来解析的。


最终 tp ~ ~ ~,也就是 tp @s ~ ~ ~ ~ ~ 的执行效果为:
执行者的坐标设置为坐标执行者的朝向设置为按照朝向解析的偏移为零的相对坐标(也就是朝向)。
替换一下:
的坐标设置为羊的坐标的朝向设置为按照@p 的朝向解析的偏移为零的相对坐标(也就是@p 的朝向)。转向成功。


以上。



第一页 上一页 下一页 最后一页