如何编写NPCs及EVENTS事件的脚本

[十五]如何编写NPCs及EVENTS事件的脚本
前14篇教程到现在这篇,整整搁置了近半年,真是让我惭愧,这其中出现了太多太多的事情,最让我沮丧的是本来已经写好的15和16篇因笔记本硬盘损坏而丢失,导致教程的整理搁浅,也感谢众多热爱UO的和热爱SPHERE脚本编写的玩家和朋友们对我的信任和支持,在今后的脚本整理过程中我会尽我最大的努力把自己对UO的理解和对脚本编写的体会全部奉献给大家,以便能够让更多的人热爱这个虚拟的世界,和我们一起分享她带给我们的快乐,我想这也是大多数优秀UO站点的Staffs们的共同愿望吧… ….几天前的不幸遭遇让我在鬼门关前go了一圈,更加感受到生活在这个世界上的对生存的意义的深深体会。尽管现在躺在病床上的我很无助也很无奈,但我的思绪仍旧没有停止,我的右手还可以动,信息化时代的便捷让我可以从容以笔写的方式来继续这篇教程。。。
一、如何编写NPCs的脚本
写NPC的脚本是件比写物品脚本还有趣的工作,当你看到自己设计的NPC穿着你为他设计的服装和语言以及充满灵气般站在你的面前的时候,是件非常让人兴奋和成就感的事情。记得我曾经在Jarry站修改过一个四处收集过来模仿NPC的脚本,带给大家的是非常快乐的回忆。可以想象一下这样的场面:
在Britain Bank的旁边,一个提着灯笼的NPC在四处游荡,忽然一个衣着入时的PLMM和PLGG出现在他面前,这个NPC忽然变成了和PLGG一摸一样的同样名字的人,于是PLMM头上出现了若干个”?”和”!”,PLGG愤怒起来,大声说道”!!!靠,这是什么?”
哈哈,是不是很funny啊?!今天让我们就以这个脚本为例,和大家探讨一下NPC的脚本的编写。
SPHERE的NPC脚本和物品脚本一样,SPHERE读取脚本的时候,把一个[CHARDEF C_XXXX]这样的语句认为是一个NPC的定义,C_XXXX可以是你任意指定的一个NPC的ID,同样可以用16进制数字来替代。比如是[CHARDEF C_TEST_NPC]这样语句,在游戏里面你就可以用”.ADDNPC C_TEST_NPC”这样的命令行来添加他。前提是这个C_XXXX不可以重复。
更多的时候,我认为SPHERE的脚本不能成为编程,应该说是一个填写表格而已,等于这个表格的行、列名字系统已经帮你命名好并填好了,你只要填写对应的数据就行了。
幻想一下这样的表格:
=========================================================
||  变量  ||   ITEM        ||   NPCS      ||
=========================================================
||  NAMES ||   I_Custom_dye  ||      C_Custom_man  ||
=========================================================
||   ID   ||    I_dye_tub    ||      0190          ||
=========================================================
||CATEGORY||  Custom Items  ||     Custom npcs    ||
=========================================================
||    …  ||      …       ||       …         ||

黑体部分为系统内定的,也就是我前面几个教程所说的那些变量和参数,这些变量和参数分为前面所说的几个大类:角色类、物品类、服务器类等等。其他的则需要你填写的,只是要写成一行行的脚本。而你所填写的就是这些变量或者参数的值。OK,让我们来填写一个NPC的表格吧:

