下面小编为大家带来我的世界使用datapack制作弓箭的自动瞄准挂的教程,自动瞄准是许多玩家的追求,那么下面的内容你就不能错过哦!
我们拿Tag——话说"Tag"这个词还有"#"这个符号被s.bmj赋予的意义太多了——hacker表示神仙,target表示被瞄准的目标,marker表示玩家鼠标要瞄的地方。先来做一个最简单的吧:
# spgoding_hacker:_init/init
# 首先把下面要用到的变量全部定义,以后就不提了,可以不看这部分,都是dummy没什么特别的。
# 储存target的motion
scoreboard objectives add xMotion dummy
scoreboard objectives add yMotion dummy
scoreboard objectives add zMotion dummy
# 储存target位置
scoreboard objectives add xTarget dummy
scoreboard objectives add yTarget dummy
scoreboard objectives add zTarget dummy
# 储存hacker位置
scoreboard objectives add xHacker dummy
scoreboard objectives add yHacker dummy
scoreboard objectives add zHacker dummy
# 储存marker位置
scoreboard objectives add xMarker dummy
scoreboard objectives add yMarker dummy
scoreboard objectives add zMarker dummy
# 储存距离
scoreboard objectives add xDistance dummy
scoreboard objectives add zDistance dummy
scoreboard objectives add d dummy
# 储存marker的变化距离
scoreboard objectives add xDelta dummy
scoreboard objectives add yDelta dummy
scoreboard objectives add zDelta dummy
# 常数
scoreboard objectives add value dummy
scoreboard players set c1 value 1
scoreboard players set c10000 value 10000
scoreboard players set c200 value 200
# 临时变量
scoreboard objectives add tmp dummy
# modules
function spgoding_hacker:sqrt/init
# spgoding_hacker:tick
# 给你要瞄准的东西加target
# 这里比较偷懒,正经使用时小心锁上火球之类的东西…
tag @e[type=!player,type=!area_effect_cloud,type=!item,type=!arrow] add target
# 确保有一个marker
execute unless entity @e[tag=marker] run summon area_effect_cloud ~ ~ ~ {Tags:["marker"],Duration:2147483647}
# 获取离hacker最近的target的坐标,放大1000倍
# 当然很容易溢出【摊手,我能怎么办,我也很绝望
execute at @p[tag=hacker] store result score @s xTarget run data get entity @e[sort=nearest,tag=target,limit=1] Pos[0] 1000
execute at @p[tag=hacker] store result score @s yTarget run data get entity @e[sort=nearest,tag=target,limit=1] Pos[1] 1000
execute at @p[tag=hacker] store result score @s zTarget run data get entity @e[sort=nearest,tag=target,limit=1] Pos[2] 1000
# 计算出marker的位置
# x坐标:
scoreboard players operation @p[tag=hacker] xMarker = @p[tag=hacker] xTarget
# y坐标:
scoreboard players operation @p[tag=hacker] yMarker = @p[tag=hacker] yTarget
# z坐标
scoreboard players operation @p[tag=hacker] zMarker = @p[tag=hacker] zTarget
# 改变marker位置
# 为啥不直接tp? 这不是为咱后面做准备嘛
execute store result entity @e[tag=marker,limit=1] Pos[0] double 0.001 run scoreboard players get @p[tag=hacker] xMarker
execute store result entity @e[tag=marker,limit=1] Pos[1] double 0.001 run scoreboard players get @p[tag=hacker] yMarker
execute store result entity @e[tag=marker,limit=1] Pos[2] double 0.001 run scoreboard players get @p[tag=hacker] zMarker
# 让hacker锁定marker
execute as @p[tag=hacker] at @s anchored eyes if entity @e[tag=target,sort=nearest,limit=1] run tp @s ~ ~ ~ facing entity @e[tag=marker,limit=1] eyes
reload,然后使用/tag add @s hacker把自己变成神仙,弄几只动物,你就发现准心会锁着离你最近的target了。但现在这个辅助瞄准只适合即时命中且无重力的这类武器,可惜mc vanilla里并没有这种东西存在。远距离我们的辅助瞄准根本没用,因此我们做一些更改。
首先使其能够预判弹道下坠。原理:根据target与hacker之间的距离,改变marker的y坐标,达到玩家准心提高的效果。
# 添加以下命令
# 获取hacker的坐标,放大1000倍
execute store result score @p[tag=hacker] xHacker run data get entity @p[tag=hacker] Pos[0] 1000
execute store result score @p[tag=hacker] yHacker run data get entity @p[tag=hacker] Pos[1] 1000
execute store result score @p[tag=hacker] zHacker run data get entity @p[tag=hacker] Pos[2] 1000
# 计算target与hacker的水平距离(垂直距离呢?那抛物线太玄学了,我们不考虑。假设玩家和目标接近同一水平面。)
# 计算原理:d=√[(x ^2-x^2)^2+(z^2-z^2)^2]
# 下面是计算xDistance^2
scoreboard players operation @p[tag=hacker] xDistance = @p[tag=hacker] xTarget
scoreboard players operation @p[tag=hacker] xDistance -= @p[tag=hacker] xHacker
scoreboard players operation @p[tag=hacker] xDistance *= @p[tag=hacker] xDistance
# 下面计算zDistance^2
scoreboard players operation @p[tag=hacker] zDistance = @p[tag=hacker] zTarget
scoreboard players operation @p[tag=hacker] zDistance -= @p[tag=hacker] zHacker
scoreboard players operation @p[tag=hacker] zDistance *= @p[tag=hacker] zDistance
# 下面算出d
scoreboard players operation @p[tag=hacker] d = @p[tag=hacker] xDistance
scoreboard players operation @p[tag=hacker] d += @p[tag=hacker] zDistance
# 开根号与今天的教程无关,所以spgoding_hacker:sqrt/calculate的
# 内容就不放了,开根号部分大家可以看chyx dalao的讲解,很详细XD:www.bilibili.com/av17932394
# 不知有没有不用开根号的方法?或许我做得太麻烦了,求指点~
scoreboard players operation @p[tag=hacker] sqrtInput = @p[tag=hacker] d
execute as @p[tag=hacker] run function spgoding_hacker:sqrt/calculate
scoreboard players operation @p[tag=hacker] d = @p[tag=hacker] sqrtOutput
# 根据d我们可以算出准心要抬高的距离
# 根据测试,大约每20格,需要抬高准心1格,即
# deltaY = d / 20 * 1 (这其实不很准确,你有更精确的数值/方法可以替换)
# cXX 是玩家假名,其值在_init/init里已经设置为XX
# 所以为什么是c200?我也不知道啊(摊手)瞎加零试出来的#run反正能用
scoreboard players operation @p[tag=hacker] yDelta = @p[tag=hacker] d
scoreboard players operation @p[tag=hacker] yDelta /= c200 value
scoreboard players operation @p[tag=hacker] yDelta *= c1 value
# 计算出marker的位置
# x, z坐标不变,y坐标:
scoreboard players operation @p[tag=hacker] yMarker = @p[tag=hacker] yTarget
scoreboard players operation @p[tag=hacker] yMarker += @p[tag=hacker] deltaY
# “改变marker位置”开始命令不变,不再赘述
现在,我们的准心会根据hacker与target的位置而预判弹道下坠啦。但即使如此,这个挂也只适用于即时命中的弹道武器,很遗憾minecraft vanilla里也没有这种东西。
为了让弓表现得更好,我们可以预判target的走位。原理:根据d,估计出箭到达target的时间;由时间与motion估计出target的位移(显然这是不准确的,但可以保证命中率),由位移计算出marker应当在的位置。
# spgoding_hacker:tick
# 加入以下代码:
# 获取离hacker最近的target的Motion,放大1000倍
execute as @p[tag=hacker] at @s store result score @s xMotion run data get entity @e[sort=nearest,tag=target,limit=1] Motion[0] 1000
execute as @p[tag=hacker] at @s store result score @s yMotion run data get entity @e[sort=nearest,tag=target,limit=1] Motion[1] 1000
execute as @p[tag=hacker] at @s store result score @s zMotion run data get entity @e[sort=nearest,tag=target,limit=1] Motion[2] 1000
# 下面我们预判一下target的走位
# 首先估计一下箭到达target的时间tmp(懒得改名了,就tmp了):
scoreboard players operation @p[tag=hacker] tmp = @p[tag=hacker] d
# 这里的c15000完全是经验之谈【逃
scoreboard players operation @p[tag=hacker] tmp /= c15000 value
# 然后根据tmp和Motion估计一下位移
scoreboard players operation @p[tag=hacker] xDelta = @p[tag=hacker] xMotion
scoreboard players operation @p[tag=hacker] xDelta *= @p[tag=hacker] tmp
scoreboard players operation @p[tag=hacker] zDelta = @p[tag=hacker] zMotion
scoreboard players operation @p[tag=hacker] zDelta *= @p[tag=hacker] tmp
# 计算出marker的位置
# x坐标:
scoreboard players operation @p[tag=hacker] xMarker = @p[tag=hacker] xTarget
scoreboard players operation @p[tag=hacker] xMarker += @p[tag=hacker] xDelta
# y坐标(命令未改动):
scoreboard players operation @p[tag=hacker] yMarker = @p[tag=hacker] yTarget
scoreboard players operation @p[tag=hacker] yMarker += @p[tag=hacker] yDelta
# z坐标
scoreboard players operation @p[tag=hacker] zMarker = @p[tag=hacker] zTarget
scoreboard players operation @p[tag=hacker] zMarker += @p[tag=hacker] zDelta
现在,已经是一个完美的辅助瞄准了……吗?并不是,minecraft vanilla里的弓箭有扩散,距离远了以后并不能保证命中率。同时距离过远,target的运动不可预测,这该怎么办呢?
古人曾经说过,打得准不如接得准
因此,我们可以使用以下一句终极命令,我就用它来结束今天的教程:
#spgoding_hacker:final_tick
execute at @p[tag=hacker] run teleport @e[tag=target,limit=1,sort=nearest] ^ ^ ^1
Thx for your watching!
19游戏网整理报道