本篇教程由作者设定未经允许禁止转载。

教程基于Psi+1.16-91,推荐配合magicpsi一同食用(magicpsi有汉化)。


CAD

Psi中的施法工具。

启动式

启动式是psi术式中最核心的模块,是玩家通过CAD干涉周遭事物的直接手段。

常量

Psi术式中由玩家预先设定不变的参数。

运算符

通过CAD收集并处理环境数据的模块。

选择符

能直接获取特定数据的模块。

错误处理符

处理CAD施法报错的模块。

 

对象

对象是psi中玩家能通过术式直接操作的单位,比如一组数据或是一个实体。

Psi中所有启动式都需要指定一种对象才能发动,比如爆炸必须指定坐标,BUFF效果必须指定实体,而放置和破坏则必须指定一个方块,值得注意的是,由于坐标和方块一一对应,所以实际上对方块的指定是以直接指定该方块所处坐标完成的。比如破坏视线指向的方块,实际进行的操作应该是先获取该方块的坐标,然后破坏该坐标的方块,而不是单纯的直接破坏方块。

顺带一提,psi中的向量和坐标是同一概念而且满足向量运算法则,举例来说,我们使用轴向向量追踪获取一个方块的侧面法向量,假如指向方块上表面,获取到的向量就是[0,1,0],此时我们使用方块破坏术式,世界上位于0,1,0这个位置的方块也会被破坏。

 

调试

图形化编程也是编程,是编程就免不了调试。

[启动式:调试]能将某一模块的输出值编号并打印在聊天栏中。举例来说,我们现在要设计一个全自动采石场术式,但在执行过程中发现了错误就很难去改。但如果我们把每一次术式执行处的坐标都通过调试编号打印到聊天栏中,就很容易看出是从哪一步开始出错的。

 

CAD参数

强大的术式也需要强大的工具才能施放。正如所有奇幻作品中那样,威力越是巨大的法术所要消耗的魔力和代价就越大,施放的条件也越苛刻。而psi中条件主要有以下几个:

复杂度:术式执行的操作总数。

复杂度越大说明要执行该术式需要的运算次数越多,术式越复杂。

强度:术式威力的量化。

强度是术式威力的量化同时也是术式威力的规定上限。

消耗:单次释放该术式所需的psi能量。

根据施法类型的不同,术式所需的能量消耗和利用效率也会发生变化。

映射:启动式总数。

单个术式能完成不同功能的最大数值。

容量:术式高度和宽度的最大值。

 

节能

随着术式威力的提高,要消耗的psi能量也随之上升。

启动式一般都会有一个初始消耗。举例来说,[启动式:破坏方块序列]破坏一个方块需要60点psi,但破坏两个方块则只需要95,以此类推按顺序破坏十个方块总共消耗375点psi。但[启动式:破坏方块]破坏一个方块只需要50点psi,破坏十次的话需要高达500点psi,由于单次执行术式psi能量会停止回复,所以在某些情况下,前者更为节能。

高消耗的术式伴随着强大的效果,而随着有些启动式等级的逐级上升,与之匹配的消耗上升却是呈几何式的。比如施加一秒凋零效果,一级需要140psi,二级440,三级940,四级1640。但是施加四秒钟的一级凋零效果消耗440psi该生物会扣两次血,施加一秒钟的二级凋零效果同样消耗440psi只对该生物造成一次伤害,适当调整参数就能用同样的消耗达成更好的实际效果。

 

施法类型

Psi的施法分为普通,投射,循环,圈阵,爆炸,遥控和陷阱七种。这其中施法类型各有优缺点,熟练应用不同施法类型才能做出更强的术式。

普通施法:单次施法。单次施法的参数一般为固定值,不能随时改变。

投射型施法:消耗更多psi发射出一枚不受重力影响的飞弹,飞弹碰撞到实体或者方块时启动术式,[选择符:目标实体]能直接选定碰撞到的实体,[选择符:焦点]输出的坐标也是该飞弹所处位置。飞弹发射后会逐渐降低速度并在一定时间后消失,如果飞弹没碰撞到任何方块或实体术式就不会发动。

循环型施法:发动循环施法后只要手握CAD就会以每秒四次的速度执行术式,循环施法不同于单次施法,施法时psi能量也会回复,同时[选择符:循环施法指针]能输出该术式的当此执行次数,这使得玩家能在术式中完成变量的效果,通过数学运算能够让参数有规律地进行变化。

圈阵型施法:圈阵型施法会瞬间消耗能量并将术式执行20次,与之相对的,圈阵型施法会获得25%的psi消耗减免,[选择符:循环施法指针]同样应用于圈阵施法,这也使得在设计中小型法术时,比起循环施法,圈阵施法有更大的优势。