[CHARDEF C_Test_Clonenpc]  //NPC定义开始标记,C_TASK…后面的表示NPC的ID
ID=C_MAN                   //该NPC所具备的外形形态,外形为人
NAME=#NAMES_HUMANMALE the Clone Man   //NPC的名字和TITLE,#NAMES_HUMANMALE是一个
名字的序列,详细列表可以参看spherename.scp里面的定义,系统会随机读取里面的名字。
CAN=MT_WALK|MT_RUN|MT_USEHANDS|MT_EQUIP //NPC具备的能力,详细参考角色及NPC变量
DAM=25,40  //NPC攻击玩家成功的时候伤害值的范围。
ARMOR=70   //NPC的防御等级
TSPEECH=spk_human_prime     //NPC的谈话触发
TSPEECH=spk_human_default
TEVENTS=e_Custom_CloneAI    //NPC的事件触发,这里面是单独定义了一个EVENTS序列。CATEGORY=Custom Npcs     //NPC在AXIS里面SPAWNS属性页里面显示的种类名字
SUBSECTION=Boss NPCs     //NPC的AXIS里面SPAWNS属性页里面显示的子类别
DESCRIPTION=Clone NPCs   //NPC的AXIS里面SPAWNS属性页里面显示的名字

ON=@Create                    //NPC在被创建的时候触发
      NPC=BRAIN_HUMAN       //NPC的头脑类型
COLOR=083f3           //NPC的身体颜色或者用BLOODCOLOR表示血的颜色
FAME ={2000 4000}     //NPC的FAME名望值
KARMA={-4000 -5000}   //NPC的KARMA善恶值
STR={257 400}         //NPC的STR力量值
DEX={254 572}      //NPC的DEX力量值
INT={1476 1573}      //NPC的INT力量值
wrestling={110.0 130.0}      //NPC的拳术技能值
Magery={100.0 160.0}          //NPC的魔法技能值
tactics={150.0 170.0}
      PARRYING  ={90.0 119.0}
ITEMNEWBIE=i_hair_long            //NPC的头发类型
COLOR={0482 0498}                 //NPC的头发颜色
ITEM=i_platemail_gloves           //盔甲,创建后NPC会自动装备,前提是具备MT_EQUIP能力
ITEM=i_platemail_arms             //盔甲
ITEM=i_platemail_gorget
ITEM=i_platemail_chest
ITEM=i_platemail_leggings
ITEM=random_coin_purse
ITEM=i_mt_ostard_forest          //NPC的坐骑

ON=@NPCRESTOCK         //NPC的背包里面的物品,死后可以loot的物品,对于店员NPC的BUY和
                     // SELL的物品必须放在这个触发后面,想让NPC死后可以从身上LOOT
                     //指定物品可以放在这里触发语句后面。NPC每次刷新的时候都会触发

ITEM=i_gold,{500 800}  //物品类型及数量
ITEM=RANDOM_JEWEL       //物品类型及数量
ITEM={ RANDOM_WAND_FIVE 1 RICH_GOLD_PILE 1 RANDOM_JEWEL 1 RANDOM_WEAPON 1 }
ITEM={ random_jewel 1 0 1 }  //物品类型及数量

这样一个NPC的脚本就算写好,之后你再定义一下e_Custom_CloneAI,因为这个是我们自己定义的,也就是所谓NPC的特定的AI,这个需要我们在定义EVENTS事件脚本中详细定义。同样,你也可以把EVENTS中的内容放在NPC脚本后面,只是这样作是为了该事件内的脚本可以重复被多个NPC调用而不会造成脚本过多,从而提高脚本运行的效率。
e_Custom_CloneAI中的内容详细见下面的说明。你可以把这段脚本放在任意一个SPHERE里面带的脚本里面或者自己定义的文件扩展名为.SCP的文件中,但最好不要放在一些特殊的脚本文件里面,比如spheremap.scp、spheredefs.scp、speretables.scp等几个文件里面,因为一方面再刷新的时候会有影响,另一方面在系统读取的时候同样也会报错,我建议您在写这类的脚本的时候最好自己建立一个文件名字(这在sphere55i版本以后使用)
让我们再看一个店员NPC和骑宠的脚本:
下面是一个铁匠铺的NPC,可以出售一些铁匠工具类物品

