• Dialog system & quests
    1 replies, posted
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.