本帖最后由 kongbaiyo 于 2015-9-6 19:23 编辑

======================前言======================


/stats这个指令 在MC的所有指令中算是比较难懂的一个了
上一个帖子我讲过之后,有很多少年发现了一些问题
我也发现我讲的不是很透彻
于是我又做了一个例子,思考了很久 想把这个指令讲透彻
上一个教程的链接:http://www.mcbbs.net/thread-399876-1-1.html
推荐先看上一个!
"更高级的安检门” 演示看视频~
[bili=2873533]1[/bili]

======================stats本质======================

接下来我就来说说/stats命令的本质
stats命令的本质可以理解成"重定向"
也就是把命令执行结果重定向至一个计分板 这在上个教程里我也说过
stats创建了命令执行结果与计分板的链接

而这种链接是怎么实现的?执行命令的实体/方块如何知道
它的执行结果要往哪一个计分板输出呢?
而这个信息就是存储在方块/实体的NBT中的

来自英文wiki:

CommandStats: Information identifying scoreboard parameters to modify relative to the last command run.
  • SuccessCountName: Player name to store success of the last command. Can be a player selector but may only have one resulting target.
  • SuccessCountObjective: Objective's name to store the success of the last command.
  • AffectedBlocksName: Player name to store how many blocks were modified in the last command. Can be a player selector but may only have one resulting target.
  • AffectedBlocksObjective: Objective's name to store how many blocks were modified in the last command.
  • AffectedEntitiesName: Player name to store how many entities were altered in the last command. Can be a player selector but may only have one resulting target.
  • AffectedEntitiesObjective: Objective's name to store how many entities were altered in the last command.
  • AffectedItemsName: Player name to store how many items were altered in the last command. Can be a player selector but may only have one resulting target.
  • AffectedItemsObjective: Objective's name to store how many items were altered in the last command.
  • QueryResultName: Player name to store the query result of the last command. Can be a player selector but may only have one resulting target.
  • QueryResultObjective: Objective's name to store the query result of the last command.



这便是用过stats指令的方块/实体会拥有的NBT值

也就是说 stats是通过看一个方块/实体的有关stats的NBT值
来决定它向哪个玩家/实体的计分板输出信息

也就是说/stats指令的格式中(以实体为例)
/stats entity <玩家名> set <模式> <玩家名2> <计分板变量名>
<玩家名2> 所指的实体
是以被使用/stats的实体为中心的<玩家名2>

所以 /stats的工作方式是这样的(以实体为例)
实体执行命令->得到输出结果->将输出结果赋予以实体为中心<玩家名2>的计分板变量

这便是对"重定向"的理解


举个例子吧
把所有玩家执行命令的成功次数 重定向至他们自己的test变量里
/stats entity @a set SuccessCount @p test
注意@a和@p的使用

这下 更高级安检门的 原理就迎刃而解了

======================具体流程======================


第一步是建立安检门 也就是在安检门处放一个装备架
testforItem变量用于检测铁锭物品
testforDoor用于比对铁锭周围的方块是否是安检门的样子
createDoor用于判断要生成的安检门的方向是什么
#检测铁锭
/scoreboard players set @e[type=Item] testforItem 1 {Item:{id:"minecraft:iron_ingot",Damage:0s,Count:1b}}
#创建链接
/stats entity @e[type=Item,score_testforItem_min=1] set AffectedBlocks @e[type=Item,score_testforItem_min=1,c=1] testforDoor
#初始化计分板
/scoreboard players set @e[type=Item,score_testforItem_min=1] testforDoor 0
#探测并标记
/execute @e[type=Item,score_testforItem_min=1] ~ ~ ~ /testforblocks 897 55 16 895 59 16 ~-1 ~-1 ~
/scoreboard players set @e[type=Item,score_testforItem_min=1,score_testforDoor_min=1] createDoor 1
/execute @e[type=Item,score_testforItem_min=1] ~ ~ ~ /testforblocks 896 55 12 896 59 10 ~ ~-1 ~-1
/scoreboard players set @e[type=Item,score_testforItem_min=1,score_testforDoor_min=1] createDoor 2
#生成装备架
/execute @e[type=Item,score_testforItem_min=1,score_createDoor_min=2,score_createDoor=2] ~ ~ ~ /clone 894 55 12 894 59 10 ~ ~-1 ~-1
/execute @e[type=Item,score_testforItem_min=1,score_createDoor_min=1,score_createDoor=1] ~ ~ ~ /clone 897 55 18 895 59 18 ~-1 ~-1 ~
(把安检门复制到铁锭物品处)
/execute @e[type=Item,score_testforItem_min=1,score_createDoor_min=1] ~ ~ ~ /summon ItemFrame ~ ~ ~ {CustomName:"doorFrame"}
(在物品处生成一个物品展示框 用于生成位于方块中心的装备架 青皮帖子里有讲)
/execute @e[type=ItemFrame,name=doorFrame] ~ ~ ~ /kill @e[type=Item,score_testforItem_min=1,score_createDoor_min=1,r=0]
/execute @e[type=ItemFrame,name=doorFrame] ~ ~ ~0.46875 /summon ArmorStand ~ ~ ~ {CustomName:"door",NoGravity:1}
/kill @e[type=ItemFrame,name=doorFrame]


接下来就是在上一篇教程中也写过的 检测玩家背包中物品数量
playerIngotCount变量用于记录玩家背包中铁锭数量
#检测玩家状态
/execute @e[type=ArmorStand,name=door] ~ ~ ~ /stats entity @a[r=10] set AffectedItems @p playerIngotCount
(建立链接)
/execute @e[type=ArmorStand,name=door] ~ ~ ~ /scoreboard players set @a[r=10] playerIngotCount 0
(初始化计分板)
/execute @e[type=ArmorStand,name=door] ~ ~ ~ /execute @a[r=10] ~ ~ ~ /clear @p minecraft:iron_ingot 0 0
(让玩家执行命令)

然后检测安检门周围有无手里有两个铁锭以上的玩家 同样用到stats
doorStatus表示门开或关的状态
#检测装备架状态
/stats entity @e[type=ArmorStand,name=door] set SuccessCount @e[type=ArmorStand,name=door,c=1] doorStatus
(建立链接)
/scoreboard players set @e[type=ArmorStand,name=door] doorStatus 0
(初始化计分板)
/execute @e[type=ArmorStand,name=door] ~ ~ ~ /testfor @a[r=10,score_playerIngotCount_min=2]
(让盔甲架执行命令)

最后开关门
#开关门
/stats entity @e[type=ArmorStand,name=door] clear SuccessCount
/execute @e[type=ArmorStand,name=door,score_doorStatus_min=1] ~ ~ ~ /fill ~ ~ ~ ~ ~1 ~ wool
/execute @e[type=ArmorStand,name=door,score_doorStatus=0] ~ ~ ~ /fill ~ ~ ~ ~ ~1 ~ air


将近三十条命令完成这个小作品

======================结语======================

/stats这个指令很冷门 主要就是因为它比较难理解
希望我讲了两回之后 各位能更好的利用这个命令XD

下载地址:http://pan.baidu.com/s/1bnvzYI7
文件名:[CBL·K_bai] 教程 [20150906].zip
[groupid=546]Command Block Logic[/groupid]