[CHARDEF 0557]               //NPC定义开始标记
DEFNAME=C_H_BLACKSMITH_F     //在ADDNPC的时候,C_H_BLACKSMITH_F等同于0557
NAME=#NAMES_HUMANFEMALE the Blacksmith  //同上一例的说明
ID=C_WOMAN                         //NPC的外形
DESIRES=i_gold,e_notoriety        //NPC喜欢的物品
AVERSIONS=t_TRAP,t_eerie_stuff    //npc讨厌的类型

TSPEECH=spk_human_prime        //NPC的谈话触发
TSPEECH=jobBlacksmith
TSPEECH=spk_shopkeep
TSPEECH=spk_needs
TSPEECH=spk_rehello
TSPEECH=spk_human_default

TEVENTS=e_Human_HearUnk        //NPC的事件触发序列
TEVENTS=e_Human_Needs
TEVENTS=e_Human_ConvInit
TEVENTS=e_Human_Greet
TEVENTS=e_Human_Space
TEVENTS=e_Human_Refuse
TEVENTS=e_Human_Environ

ON=@Create                   //NPC创建的时候触发
NPC=brain_vendor             //NPC的头脑类型
COLOR=colors_skin            //NPC的皮肤颜色
STR={86 100}                 //NPC的STR属性值
DEX={66 80}
INT={61 75}

MINING={35.0 55.0}          //NPC的技能值
ARMSLORE={65.0 88.0}
BLACKSMITHING={55.0 78.0}
FENCING={35.0 55.0}
PARRYING={35.0 50.0}
SWORDSMANSHIP={35.0 50.0}
WRESTLING={45.0 68.0}
MACEFIGHTING={35.0 50.0}
TACTICS={35.0 55.0}

ITEMNEWBIE=random_female_hair  //npc的头发
COLOR=colors_hair

ON=@NPCRestock            //NPC刷新的时候触发
ITEM=RANDOM_LIGHT         //物品
ITEM=i_shirt_plain
COLOR=colors_all
ITEM=random_skirt
COLOR=colors_all
ITEM=i_apron_full
COLOR=colors_all
ITEM=i_boots_calf
COLOR=colors_neutral
ITEM=random_weapon
ITEM=random_coin_purse

SELL=VENDOR_S_ARMORER_RING    //卖的物品的模板清单
SELL=VENDOR_S_ARMORER_CHAIN
SELL=VENDOR_S_ARMORER_PLATE
SELL=VENDOR_S_ARMORER_SHIELDS
SELL=VENDOR_S_WEAPONS_BLADED
SELL=VENDOR_S_WEAPONS_BLUNT
SELL=VENDOR_S_BLACKSMITH
SELL=VENDOR_S_COLOURED_ARMOR
SELL=VENDOR_S_MAGIC_ARMOR
SELL=VENDOR_S_MAGIC_WEAPONS
BUY=VENDOR_B_ARMORER_RING      //从玩家手里买的物品的模板清单
BUY=VENDOR_B_ARMORER_CHAIN   //这些物品模板可以参考spheretemp_vend.scp里面的相关定义
BUY=VENDOR_B_ARMORER_PLATE
BUY=VENDOR_B_ARMORER_SHIELDS
BUY=VENDOR_B_WEAPONS_BLADED
BUY=VENDOR_B_WEAPONS_BLUNT
BUY=VENDOR_B_BLACKSMITH
BUY=VENDOR_B_COLOURED_ARMOR
BUY=VENDOR_B_MAGIC_ARMOR
BUY=VENDOR_B_MAGIC_WEAPONS

CATEGORY=Civilized             //AXIS里面的spawns属性页类别名字
SUBSECTION=Tradesmen           //AXIS里面的分类属性页名字
DESCRIPTION=Blacksmith (female)  //AXIS里面的显示的名字

再看一个系统自带的一个Mustang野马的脚本:

