-
Notifications
You must be signed in to change notification settings - Fork 167
How to create NPC script
Etorth edited this page Jun 16, 2022
·
8 revisions
<map_name>.<npc_name>.lua
an example:
道馆_1.栗子商人_1.lua
here map_name
is where the NPC stands, npc_name
is the NPC's name, if there are NPC's with same name, use _<index>
as in the example, name duplication is common in mir3, like several 六面神石
on same map.
Put the script in <server-dir>/script/npc
to get automatically loaded.
local function onSellChestnut(uid, chestnutName, currTagName, lastTagName)
local priceTable = {
['金色栗子'] = 10000,
['银色栗子'] = 5000,
['铜色栗子'] = 2000,
['褐色栗子'] = 1000,
}
if priceTable[chestnutName] == nil then
fatalPrintf('Invalid chestnut name: %s', tostring(chestnutName))
end
if uidUseItem(uid, chestnutName, 1) then
uidPostGold(uid, priceTable[chestnutName])
uidPostXML(uid,
[[
<layout>
<par>请收下<t color="red">%d</t>金币</par>
<par></par>
<par><event id="%s" arg="%s">还卖其它的%s</event></par>
<par><event id="%s">前一步</event></par>
<par><event id="%s">关闭</event></par>
</layout>
]], priceTable[chestnutName], currTagName, chestnutName, chestnutName, lastTagName, SYS_NPCDONE)
else
uidPostXML(uid,
[[
<layout>
<par>哼,你没带%s来,快去找!</par>
<par></par>
<par><event id="%s">关闭</event></par>
</layout>
]], chestnutName, SYS_NPCDONE)
end
end
setEventHandler(
{
[SYS_NPCINIT] = function(uid, value)
if uidQueryRedName(uid) then
uidPostXML(uid,
[[
<layout>
<par>跟你这种人我无话可说。</par>
<par></par>
<par><event id="%s">关闭</event></par>
</layout>
]], SYS_NPCDONE)
else
uidPostXML(uid,
[[
<layout>
<par>欢迎光临,对,我就是买栗子的。 如果你能给我找来那些味道又好,营养又好的栗子,我就送你一份大礼。</par>
<par>你有栗子吗?</par>
<par></par>
<par><event id="npc_goto_trade" arg="金色栗子">带来了金色栗子,你要卖吗?</event></par>
<par><event id="npc_goto_trade" arg="银色栗子">带来了银色栗子,你要卖吗?</event></par>
<par><event id="npc_goto_trade" arg="铜色栗子">带来了铜色栗子,你要卖吗?</event></par>
<par><event id="npc_goto_trade" arg="褐色栗子">带来了褐色栗子,你要卖吗?</event></par>
<par><event id="%s">马上去给你找</event></par>
</layout>
]], SYS_NPCDONE)
end
end,
["npc_goto_trade"] = function(uid, value)
onSellChestnut(uid, value, "npc_goto_trade", SYS_NPCINIT)
end,
})
Another example to support daily quest, quests are modeled by FSM, take 铁匠
as example:
local events = rotable({
{name = 'event::接受任务' , from = 'state::可接受任务' , to = 'state::已接受任务' },
{name = 'event::集齐所需矿石' , from = 'state::已接受任务' , to = 'state::已经收集到所需矿石'},
{name = 'event::把矿石交给NPC', from = 'state::已经收集到所需矿石', to = 'state::任务完成' },
})
local callbacks = rotable({
['on_enter_state::' ... '接受任务'] = function(uid)
uidExecute(uid, [[
addTrigger(ON_ADDITEM, function(item)
if hasInventoryItem('黑铁矿', 5) then
fsm.trigger('event::集齐所需矿石')
return true
end
return false
end)
]])
end
['on_enter_state::' ... 'state::已经集齐需要的矿石'] = function(uid)
uidExecute(uid, [[
postString('已经收集齐了所需黑铁矿,把它们交给王铁匠把!')
]])
end
['on_enter_state::' ... 'state::任务完成'] = function(uid)
uidExecute(uid, [[
addDailyQuestDoneCount()
]])
end
})
local fsm = require('statemachine').create(events)
setEventHandler(rotable
{
[SYS_NPCINIT] = function(uid, value)
local dailyQuestString <const> = (function()
if uidQueryDailyQuestNPCName() == getNPCFullName() then
return '<par><event id = "npc_goto_daily_quest_initial">对今日任务进行了解</event></par>'
else
return ''
end
end())
uidPostXML(uid,
[[
<layout>
<par>客官%s你好我是%s,你需要什么帮助?<emoji id="0"/></par>
<par></par>
<par><event id="npc_goto_common_service">日常服务</event></par>
%s
<par></par>
<par><event id="%s">关闭</event></par>
</layout>
]], uidQueryName(uid), getNPCName(), dailyQuestString, SYS_NPCDONE)
end,
['npc_goto_common_service'] = function(uid, value)
uidPostXML(uid,
[[
<layout>
<par>我不会。。。</par>
<par><event id="%s">关闭</event></par>
</layout>
]], SYS_NPCDONE)
end,
['npc_goto_daily_quest_initial'] = function(uid, value)
uidPostXML(uid,
[[
<layout>
<par>我需要5个纯度15以上的黑铁矿,你能帮我找到吗?我会有丰厚的酬谢!</par>
<par></par>
<par><event id="npc_goto_daily_quest_accept">好的我这就去帮你找</event></par>
<par><event id="npc_goto_daily_quest_refuse">我再考虑考虑</event></par>
<par></par>
<par><event id="%s">关闭</event></par>
</layout>
]], SYS_NPCDONE)
end
['npc_goto_daily_quest_accept'] = function(uid, value)
fms:trigger('接受任务')
uidPostXML(uid,
[[
<layout>
<par>那就谢谢你了!</par>
<par></par>
<par><event id="%s">关闭</event></par>
</layout>
]], SYS_NPCDONE)
end
})