爆炸型施法:爆炸型施法和投射型施法的效果几乎完全一致,但是爆炸型施法接触到目标后不会直接展开,而是会在施法三秒后自动展开术式,而且它受重力影响,需要注意的是,该术式接触到实体后会记录下最后接触到的实体,这使得该术式只要砸到了实体,最后无论怎样都能对该实体进行影响。

遥控型施法:和爆炸型施法效果一致,但该术式会在世界上存在五分钟且不会自动触发,而是需要玩家用术式引发器或者对应启动式激活。

陷阱型施法:顾名思义,如同地雷一般,当实体踩中该术式后离开时激活,会存在五分钟。

 

传感器和触发事件

胸甲:玩家受伤时

护腿:每TICK触发一次

靴子:玩家进行一次跳跃

光传感器:所处亮度较低时

水传感器:玩家在水里时

热传感器:玩家着火时

压力传感器:玩家生命低于三颗心时

陷阱传感器:玩家周围32格有陷阱型术式被触发时

顾名思义,在以上条件被满足时,该条件对应的术式就会被触发。


理论和废话也听够了,现在来点实战,我们先构建一个最简单的调试术式。

如何用PSI做一个实用术式-第1张图片

首先添加一个调试,将目标输入指向常量1,执行术式,聊天栏中便会打印出目标输入指向的字符了。

如何用PSI做一个实用术式-第2张图片


好了,你已经会构建术式了,下面我们编写一个稍微实用一点的。

普通术式受限于能量回复等问题并不能作为大型术式的施法类型,强大的魔法必然伴随着巨量的魔法消耗,拥有psi能量减免的圈阵施法是我们的不二选择。

在原版,特别是较高版本中,攻击CD和地狱更新的强力怪物或许会成为很多萌新玩家的拦路虎,而众所周知,psi秉承vazkii的设计理念,完全杜绝了直接伤害,玩家想要伤害怪物需要使用摔落,buff,燃烧,溺水这些特殊效果,对于最常见的怪物来说,溺水和燃烧泛用性都不足,而在前文中也提到使用高等级buff需要消耗的魔力量巨大,摔落伤害似乎是最节能也是最效率的选择。

如何用PSI做一个实用术式-第3张图片

蓝色线框是延迟施法模块,设定一个初始值95,循环施法指针从1开始计数,将其乘以5再由初始赋值95的变量减去就能得到从95到0的二十组数据作为延迟。这会让20次术式在最后同时执行。

红色线框是目标选取,获取法阵周围怪物列表,用群体附加运动给列表内实体附加一个向上的速度1运动向量。

由于延迟施法,红色部分的术式会在圈阵消失的瞬间被执行二十次,怪物获得远超1的垂直速度,被送上一百格的高空摔落致死。

有意思的是这个术式对群所需的魔力增量寥寥无几,释放一次理论所需魔力只有1575点,而且检索列表使用的是敌对生物列表,也就是说该术式能在一堆实体中只杀死敌对生物,具体演示可以参考https://www.bilibili.com/video/BV1py4y1U7gY

参考代码:

{modsRequired:[{modVersion:"1.16-88",modName:"psi"}],spellName:"Voyage1969",uuidMost:-5024520592077141127L,validSpell:1b,spellList:[{data:{params:{_time:2},key:"psi:trick_delay"},x:0,y:0},{data:{params:{_target:4,_constant:2},key:"psi:constant_wrapper"},x:0,y:1},{data:{key:"psi:constant_number",constantValue:"95"},x:0,y:2},{data:{key:"psi:constant_number",constantValue:"1"},x:0,y:3},{data:{params:{_target:1},key:"psi:connector"},x:0,y:4},{data:{params:{_number2:4,_number3:0,_number1:2},key:"psi:operator_subtract"},x:1,y:1},{data:{params:{_target:3},key:"psi:connector"},x:1,y:2},{data:{params:{_direction:2,_speed:3,_target:4},key:"psi:trick_mass_add_motion"},x:1,y:3},{data:{params:{_x:0,_y:3,_z:0},key:"psi:operator_vector_construct"},x:1,y:4},{data:{key:"psi:selector_loopcast_index"},x:2,y:0},{data:{params:{_number2:2,_number3:0,_number1:1},key:"psi:operator_multiply"},x:2,y:1},{data:{key:"psi:constant_number",constantValue:"5"},x:2,y:2},{data:{params:{_position:2,_radius:0},key:"psi:selector_nearby_enemies"},x:2,y:3},{data:{params:{_target:4},key:"psi:operator_entity_position"},x:2,y:4},{data:{key:"psi:error_suppressor"},x:3,y:3},{data:{key:"psi:selector_focal_point"},x:3,y:4}],uuidLeast:-8607468769685488773L}



PSI简易珍珠控制