[CHARDEF 01114]            //npc的定义开始标记
DEFNAME=C_A_MUSTANG_BLACK
NAME=Mustang
SOUND=snd_ANIMALS_HORSE1   //NPC能发出的声音,可选清单见spheredefs.scp里面的定义
ID=c_horse_brown_dk        //外形
ICON=i_pet_horse_brown_dk   //诸如在追踪技能显示出来的小的图标外形
DAM=3,4
ARMOR=9
RESOURCES=15 i_ribs_raw,10 i_hide  //死后被解剖的物品
CAN=MT_WALK|MT_RUN
FOODTYPE=55 t_crops, 55 t_fruit, 55 t_grain, 64 t_grass  //可以吃的食物类型
DESIRES=e_horses,c_man,c_woman   //希望的喜欢的东西
TEVENTS=e_horses                 //具备的触发事件队列
SHELTER=r_stables,e_Human_Greet  //隐蔽地点
AVERSIONS=e_carnivores3         //厌恶的东西和地方
DESCRIPTION=Horse (Black Mustang)  //AXIS里面显示的名字
SUBSECTION=Land (Wild)
CATEGORY=Animals

ON=@Create            //创建时候触发
COLOR=0455
STR={100 180}          //NPC的力量值
DEX={90 130}
INT={6 10}

PARRYING={35.0 45.0}      //NPC的技能值
MAGICRESISTANCE={25.0 30.0}
TACTICS={29.0 44.0}
WRESTLING={29.0 44.0}
TAMING=98.0

NPC=brain_animal

FAME=0                //npc的fame值
KARMA={-1 -99}

二、如何编写EVENTS事件脚本
所谓事件脚本,就是一些触发事件的组合,在遇到这些触发条件触发时,可以执行下面的相关语句。对于一些重复的触发代码,我们就可以定义一个EVENTS,这样在需要调用这些触发的地方用TEVENTS或者EVENTS变量调用就行了。
和CHARDEF和ITEMDEF一样,事件的定义标记是EVENTS,上面我们讲解NPC脚本的时候曾经引用了一个e_Custom_CloneAI事件,下面我就把这个事件的完整脚本列出来和大家一起分析一下:

[EVENTS e_Custom_CloneAI]  //事件定义标记

ON=@NPCSEENEWPLAYER     //看见新玩家的时候触发
IF <SRC.FLAGS>&02      //如果该角色的标记是02即鬼魂
RETURN 0           //结束返回0,继续动作,如果是1就停止执行下面的语句
ENDIF                //结束IF语句
if <src.npc>      //如果看见的是NPC
   return 0     //结束这个判断继续下面的语句
endif             //结束IF语句

IF !(<SRC.COLOR>==<COLOR>)  //如果看到的对象的颜色和自己的颜色不相同
COLOR=<SRC.COLOR>         //颜色和看到的对象的皮肤颜色相同
BODY=<SRC.BODY>            //身体外形和看到的对象的身体外形相同
NAME=<SRC.NAME>             //名字和看到的对象的名字相同
ENDIF                      //结束IF判断语句

FINDLAYER(1).REMOVE     //删除自己的LAYER(1),关于LAYER可以参考以前的教程里面描述
FINDLAYER(2).REMOVE     //左手
FINDLAYER(3).REMOVE
FINDLAYER(4).REMOVE
FINDLAYER(5).REMOVE
FINDLAYER(6).REMOVE
FINDLAYER(7).REMOVE
FINDLAYER(8).REMOVE
FINDLAYER(9).REMOVE
FINDLAYER(10).REMOVE
FINDLAYER(11).REMOVE
FINDLAYER(12).REMOVE
FINDLAYER(13).REMOVE
FINDLAYER(14).REMOVE
FINDLAYER(15).REMOVE
FINDLAYER(16).REMOVE
FINDLAYER(17).REMOVE
FINDLAYER(18).REMOVE
FINDLAYER(19).REMOVE
FINDLAYER(20).REMOVE
FINDLAYER(22).REMOVE
FINDLAYER(24).REMOVE
FINDLAYER(25).REMOVE

