大家好,
我本来打算这么做一段时间了,但因为最近离开了Shaiya版块的人,我被永久封禁了。
总之,这就是一个关于如何创建自定义怪物AI(AI的缩写)的简短教程。
首先,Shaiya 中的 AI 是什么意思?你能用它做些什么?
- 当某个怪物触发某个事件时,召唤多个怪物。比如:当怪物达到满血80%时,你可以让它复制自己。你还可以选择事件触发后新怪物生成的位置,这使得自定义AI比Obelisk.ini中更灵活
- 解锁传送门。
- 让被这个AI影响的怪物改变攻击类型或使用其他攻击技能。
- 让怪物说话。
- 删除怪物。
- 还有更多你可能想自己研究的酷炫内容。
这种设定在游戏中只在两张地图上出现。这和地图本身无关,除了这些地图分别是Caelum Sacra F1(光明)、Caelum Sacra F1(狂怒)和Caelum Sacra F2,正如你可能已经知道的,受自定义AI影响的怪物(我们将在本教程中引导)都是迪奥斯·埃克西尔和他的4名护卫的形态。 永恒者、加加德尔、惠斯塔顿和卢希尔。
我们开始吧。你需要的文件显然存储在服务器端,比如PSM_Client\Bin\Data\Lua文件夹。
我认为理解这一点最好的方法是给还没有AI的怪物应用自定义AI。你只需要跟着教程操作,完全按照教程操作。如果你做得对,你很可能会理解这个过程。
假设我们拿Dentatus,给它应用一个自定义的AI,它能做以下事情:
- 第一部分:当你开始攻击它时,它会侮辱你。
- 第二部分:当它的生命值达到75%时,Secreta会出现,Dentatus会说出相关话语。
- 第三部分:当它的生命值达到50%时,Lumen会刷新,Dentatus会说出相关话语。
- 第四部分:当生命值达到25%时,Ales会刷新,Dentatus会说出相关话语,同时开始使用死亡吐息。
- 第五部分:当它快死时,登塔图斯会彻底诅咒你,并承诺复仇。
如果你从没动过.lua文件,那么你拥有的最高自定义AI肯定是118。从那个文件夹里拿任何 .lua 文件,复制并粘贴到同一个文件夹里。把它重命名为119.lua,然后用记事本打开。
第一行大概是这样写的:
代码:
-- Д«АП·л »зЕ©¶у єёЅє 2Вч_єРЅЕ јТИЇµЗ±вАь ёуЅєЕН_ID-2470 AI 117.Lua ver.090113
我划线的两个数字分别代表你想应用AI的生物ID和AI编号,所以基本上应该是这样的:
代码:
-- Д«АП·л »зЕ©¶у єёЅє 2Вч_єРЅЕ јТИЇµЗ±вАь ёуЅєЕН_ID-2821 AI 119.Lua ver.090113
以下行表示自定义AI的初始化:
这3条线代表3个变量的初始化:
代码:
dwNextCreateTime = 0bMobSay = 0bMobCreate = 0
这些行是函数声明:
代码:
function Init()endfunction OnAttacked( dwTime, dwCharID )endfunction OnAttackable( dwTime, dwCharID )endfunction OnNormalReset( dwTime )endfunction OnDeath( dwTime, dwAttackedCount )endfunction OnReturnHome( dwTime, dwAttackedCount )endfunction OnMoveEnd( dwTime )endfunction WhileCombat( dwTime, dwHPPercent, dwAttackedCount )end
对于我们最初设定的目标,我们本可以使用更多上述函数,但我决定把所有代码都放进最后一个函数,也就是函数 WhileCombat。
第一部分:
我们得让登塔图斯侮辱我们。怪物说的一切都在客户端,也就是sysmsg-uni.txt。到底部,重新划一条线。本教程将使用从12001开始的行数。
它应该是这样的:
代码:
12001 "My name is Dentatus and yo mama's so fat that she's stuck at the login page."
代码:
if ( dwHPPercent >= 95 ) thenif ( bMobSay < 1) thenMob:LuaSayByIndex ( 12001, 200.0 )bMobSay = bMobSay + 1endend
因为我决定把所有要做的事情都存储在WhileCombat函数里,我们必须检查怪物的生命值。通常你不能一击杀死Dentatus,所以第一行检查Dentatus的生命值是否达到95%或以上,这肯定是这样。第二行检查变量bMobSay,这是怪物说话次数的计数器。第二行是让怪物真正说话的那行,第一个参数代表它需要显示的字符串索引,取自sysmsg-uni.txt。第四行是增加bMobStay变量的地方,它同样是怪物说话次数的计数器。AI即使没有它也能工作,但正如你看到的第二行,我们需要记录怪物说话的次数。
第二部分:
我们需要让Dentatus达到75%时,Secreta会出现,并且Dentatus会说出相关的话。
文本会放在WhileCombat函数里,就在我们为目标第一部分写的那个下面。
代码:
if ( dwHPPercent <= 75 ) thenif ( bMobSay < 2) thenMob:LuaSayByIndex ( 12002, 200.0 )bMobSay = bMobSay + 1endMob:LuaCreateMob ( 2803, 1, 0.0, 0.0 )end
如你所见,有一个新函数其实非常容易理解,但我还是会稍后解释。LuaCreateMob函数负责生成新怪物。这四个参数代表MobID生成的数量,以及X轴和Z轴上的坐标,显示指定数量的怪物。如果坐标是0.0,它会生成在AI应用的怪物所在的位置。
第三
部分自己完成应该不难,因为它和第二部分非常相似。
第四部分:
我们需要让丹塔图斯的生命值达到25%时,艾尔斯会出现,丹塔图斯会说出相关话语,并且开始使用死亡吐息。
代码:
if ( dwHPPercent <= 25 ) thenif ( bMobSay < 4) thenMob:LuaSayByIndex ( 12004, 200.0 )bMobSay = bMobSay + 1endMob:LuaCreateMob ( 2785, 1, 0.0, 0.0 )Mob:LuaAttackAI ( 173 )end
你还不熟悉的功能是LuaAttackAI。它允许使用另一个技能,该参数代表你想让怪物使用的技能的SkillID,取自NpcSkill.SData。NpcSkill.SData 是位于客户端 Data\Monster 文件夹里的文件。如果你想用 Shaiya Studio 打开它,可以把它重命名为 Skill.SData。在那里你可以找到所有怪物可用的技能。服务器端的相应技能位于数据库中的PS_GameDefs.dbo.Skills中,技能等级=100。
第五部分和第二、三部分一样,写起来应该没问题。
测试
前,别忘了把AI分配给怪物,这里是Dentatus:
代码:
UPDATE PS_GameDefs.dbo.MobsSET AI = 119WHERE MobID = 2821
需要服务器重启才能应用这些更改。
附言:我大学时用的是上世纪组装的电脑写的这个教程,所以一切都源自我的脑海。我之前在测试服务器上做过这件事,成功了。如果这方法不如预期,我回家后会进一步了解。