TA的每日心情 | 郁闷 2022-5-30 11:17 |
---|
签到天数: 20 天 [LV.4]偶尔看看III
管理员
  
- 积分
- 73795
|
一.创建任务目录
在...\data\jscript\quests上创建一个目录
二.把任务目录加入到目录列表
任务列表文件在...\data\jscript\quests下的__init__.py
用记事本打开可以看到
复制代码
- 1.'1_LettersOfLove1',
- 2.'2_WhatWomenWant1',
- 3.'3_ReleaseDarkelfElder1',
- 4.'4_LongLiveLordOfFlame',
- 5.'5_MinersFavor',
- 6.'6_StepIntoTheFuture',
- 7.'7_ATripBegins',
- 8.'8_AnAdventureBegins',
- 9.'9_IntoTheCityOfHumans',
- 10.'10_IntoTheWorld',
- 11.'19_GoToThePastureland',
- 12.'32_AnObviousLie',
- 13.'33_MakeAPairOfDressShoes',
- 14.'34_InSearchOfClothes',
- 15.'35_FindGlitteringJewelry',
- 16.'36_MakeASewingKit',
- 17.'37_PleaseMakeMeFormalWear',
- 18.'39_RedEyedInvaders',
- 19.'42_HelpTheUncle',
- 20.'43_HelpTheSister',
- 21.'44_HelpTheSon',
- 22.'45_ToTalkingIsland',
- 23.'46_OnceMoreInTheArmsOfTheMotherTree',
- 24.'47_IntoTheDarkForest',
- 25.'48_ToTheImmortalPlateau',
- 26.'49_TheRoadHome',
- 27.'101_SwordOfSolidarityQuest',
- 28.'102_FungusFever',
- 29.'103_SpiritOfCraftsman',
- 30.'104_SpiritOfMirror',
- 31.'105_SkirmishWithOrcs',
- 32.'106_ForgottenTruth',
复制代码
格式:
复制代码
- 1.'目录名',
- 2.添加在__all__ = [
- 3.]
- 4.print ""
- 5.print "importing quests ..."
- 6.from data.jscript.quests import *
- 7.
- 8.print"... done"
复制代码
之间
.
任务列表部分完成.
=三.任务__init__.py编写
__init__.py文件头数据
利用这些语句执行任务的JAVAclass
复制代码
- 1.print "importing quests: 607: Prove your courage!"
- 2.import sys
- 3.from net.sf.l2j.gameserver.model.quest import State
- 4.from net.sf.l2j.gameserver.model.quest import QuestState
- 5.from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest
复制代码
'Class QuestJython'是任务信息
'Class State'任务中每一阶段的状态
'QuestState'相关玩家进行任务的状态/信息
基本上都要执行这些语句
==================================
任务相关NPC/道具等等
例如
复制代码
- 1.KELTIR_NPC_ID = 12082 // 任務NPC
- 2.FANGS_ITEM_ID = 1859 // 任務道具
- 3.DROP_RATE = 500000 // 任務道具掉落率
- 4.WORLD_MAP_ITEM_ID = 1665 // 任務獎勵 ,
复制代码
复制代码
- 1.#Items
- 2.HEAD_OF_SHADITH_ID = 7235
- 3.TOTEM_OF_VALOR_ID = 7219
- #NPCs
- KADAN_ZU_KETRA_ID = 8370
复制代码
尽量使用这种方法,不过,如果你的技术高超的话可以用其他语句/方法.
所以尽量使你的PY文件更容易读会更好些.
=帮助任务判别的方法
复制代码- 1.def getCount(st) : // st是指QuestState
- 2.return st.getQuestItemsCount(FANGS_ITEM_ID)
复制代码
注意例如FANGS_ITEM_ID是变量来的,必须在上面定义
例如FANGS_ITEM_ID = 15205
就是任务道具为15205
=上面是任务系统在玩家在执行任务中,检查/增加/减少人一些功能语句
复制代码- 1.def completed(st) : // st是指QuestState
- 2.st.setState(COMPLETED) // ?#93;任务完成状态
- 3.st.clearQuestDrops()
- 4.st.takeItems(FANGS_ITEM_ID,-1) // 将任务道具回收
- 5.st.giveItems(WORLD_MAP_ITEM_ID,1) // 给予玩家任务奖励
- 6.st.exitQuest(False) // 此任务不能重复执行
- 7.return
复制代码
这个功能是用来结束任务,用来回收任务道具和给予道具
=====
复制代码- 1.def check(st) :
- 2.if getCount(st) >= 4 : // 任务道具4个以上
- 3. completed(st)
- 4.return
复制代码
这段代码是用来确认玩家身上的道具数量,从而使任务结束.
=================================
四.任务本身
代码:
复制代码- 1.class Quest (JQuest):
- 2.
- 3.def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)
- 4.
- 5.def onEvent (self,event,st):
- 6. id = st.getState()
- 7. if id == CREATED : st.setState(STARTED)
- 8. elif id == COMPLETED: pass
- 9. elif id == STARTED : check(st)
- 10. return
复制代码
任务是由 python class 所构成的,它是由 java class 延伸出来的。
在这裡我们用了一个任务触发的方法 (onEvent)。
在 def __init__(self,id,name,descr) 裡的定义:
代码:
- self // 关於任务
- id // 任务在客户端的编号代码
- name // 任务名称,必须与L2jserver的任务名称相同
- descr // 任务描述,会在客户端显示出来
复制代码
而 def onEvent (self,event,st) 裡的定义:
代码:
- self // 关於目前这个任务
- event // 一个字串的定义,可以被java?#123;式触发
- st // QuestState的状态,可以提供玩家目前任务进行的资讯
复制代码
5. 说明 onEvent 的方法
代码:
我们将玩家目前任务进行的状态数值宣告,它会被存入 id 。
接著我们检查任务的状态,并且使任务状态转移到新的状态。
代码:
- if id == CREATED : st.setState(STARTED)
复制代码
如果玩家触发了任务,状态为 (state CREATED) ,那麼任务状态
将转移至 (state STARTED) 。
代码:
- elif id == COMPLETED: pass
复制代码
如果玩家已经完成任务,那我们在这就不处理它。
代码:
- elif id == STARTED : check(st)
复制代码
如果玩家仍然在任务进行中,那麼我们呼叫
我们之前所宣告的功能,来检查任务道具数量。
代码:
- def check(st) :
- if getCount(st) >= 4 : // 任务道具4个以上
- completed(st)
- return
复制代码
如果玩家身上的道具数量足够的话,那任务状态
就直接进入结束状态 (state COMPLETED) 。
在这个范例中,我们并没有检查 (event) 的状态,因为
所有的 (Event) 的发生状态都是经由与 NPC 对话所发生的
,所以 (onEvent) 被呼叫的话,一定是玩家与 NPC 对话。
6. 宣告任务状态
代码:
- QUEST = Quest(201,"Tutorial", "Tutorial quest")
- CREATED = State('Start', QUEST)
- STARTED = State('Started', QUEST)
- COMPLETED = State('Completed', QUEST)
复制代码
每一个状态都连结一个对话 (html) ,所以当状态发生时,
都会显示一个对话:
状态 (CREATED) 发生时,出现 start.htm
状态 (STARTED) 发生时,出现 started.htm
状态 (COMPLETED) 发生时,出现 Completed.htm
代码:
- QUEST.setInitialState(CREATED)
- QUEST.addStartNpc(7056) // 任务触发 NPC
复制代码
现在我们要为这个任务宣告触发状态及任务触发 NPC 。
代码:
- <a action="bypass -h npc_%objectId%_Quest">任务</a>
复制代码
在触发 NPC 的 html 裡要有这段连结来触发任务。
7. 宣告任务道具掉落
代码:
- STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)
复制代码
设定玩家在 (STARTED) 状态时,任务道具掉落、机率及猎杀的怪物。
8. 任务编写完成
代码:
复制代码- 1.import sys
- 2.from net.sf.l2j.gameserver.model.quest import State
- 3.from net.sf.l2j.gameserver.model.quest import QuestState
- 4.from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest
- 5.
- 6.
- 7.KELTIR_NPC_ID = 12082
- 8.FANGS_ITEM_ID = 1859
- 9.DROP_RATE = 500000
- 10.WORLD_MAP_ITEM_ID = 1665
- 11.
- 12.
- 13.def getCount(st) :
- 14.return st.getQuestItemsCount(FANGS_ITEM_ID)
- 15.
- 16.def completed(st) :
- 17.st.setState(COMPLETED)
- 18.st.clearQuestDrops()
- 19.st.takeItems(FANGS_ITEM_ID,-1)
- 20.st.giveItems(WORLD_MAP_ITEM_ID,1)
- 21.st.exitQuest(False)
- 22.return
- 23.
- 24.def check(st) :
- 25.if getCount(st) >= 4 :
- 26. completed(st)
- 27.return
- 28.
- 29.class Quest (JQuest):
- 30.
- 31.def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)
- 32.
- 33.def onEvent (self,event,st):
- 34. id = st.getState()
- 35. if id == CREATED : st.setState(STARTED)
- 36. elif id == COMPLETED: pass
- 37. elif id == STARTED : check(st)
- 38. return
- 39.
- 40.QUEST = Quest(201,"Tutorial", "Tutorial quest")
- 41.CREATED = State('Start', QUEST)
- 42.STARTED = State('Started', QUEST)
- 43.COMPLETED = State('Completed', QUEST)
- 44.
- 45.QUEST.setInitialState(CREATED)
- 46.QUEST.addStartNpc(7056)
- 47.
- 48.STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)
- 49.
复制代码
这个任务已经完成,并可以在伺服器上执行了。
我们来说明一下这个任务的流程:
I. 玩家向 NPC (ID 7056) 对话并触发任务,此时任务的状态
为 CREATED ,同时显示对话 Start.htm 。
II. 而 Start.htm 会呼叫 (onEvent) 这个功能,使得任务的状态
转变为 STARTED ,同时显示对话 Started.htm 。
III. 在 STARTED 的状态下,会使任务怪物掉落任务道具。
在这个状态下,玩家也许会回去找 NPC 对话,此时 (onEvent)
功能会被再呼叫,在这个状态下, check(st) 功能会检查玩家
身上是否有足够的任务道具,如果没有足够的任务道具,会再
次出现 Started.htm 。如果玩家有足够的道具, check(st) 会
将任务状态转换至 COMPLETED 的状态,收回玩家身上的任务
道具,并给予玩家奖励,而同时会出现对话 Completed.htm 。
以上这个任务只用了 onEvent 这个功能,其实还有另外两个功能
尚未使用到, onTalk 和 onKill ,这两个功能类似 onEvent,
使用时机不同而已。
在以上的范例中,我们并没有宣告 onTalk or onKill 这两种功能,
所以整个任务的流程都是使用 onEvent 这个功能。
onEvent 功能和这两个功能不同的地方是, onTalk or onKill 是针对
在任务中玩家与NPC对话或是猎杀任务怪物死亡后呼叫的功能。
9. 加入 onKill 功能
代码:
- STARTED.addKillId(KELTIR_NPC_ID)
复制代码
我们再加入在 STARTED 状态之下,猎杀任务怪物后,呼叫 onKill 功能。
代码:
- class Quest (JQuest):
- ...
- def onKill (self,npcId,st):
- if npcId == KELTIR_NPC_ID:
- n = getCount(st)
- if n == 0:
- return "Chat0.htm"
- elif n == 1:
- return "Chat1.htm"
- elif n >= 4:
- return "Chat4.htm"
- return "Collected "+str(n)+" of 4 fangs"
- return
复制代码
onKill 的定义:
代码:
- self // 关於任务
- npcID // 被猎杀的怪物 ID
- st // 玩家目前的任务状态 (QuestState)
复制代码
代码:
检查玩家身上的任务道具。
代码:
- if n == 0:
- return "Chat0.htm"
复制代码
如果玩家身上没有任务道具,则会显示 Chat0.htm 。
代码:
- elif n == 1:
- return "Chat1.htm"
复制代码
如果玩家身上只有1个任务道具或是不足4个时,则显示 Chat1.htm 。
代码:
- elif n >= 4:
- return "Chat4.htm"
复制代码
如果玩家身上已经有4个任务道具时,则显示 Chat4.htm 。
经由 onEvent、onTalk 和 onKill 而 return 的字串值,结尾是 .htm 时
L2j server 就会将它显示在客户端,让玩家知道。
在此范例中:
代码:
- Chat0.htm 的内容可能是"快去猎杀怪物吧......等等"
- Chat1.htm 的内容可能是"你只有一个任务道具.......等等"
- Chat4.htm 的内容可能是"任务完成,回去找 NPC 吧.....等等"
复制代码
当然经由 onEvent、onTalk 和 onKill 而 return 的字串值不一定要是
.htm 结尾,也可以开头用 <html> 的语法来达成同样的目的。
代码:
代码:
- return "<html><body>任务完成,回去找NPC吧</body></html>"
复制代码
以上两个都会被 L2j server 所接受。
如果 return 的字串值不是以上两种,而我们想用系统来让客户端显示。
代码:
- return "Collected "+str(n)+" of 4 fangs"
复制代码
这样客户端就以系统通知玩家"收集了N个任务道具\"。
不过我们现在这个范例的 onKill 功能,有些问题,它会一直重复显示
Chat0.htm、Chat1.htm、Chat4.htm,我们现在只想要它出现一
次就可以,如何达成这个目的呢?
代码:
- def onKill (self,npcId,st):
- if npcId == KELTIR_NPC_ID:
- n = getCount(st)
- if n == 0:
- if st.get('chat0') == None :
- st.set("chat0", "true")
- return "Chat0.htm"
- elif n == 1:
- if st.get('chat1') == None :
- st.set("chat1", "true")
- return "Chat1.htm"
- elif n >= 4:
- return "Chat4.htm"
- return "Collected "+str(n)+" of 4 fangs"
- return
复制代码
我们可以用变数来达成,每一个任务都会储存字串值在资料库裡当作变数,
在这个范例我们使用 set 、 get 和 unset 来设定变数。
代码:
- if n == 0:
- if st.get('chat0') == None :
复制代码
当玩家没有任务道具时(n==0),我们得到 (get) "chat0" 这个变数,当
第一次 onKill 被呼叫时,系统并没有这个变数,所以系统返回 None 值,
显示 Chat0.htm 。
代码:
- if n == 0:
- if st.get('chat0') == None :
- st.set("chat0", "true") // 系统取得变数
- return "Chat0.htm"
复制代码
当我们猎杀任务怪物(未掉落任务道具)时,系统会经由 st.set("chat0", "true")
返回 true ,这个范例中系统返回 None 才会显示 Chat0.htm ,所以现在
系统不会显示 Chat0.htm。
代码:
- return "Collected "+str(n)+" of 4 fangs"
复制代码
因为我们还有经由系统通知玩家,所以会显示"收集了N个任务道具\"。
10. 任务全貌
代码:
复制代码- 1.import sys
- 2.from net.sf.l2j.gameserver.model.quest import State
- 3.from net.sf.l2j.gameserver.model.quest import QuestState
- 4.from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest
- 5.
- 6.
- 7.KELTIR_NPC_ID = 12082
- 8.FANGS_ITEM_ID = 1859
- 9.DROP_RATE = 500000
- 10.
- 11.WORLD_MAP_ITEM_ID = 1665
- 12.
- 13.
- 14.def getCount(st) :
- 15.return st.getQuestItemsCount(FANGS_ITEM_ID)
- 16.
- 17.def completed(st) :
- 18.st.setState(COMPLETED)
- 19.st.clearQuestDrops()
- 20.st.takeItems(FANGS_ITEM_ID,-1)
- 21.st.giveItems(WORLD_MAP_ITEM_ID,1)
- 22.st.exitQuest(False)
- 23.return
- 24.
- 25.def check(st) :
- 26.if getCount(st) >= 4 :
- 27. completed(st)
- 28.return
- 29.
- 30.class Quest (JQuest):
- 31.
- 32.def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)
- 33.
- 34.def onEvent (self,event,st):
- 35. id = st.getState()
- 36. if id == CREATED : st.setState(STARTED)
- 37. elif id == COMPLETED: pass
- 38. elif id == STARTED : check(st)
- 39. return
- 40.
- 41.def onKill (self,npcId,st):
- 42. if npcId == KELTIR_NPC_ID:
- 43. n = getCount(st)
- 44. if n == 0:
- 45. if st.get('chat0') == None :
- 46. st.set("chat0", "true")
- 47. return "Chat0.htm"
- 48. elif n == 1:
- 49. if st.get('chat1') == None :
- 50. st.set("chat1", "true")
- 51. return "Chat1.htm"
- 52. elif n >= 4:
- 53. return "Chat4.htm"
- 54. return "Collect "+str(n)+" of 4 fangs"
- 55. return
- 56.
- 57.QUEST = Quest(201, "Tutorial", "Tutorial quest")
- 58.CREATED = State('Start', QUEST)
- 59.STARTED = State('Started', QUEST)
- 60.COMPLETED = State('Completed', QUEST)
- 61.
- 62.QUEST.setInitialState(CREATED)
- 63.QUEST.addStartNpc(7056)
- 64.QUEST.addStartNpc(7012)
- 65.QUEST.addStartNpc(7009)
- 66.QUEST.addStartNpc(7011)
- 67.
- 68.STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)
- 69.STARTED.addKillId(KELTIR_NPC_ID)
- 70.STARTED.addTalkId(7056)
- 71.STARTED.addTalkId(7012)
- 72.STARTED.addTalkId(7009)
- 73.STARTED.addTalkId(7011)
复制代码
以上就是我们写出来的任务.
以上文章是引用了L2JTW的root写"Jython Quest 任務編寫:在此感谢ROOT
|
|