My first task was to create a "metadata" system for characters. Basically it lets me read and write values with names assigned to each value, and all metadata saves and loads with the character. This is so quest scripts could read and write dynamic character data on the fly, i.e. a counter for how many demons you've slain.
Once that was in, I started on the quest system. The basic idea is to "activate" a quest which then begins observing and reads/writes metadata based on its observations. This is what a quest script looks like:
KillDemonBaby = BaseQuest:extend()
KillDemonBaby.targetName = "killDemonBaby"
KillDemonBaby.printName = "Tainted Birth"
KillDemonBaby.description = "Slay 5 Demon Babies"
function KillDemonBaby:activate(event)
event.EventSystem:Add("OnUnitKilled", self, self.onUnitKilled, event)
end
function KillDemonBaby:deactivate(event)
event.EventSystem:Remove("OnUnitKilled", self, self.onUnitKilled)
end
function KillDemonBaby:canStart(event)
-- check prerequisites here
-- i.e if player needs to finish another quest first,
-- event.Character.Meta:GetQuestState("otherQuest") == QuestState.Completed
return true
end
function KillDemonBaby:onStart(event)
CS.UnityEngine.Debug.Log("START DEMON BABBY")
end
function KillDemonBaby:onComplete(event)
CS.UnityEngine.Debug.Log("COMPLETE DEMON BABY")
end
function KillDemonBaby:onUnitKilled(unit, event)
if unit.LuaTargetName ~= "demonBaby" then return end
local counter = event.Character.Meta:GetInt("killDemonBaby_Counter") + 1
if counter >= 5 then
self:complete(event)
else
event.Character.Meta:SetInt("killDemonBaby_Counter", counter)
end
end
The dialog system gives players a way to activate quests and learn about characters. I wasn't really sure where to start with this, so I just opened up notepad++ and started writing some random Lua script in attempt to get an idea. I whipped up a very simple dialog script format. The first line is what the NPC is saying to you, the following lines represent the player's responses. Between parentheses indicates the method name to execute if that response is chosen, between square brackets is the text shown in the dialog box.
I need you to kill babby.
(decline)[No thanks]
(accept)[Sure thing]
(closeDialog)[Goodbye]
TestDialog = BaseDialog:extend()
TestDialog.targetName = "testDialog"
function TestDialog:activate(event)
if event.Character.Meta:GetQuestState("testQuest") == QuestState.None then
event.Dialog:Print(self, [[
I need you to kill babby.
(decline)[No thanks]
(accept)[Sure thing]
(closeDialog)[Goodbye]
]], event)
else
event.Dialog:Print(self, [[
Have you kill babby?
(closeDialog)[I should go do that!]
]], event)
end
end
function TestDialog:decline(event)
event.Dialog:Print(self, [[
Whatever dude.
(closeDialog)[Goodbye]
]], event)
end
function TestDialog:accept(event)
if event.Character.QuestBook:TryStartQuest("testQuest") then
event.Dialog:Print(self, [[
Great!
(closeDialog)[I'll be back]
]], event)
else
event.Dialog:Print(self, [[
You can't do this quest yet
(closeDialog)[Hm]
]], event)
end
end
function TestDialog:closeDialog(event)
event.Dialog:Close()
end
This combines data with logic, but I'm really happy with how it works. Here it is in action:
https://crayz.tv/files/sharex/2018-05-23%2023-03-04.mp4
Sorry, you need to Log In to post a reply to this thread.