好象没有人出过这方面的系统。。快开学了,趁有时间去www.wc3jass.com上淘了一个给大家
原贴地址:http://www.wc3jass.com/viewtopic.php?t=203
原作者:KaTTaNa
翻译:通魔作坊·宝宝暴暴
演示地图和系统代码在贴子末尾提供下载
这是几个使用了全局变量的函数,它允许你创建如同真的RPG游戏(例如无冬之夜)一样的对话系统。
它使用texttags (漂浮文字) 来显示NPC的对话,而且玩家可以使用方向键来选择他的回答。选择都会用漂浮文字显示出来,你当前选中的回答会高亮显示。你使用方向键右来决定你的答案。
当书写对话的时候, 你可以附加上"#"来使用指令。举个例子来说, #pc#可以用来代替玩家的名字, #npc# 可以用来代替NPC的名字 (Object name)。
我制作了一个演示地图来展示我的系统, 我建议你试试它, 他只展示了整个系统的一小部分功能。
下面是它的使用说明。
开始:
第一步: 执行
首先,创建下面的全局变量
Conv_CanIHelp: 字符串数组
Conv_Choice: 整数数组
Conv_Conversations: 字符串数组
Conv_Hello: 字符串数组
Conv_Id: 整数数组
Conv_Msg: 漂浮文字数组
Conv_TalkTriggers: 触发器数组
Conv_Triggers:触发器数组
Conv_NPC: 单位数组
Conv_Count: 整数
Conv_EventNPC: 单位
Conv_EventPC: 单位
Conv_EventId: 整数
Conv_NoDisturb: 布尔数组
PlayerHeroes: 单位数组
接着,复制所有的函数到地图的根。
如果你已经有EvaluateBoolexpr, StringFind, StringReplace, Boolexpr2Integer or Integer2Boolexpr 在你的地图里面,确保不会存在两个。
第二步: 地图初始化
在地图初始化的过程中,运行函数InitConversationSystem.
同时为玩家的英雄锁定镜头并确认playerHeroes[N] = Player[N]的英雄
书写一个对话
在这个系统中, 一个"对话"的意思是一个NPC的语言,和一系列玩家的回复选择.每一个玩家的悬想或者结束一个对话或者开启另外一个对话。
你可以使用NewConversation函数创建一个新的对话。这个函数的参数为:
string NPCOpening, string Responses, trigger trg
NPCOpening 是对话开始的时候NPC说的话
Responses 一般情况下设置为"" (非空).
trg 是每次对话发生时都会运行的触发器 (可以为null).
NewConversation的返回值是一个整数值,因为以后还要使用它,所以你必须好好保存这个数
你可以使用ConversationAddResponse来为对话增加玩家的选择.
ConversationAddResponse的参数为: integer ConversationID, string Response, integer To
ConversationID 是使用NewConversation来创建对话时的返回值。
Response 是玩家可以选择的选项.
To 是这个选项所指向的对话的ID. 使用 -1 来结束一个对话.
让我们看一个小示例:
代码:
local integer array p
set p[1] = NewConversation("Hello, my name is Joe. Can I help you?", "", null)
set p[2] = NewConversation("He lives just down the street to the left", "", null)
call ConversationAddResponse(p[1], "Where does Bob live?", p[2])
call ConversationAddResponse(p[1], "Goodbye Joe", -1)
call ConversationAddResponse(p[2], "Okay thanks.. see you later", -1)
这个示例示范了这个系统的底层.. 所有的 NPC对话必须在加入玩家选择之前建立。
给出的示例将创建一个小的对话,在这个对话中NPC说“Hello, my name is Joe”,然后玩家可以选择“Where does Bob live?”或者“Goodbye Joe”。如果玩家选择"Where does Bob live?", 那么NPC就会说 "He lives just down the street to the left", 接着玩家只有一个选项“Okay thanks.. see you later"可以选择。
现在,介绍一点可以很方便的给对话增加趣味的东西。
下面的单词在显示时都会被被相应的字符串代替:
#pc# ->玩家名字
#npc# -> NPC名字(units object name)
#type# ->玩家单位的类型(units object name)
#gold# -> 玩家的金钱
#lumber# -> 玩家的木头
#lvl# -> 玩家的等级
#hello# ->随机字符串udg_Conv_Hello
#help# ->随机字符串udg_Conv_CanIHelp
我叫它们 ”对话控制符“.
注意: udg_Conv_Hello 和udg_Conv_CanIHelp在InitConversationSystem中初始化.你可以把他们更改成你喜欢的.
如果我们在示例中使用它们的话, 我们将第一行改成这样:
代码:
set p[1] = NewConversation("#hello# #pc#, my name is Joe. #help#", "", null)
这行将使NPC说的话是: "Well met KaTTaNa, my name is Joe. What can I do for you?", 但是第一部分和最后一个部分在每个对话中都有可能不同,而且 "KaTTaNa" 在这个示例中是玩家的名字。
接着你将要显示在满足特定条件下才显示的玩家选项。 比如说当英雄携带了某一个物品的时候。
很幸运的,在这个系统中很容易实现
代码:
function PlayerHasBobsRing takes nothing returns boolean
return UnitHasItemOfTypeBJ(udg_Conv_EventPC, 'I000')
endfunction
local integer array p
set p[1] = NewConversation("#hello# #pc#, my name is Joe. #help#", "", null)
set p[2] = NewConversation("He lives just down the street to the left", "", null)
call ConversationAddResponse(p[1], "Where does Bob live?", p[2])
call ConversationAddResponse(p[1], "Goodbye Joe", -1)
call ConversationAddConditionalResponse(p[1], "Here, take this ring. Bob told me to give it to you", p[3], Condition(function PlayerHasBobsRing))
call ConversationAddResponse(p[2], "Okay thanks.. see you later", -1)
就象你看到的一样,函数PlayerHasBobsRing 判定了玩家选项是否可以显示。
注意我使用udg_Conv_EventPC的方式,变量udg_Conv_EventXXX使用的时候象事件响应.在这个示例中是单位和NPC说话。
这个”假“的事件响应在触发器中被NPCOpenings调用:
代码:
set p[3] = NewConversation("Thank you #pc#! You're the kindest #type# I've ever met. Take this 100 gold in return.", "", gg_trg_Bobs_Ring_Delivered)
.....
call ConversationAddResponse(p[3], "I appreciate that. Good day to you", -1)
gg_trg_Bobs_Ring_Delivered 将从英雄的物品栏中移除物品并且给予玩家100金.
按 上下 键选择 右 键决定 (都是方向键)
责任编辑:瞳瞳
进入论坛参与针对本文章的讨论