IF <FINDID.i_spellbook>  //如果发现魔法书
FINDID.i_spellbook.REMOVE  //删除
ENDIF              //结束IF

IF <SRC.FINDID.i_spellbook> //如果看到对象身上有魔法书
SRC.NEWITEM i_spellbook    //添加一本魔法书
SRC.ACT.MORE1=<SRC.FINDID.i_spellbook.MORE1>&06c2a0885  //设置魔法书的内容
SRC.ACT.MORE2=<SRc.FINDID.i_spellbook.MORE2>&0fb576671   //同上,设置为攻击类魔法
SRC.ACT.CONT=<FINDLAYER(21).SERIAL>  //设置该物品的容器为自己的背包
ENDIF

IF <SRC.FINDLAYER(1)>           //如果发现对象的右手上有东西
SRC.NEWITEM <SRC.FINDLAYER(1).ID>  //添加一个相同ID的物品
SRC.ACT.NAME=<SRC.FINDLAYER(1).NAME>  //名字相同
SRC.ACT.COLOR=<SRC.FINDLAYER(1).COLOR>  //颜色相同
SRC.ACT.MOREP=<SRC.FINDLAYER(1).MOREP>  //morep值相同
SRC.ACT.ATTR=<SRC.FINDLAYER(1).ATTR>|04 //属性为不新人属性
EQUIP <SRC.ACT.SERIAL>             //装备这个物品
ENDIF                             //结束IF语句

IF <SRC.FINDLAYER(2)>                //同上
SRC.NEWITEM <SRC.FINDLAYER(2).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(2).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(2).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(2).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(2).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(3)>
SRC.NEWITEM <SRC.FINDLAYER(3).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(3).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(3).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(3).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(3).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(4)>
SRC.NEWITEM <SRC.FINDLAYER(4).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(4).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(4).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(4).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(4).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(5)>
SRC.NEWITEM <SRC.FINDLAYER(5).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(5).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(5).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(5).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(5).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(6)>
SRC.NEWITEM <SRC.FINDLAYER(6).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(6).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(6).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(6).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(6).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(7)>
SRC.NEWITEM <SRC.FINDLAYER(7).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(7).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(7).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(7).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(7).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(8)>
SRC.NEWITEM <SRC.FINDLAYER(8).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(8).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(8).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(8).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(8).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(9)>
SRC.NEWITEM <SRC.FINDLAYER(9).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(9).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(9).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(9).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(9).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(10)>
SRC.NEWITEM <SRC.FINDLAYER(10).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(10).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(10).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(10).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(10).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(11)>
SRC.NEWITEM <SRC.FINDLAYER(11).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(11).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(11).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(11).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(11).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(12)>
SRC.NEWITEM <SRC.FINDLAYER(12).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(12).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(12).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(12).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(12).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(13)>
SRC.NEWITEM <SRC.FINDLAYER(13).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(13).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(13).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(13).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(13).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(14)>
SRC.NEWITEM <SRC.FINDLAYER(14).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(14).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(14).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(14).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(14).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(15)>
SRC.NEWITEM <SRC.FINDLAYER(15).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(15).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(15).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(15).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(15).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(16)>
SRC.NEWITEM <SRC.FINDLAYER(16).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(16).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(16).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(16).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(16).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(17)>
SRC.NEWITEM <SRC.FINDLAYER(17).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(17).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(17).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(17).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(17).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(18)>
SRC.NEWITEM <SRC.FINDLAYER(18).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(18).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(18).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(18).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(18).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(19)>
SRC.NEWITEM <SRC.FINDLAYER(19).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(19).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(19).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(19).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(19).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(20)>
SRC.NEWITEM <SRC.FINDLAYER(20).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(20).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(20).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(20).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(20).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(22)>
SRC.NEWITEM <SRC.FINDLAYER(22).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(22).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(22).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(22).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(22).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(24)>
SRC.NEWITEM <SRC.FINDLAYER(24).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(24).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(24).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(24).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(24).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF <SRC.FINDLAYER(25)>
SRC.NEWITEM <SRC.FINDLAYER(25).ID>
SRC.ACT.NAME=<SRC.FINDLAYER(25).NAME>
SRC.ACT.COLOR=<SRC.FINDLAYER(25).COLOR>
SRC.ACT.MOREP=<SRC.FINDLAYER(25).MOREP>
SRC.ACT.ATTR=<SRC.FINDLAYER(25).ATTR>|04
EQUIP <SRC.ACT.SERIAL>
ENDIF