如何用PSI做一个实用术式-第4张图片首先做一个极简的珍珠缓存塔。

如何用PSI做一个实用术式-第5张图片

如何用PSI做一个实用术式-第6张图片

投入珍珠后珍珠会受气泡柱影响漂浮在水面。

原版珍珠炮是利用单选器输出数据经编码解码加载TNT阵列给予经动量消除和位置校准的珍珠初动量,再用无延迟红石导线沿路径加载区块使珍珠将玩家传送至预先设置的地点。那么如何用psi实现呢?

psi可以直接读取实体坐标以及操作其动量,但要求同时输入多组数据需要用到不止一个术式,所以地点选择直接由预先设置的术式编写台就能完成,同时追求结构简单所以并不需要对落点进行精确校准,直接调整参数就能将落点误差控制在十格以内。

如果要追求精确传送,可以使用珍珠缓存器。

如何用PSI做一个实用术式-第7张图片

这种结构也较为简单,用psi输出珍珠坐标显示xz动量已完全消除,y动量仅有5个浮动量,中短距离误差控制较好。

如何用PSI做一个实用术式-第8张图片使用鬼畜活塞对珍珠进行进一步控制可以使y动量误差从+-0.2845减少到+-0.045,误差缩小了数倍。CAD只能由玩家施法,故不能使用红石进一步缩小误差了,比起最简的水流式发射塔,珍珠缓存器做两台就能实现高精度的大范围传送,值得一试。

如何用PSI做一个实用术式-第9张图片

下方xz坐标提供落点坐标,考虑泛用性,y轴坐标进行人工校准。首先使用[运算符:向量构造]表示落点位置,而后使用[选择符:附近投射物]得到附近的投射物列表,[选择符:随机实体]配合[运算符:实体位置]获得末影珍珠具体坐标,由落点和珍珠坐标作差可得到珍珠到落点的向量,由于珍珠受重力影响且未消除y轴动量,在构造落点向量时调高y参数抵消重力影响,最后使用上文的圈阵延迟施法,对珍珠附加二十次动量将珍珠射出。

珍珠移动也受到区块加载影响,所以珍珠路径必须加载区块,教程使用了鸡牌区块加载器,也可使用其他mod的加载器或者使用原版的无延迟导线进行区块加载。

这种方法误差不大,建造极为简单,可用于单人生存和装有psi的中小型服务器。此处贴出参考代码。

{modsRequired:[{modVersion:"1.16-91",modName:"psi"}],spellName:"珍珠移动",uuidMost:-8065623370078597451L,validSpell:1b,spellList:[{data:{params:{_time:2},key:"psi:trick_delay"},x:0,y:0},{data:{params:{_target:4,_constant:2},key:"psi:constant_wrapper"},x:0,y:1},{data:{key:"psi:constant_number",constantValue:"95"},x:0,y:2},{data:{key:"psi:constant_number",constantValue:"2.5"},x:0,y:3},{data:{params:{_target:2},key:"psi:connector"},x:0,y:5},{data:{key:"psi:constant_number",constantValue:"128"},x:0,y:6},{data:{key:"psi:error_suppressor"},x:1,y:0},{data:{params:{_number2:4,_number3:0,_number1:2},key:"psi:operator_subtract"},x:1,y:1},{data:{params:{_target:3},key:"psi:connector"},x:1,y:2},{data:{params:{_direction:2,_speed:3,_target:4},key:"psi:trick_mass_add_motion"},x:1,y:3},{data:{params:{_vector3:0,_vector2:4,_vector1:2},key:"psi:operator_vector_subtract"},x:1,y:4},{data:{params:{_x:3,_y:2,_z:4},key:"psi:operator_vector_construct"},x:1,y:5},{data:{key:"psi:constant_number",constantValue:"139"},x:1,y:6},{data:{key:"psi:selector_loopcast_index"},x:2,y:0},{data:{params:{_number2:2,_number3:0,_number1:1},key:"psi:operator_multiply"},x:2,y:1},{data:{key:"psi:constant_number",constantValue:"5"},x:2,y:2},{data:{params:{_target:4},key:"psi:connector"},x:2,y:3},{data:{params:{_target:4},key:"psi:operator_entity_position"},x:2,y:4},{data:{params:{_target:2},key:"psi:connector"},x:2,y:5},{data:{key:"psi:constant_number",constantValue:"1139"},x:2,y:6},{data:{params:{_position:4,_radius:0},key:"psi:selector_nearby_projectiles"},x:3,y:3},{data:{params:{_target:1},key:"psi:operator_random_entity"},x:3,y:4},{data:{params:{_target:2},key:"psi:operator_entity_position"},x:4,y:3},{data:{key:"psi:selector_focal_point"},x:4,y:4}],uuidLeast:-7950268267028308394L}