IF !(STRCMPI(<NAME>,<SRC.NAME>) ==0)
NAME=<SRC.NAME>
HITS=<STR>
UPDATE
RETURN 1
ENDIF
UPDATE

ON=@DEATH    //死的时候触发
SRC.FINDLAYER(25).LINK.REMOVE  //删除layer(25)的link
SRC.FINDLAYER(25).REMOVE   //删除坐骑

怎么样,这样的脚本编写是不是很简单啊?同样你不仅仅可以只在这个EVENTS里面加入看到NPC触发,同样可以让他拥有受到魔法伤害的时候触发,或者被攻击的时候触发等等。
再来看一个NPC的AI设计:

[EVENTS e_Custom_NPCsAI]

ON=@SPELLEFFECT   //受到魔法影响的时候触发

IF (<ARGN> ==20 )&&(<eval RAND(5)> ==2)  //当受到下毒魔法时候并且随机数为2的时候触发
      SAY “An Nox”           //念咒语
Effect 2,0376a,6,15,0  //身上有解毒魔法的效果
Spelleffect 11,<Magery> //施展解毒魔法
Sound snd_SPELL_CURE   //解毒魔法施展时候的声音
return 1                 //结束返回1
ElseIF(<hits> <100)&&(<eval RAND(12)> ==8)  //当hits值小于100并且随机数为8时触发
SAY  “In Vas Mani”      //同上,念咒
      Effect 3,0376a,6,15,0
      Sound snd_SPELL_GREATER_HEAL
      hits=<hits>+100
      RETURN 1
ENDIF

ON=@gethit           //受到物理攻击的时候触发
if (<flags> & 080)&&(<eval RAND(5)> ==2)  //如果是中毒状态并且随机数为2
SAY “An Nox”
Effect 2,0376a,6,15,0
Spelleffect 11,<Magery>
Sound snd_SPELL_CURE
return 1
ELSEif (<hits> <100)&&(<eval RAND(10)> ==6)  //同上
hits=<hits>+100    //血值HITS自动加100
emote apply bandages to self.  //EMOTE,NPC头上出现红色的you see…的字样
RETURN 1  //结束返回 1
endif    //结束ENDIF

这样,如果你想让NPC具备自动解毒和补血的功能,就象第一个NPC的定义那样再ON=@CREATE上面用这样的语句调用这个EVENTS
TEVENTS=e_Custom_NPCsAI
这样,该NPC就会具备了上面的这个事件中定义的一些触发特性,比如被毒的时候会解毒,血少的时候会自动加血了。这些事件脚本和NPC、物品脚本一样都可以放在自己定制的一些脚本文件里面。比如另存为这样的文件:
Custom_npcs.scp
Custom_items.scp
Custom_events.scp
… …

ahah,手真的好痛了,护士MM说你是不是不想出去了?5555,今天先写到这里吧,不知道大家对sphere的脚本认识是不是又加深了许多理解呢?希望是这样吧!一个好的建议就是在写脚本的时候最好能够做到边写边调试琢磨,并仔细看别人写的或者系统自带的脚本,这样可以让你的印象更加深刻,不要老是问别人一些可以通过自己仔细思考一下就可以解决的小问题。

留言

还没有留言,来坐个沙发吧。

留个言

留个言