Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[EO] Alatar's Quest System v1.2


Alatar
 Share

Recommended Posts

**Alatar's Quest System v1.2**

Screenshots:

>! ![](http://img440.imageshack.us/img440/8051/screenier.jpg)
![](http://i53.tinypic.com/2jfgbd5.jpg)

* * *

Hello and welcome. This is a tutorial for EO 2.0, and also includes the entire project if you wan't to use it right away without the need of following the tutorial. I've started with the idea of this system months ago, and although I abandon it a few times and moved to other things, finally in the past few days I've manage to finish it. I'm just learning to program like many here, so this was my first 'big' personal challenge. So please report any error or suggestion and I will try to do my best ^^
Ok, let's go to the important. (And please forgive me, English is not my main language)

**Features**

This quest system is a bit different to others due to the fact that it allow developers to create dinamyc quests with different purpose and itinerary, like "_go talk to X npc, then kill X amount of X npc, then talk to Y npc and gather X amount of X item, finally come back and talk to me_".
Each quest can have several tasks to do, each of one fully customizable. The quest system also has a fully working QuestLog and QuestSpeech window.

**Types of Tasks**

* **GoSlay**: Kill **X** amount of **X** npc's.
* **GoGather**: Gather **X** amount of **X** item.
* **GoTalk**: Interact with **X** npc.
* **GoTravel**: Reach **X** map.
* **GoGive**: Give **X** amount of **X** item to **X** npc.
* **GoKill**: Kill **X** amount of players.
* **GoTrain**: Hit **X** amount of times **X** resource.
* **GoGet**: Get **X** amount of **X** item from **X** npc.

**To-Do List**

* Replace [?] and [!] text with surfaces.

**How it Works**
To open the Quest Editor type /editquest.

**Changelog from v1.1 to v1.2**

>! * Redesigned the Quest UDT.
* Fixed experience reward.
* Added [?] and [!] symbols over npc's heads.
* Added requirements and rewards to the questlog.
* Added graphics to quest GUI.
* Fixed finished quest speech when having a repeatitive quest.
* Added completed quests to the quest log.
* Removed Delete key procedure that was used for testing only.
* Starting a quest now works with shopkeepers also.
* Fixed GoKill bug that added +1 to the current count of every quest active.
* Added multiple rewards, multiple take-item-on-the-end and multiple give-item-on-the-start.
* Fixed currency issues on GoGive, GoGet and GoGather.
* Fixed an exploit on give item on start.

Ok, let's go with the code.  :huh:

There are two ways to use this.

**Way 1**
[Download the full system](http://www.mediafire.com/?0ef5z3a9wa5tiif) already added to a blank EO and go test it. That's all, you don't need to follow the steps.

**Way 2**
Install the system on your own EO manually, following the steps below and **remember** to [download the extra files](http://www.mediafire.com/?4e8jd54chvmdwxs) and add them to your project:

**Server Side**

**Add the modSvQuest to your project.**

**modCombat**

Find:
```
If Len(Trim$(NPC(npcNum).AttackSay)) > 0 Then
```Above, after the Else, put
```
                      If NPC(npcNum).Behaviour = NPC_BEHAVIOUR_FRIENDLY Or NPC(npcNum).Behaviour = NPC_BEHAVIOUR_SHOPKEEPER Then
                            Call CheckTasks(attacker, QUEST_TYPE_GOTALK, npcNum)
                            Call CheckTasks(attacker, QUEST_TYPE_GOGIVE, npcNum)
                            Call CheckTasks(attacker, QUEST_TYPE_GOGET, npcNum)

                            If NPC(npcNum).Quest = YES Then
                                If Player(attacker).PlayerQuest(NPC(npcNum).Quest).Status = QUEST_COMPLETED Then
                                    If Quest(NPC(npcNum).Quest).Repeat = YES Then
                                        Player(attacker).PlayerQuest(NPC(npcNum).Quest).Status = QUEST_COMPLETED_BUT
                                        Exit Function
                                    End If
                                End If
                                If CanStartQuest(attacker, NPC(npcNum).QuestNum) Then
                                    'if can start show the request message (speech1)
                                    QuestMessage attacker, NPC(npcNum).QuestNum, Trim$(Quest(NPC(npcNum).QuestNum).Speech(1)), NPC(npcNum).QuestNum
                                    Exit Function
                                End If
                                If QuestInProgress(attacker, NPC(npcNum).QuestNum) Then
                                    'if the quest is in progress show the meanwhile message (speech2)
                                    QuestMessage attacker, NPC(npcNum).QuestNum, Trim$(Quest(NPC(npcNum).QuestNum).Speech(2)), 0
                                    Exit Function
                                End If
                            End If
                        End If
```
Sub PlayerAttackNpc, find:
```
' send death to the map
```Above place this:
```
Call CheckTasks(attacker, QUEST_TYPE_GOSLAY, npcNum)
```
Sub PlayerAttackNpc, find:
```
Call OnDeath(victim)
```Above place this:
```
Call CheckTasks(attacker, QUEST_TYPE_GOKILL, victim)
```
**modGeneral**

In InitServer find:
```
ChkDir App.Path & "\Data\", "spells"
```Paste this below:
```
ChkDir App.Path & "\Data\", "quests"
```
In ClearGameData find:
```
Call ClearAnimations
```Paste this below:
```
Call SetStatus("Clearing quests...")
Call ClearQuests
```
In LoadGameData find:
```
Call LoadAnimations
```Paste this below:
```
Call SetStatus("Loading quests...")
Call LoadQuests
```
**modHandleData**

Find:
```
HandleDataSub(CPartyLeave) = GetAddress(AddressOf HandlePartyLeave)
```Paste:
```
HandleDataSub(CRequestEditQuest) = GetAddress(AddressOf HandleRequestEditQuest)
    HandleDataSub(CSaveQuest) = GetAddress(AddressOf HandleSaveQuest)
    HandleDataSub(CRequestQuests) = GetAddress(AddressOf HandleRequestQuests)
    HandleDataSub(CPlayerHandleQuest) = GetAddress(AddressOf HandlePlayerHandleQuest)
    HandleDataSub(CQuestLogUpdate) = GetAddress(AddressOf HandleQuestLogUpdate)
```
At the end of the module add this:

```
Sub HandleRequestEditQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer

    ' Prevent hacking
    If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
        Exit Sub
    End If

    Set Buffer = New clsBuffer
    Buffer.WriteLong SQuestEditor
    SendDataTo Index, Buffer.ToArray()
    Set Buffer = Nothing
End Sub

Sub HandleSaveQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim n As Long
    Dim Buffer As clsBuffer
    Dim QuestSize As Long
    Dim QuestData() As Byte
    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()

    ' Prevent hacking
    If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
        Exit Sub
    End If

    n = Buffer.ReadLong 'CLng(Parse(1))

    If n < 0 Or n > MAX_QUESTS Then
        Exit Sub
    End If

    ' Update the Quest
    QuestSize = LenB(Quest(n))
    ReDim QuestData(QuestSize - 1)
    QuestData = Buffer.ReadBytes(QuestSize)
    CopyMemory ByVal VarPtr(Quest(n)), ByVal VarPtr(QuestData(0)), QuestSize
    Set Buffer = Nothing

    ' Save it
    Call SendUpdateQuestToAll(n)
    Call SaveQuest(n)
    Call AddLog(GetPlayerName(Index) & " saved Quest #" & n & ".", ADMIN_LOG)
End Sub

Sub HandleRequestQuests(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    SendQuests Index
End Sub

Sub HandlePlayerHandleQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer
    Dim QuestNum As Long, Order As Long, i As Long, n As Long
    Dim RemoveStartItems As Boolean

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    QuestNum = Buffer.ReadLong
    Order = Buffer.ReadLong '1 = accept quest, 2 = cancel quest

    If Order = 1 Then
        RemoveStartItems = False
        'Alatar v1.2
        For i = 1 To MAX_QUESTS_ITEMS
            If Quest(QuestNum).GiveItem(i).Item > 0 Then
                If FindOpenInvSlot(Index, Quest(QuestNum).RewardItem(i).Item) = 0 Then
                    PlayerMsg Index, "You have no inventory space. Please delete something to take the quest.", BrightRed
                    RemoveStartItems = True
                    Exit For
                Else
                    If Item(Quest(QuestNum).GiveItem(i).Item).Type = ITEM_TYPE_CURRENCY Then
                        GiveInvItem Index, Quest(QuestNum).GiveItem(i).Item, Quest(QuestNum).GiveItem(i).Value
                    Else
                        For n = 1 To Quest(QuestNum).GiveItem(i).Value
                            If FindOpenInvSlot(Index, Quest(QuestNum).GiveItem(i).Item) = 0 Then
                                PlayerMsg Index, "You have no inventory space. Please delete something to take the quest.", BrightRed
                                RemoveStartItems = True
                                Exit For
                            Else
                                GiveInvItem Index, Quest(QuestNum).GiveItem(i).Item, 1
                            End If
                        Next
                    End If
                End If
            End If
        Next

        If RemoveStartItems = False Then 'this means everything went ok
            Player(Index).PlayerQuest(QuestNum).Status = QUEST_STARTED '1
            Player(Index).PlayerQuest(QuestNum).ActualTask = 1
            Player(Index).PlayerQuest(QuestNum).CurrentCount = 0
            PlayerMsg Index, "New quest accepted: " & Trim$(Quest(QuestNum).Name) & "!", BrightGreen
        End If
        '/alatar v1.2

    ElseIf Order = 2 Then
        Player(Index).PlayerQuest(QuestNum).Status = QUEST_NOT_STARTED '2
        Player(Index).PlayerQuest(QuestNum).ActualTask = 1
        Player(Index).PlayerQuest(QuestNum).CurrentCount = 0
        RemoveStartItems = True 'avoid exploits
        PlayerMsg Index, Trim$(Quest(QuestNum).Name) & " has been canceled!", BrightGreen
    End If

    If RemoveStartItems = True Then
        For i = 1 To MAX_QUESTS_ITEMS
            If Quest(QuestNum).GiveItem(i).Item > 0 Then
                If HasItem(Index, Quest(QuestNum).GiveItem(i).Item) > 0 Then
                    If Item(Quest(QuestNum).GiveItem(i).Item).Type = ITEM_TYPE_CURRENCY Then
                        TakeInvItem Index, Quest(QuestNum).GiveItem(i).Item, Quest(QuestNum).GiveItem(i).Value
                    Else
                        For n = 1 To Quest(QuestNum).GiveItem(i).Value
                            TakeInvItem Index, Quest(QuestNum).GiveItem(i).Item, 1
                        Next
                    End If
                End If
            End If
        Next
    End If

    SavePlayer Index
    SendPlayerData Index
    SendPlayerQuests Index

    Set Buffer = Nothing
End Sub

Sub HandleQuestLogUpdate(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    SendPlayerQuests Index
End Sub
```
**modTypes**

In Private Type PlayerRec, find:
```
Dir As Byte
```Paste:
```
PlayerQuest(1 To MAX_QUESTS) As PlayerQuestRec
```
In Private Type NpcRec, find:
```
Level As Long
```Paste:
```
Quest As Byte
    QuestNum As Long
```
**modEnumerations**

Find:
```
SPartyVitals
```Paste:
```
    SQuestEditor
    SUpdateQuest
    SPlayerQuest
    SQuestMessage
```
Find:
```
CPartyLeave
```Paste:
```
    CRequestEditQuest
    CSaveQuest
    CRequestQuests
    CPlayerHandleQuest
    CQuestLogUpdate
```
**modPlayer**

Find:
```
Call SendHotbar(Index)
```Paste:
```
Call SendQuests(Index)
```
In PlayerWarp, find:
```
' if same map then just send their co-ordinates
    If mapNum = GetPlayerMap(Index) Then
        SendPlayerXYToMap Index
```Paste:
```
Call CheckTasks(Index, QUEST_TYPE_GOREACH, mapNum)
```
In PlayerWarp find:
```
TempPlayer(Index).GettingMap = YES
```Paste:
```
Call CheckTasks(Index, QUEST_TYPE_GOREACH, mapNum)
```
In PlayerMapGetItem, find:
```
SendActionMsg GetPlayerMap(Index), Msg, White, 1, (GetPlayerX(Index) * 32), (GetPlayerY(Index) * 32)
```Paste:
```
Call CheckTasks(Index, QUEST_TYPE_GOGATHER, GetItemNum(Trim$(Item(GetPlayerInvItemNum(Index, n)).Name)))
```
In CheckResource find:
```
SendMapSound Index, rX, rY, SoundEntity.seResource, Resource_index
```Paste:
```
Call CheckTasks(Index, QUEST_TYPE_GOTRAIN, Resource_index)
```

**Client Side**

**Add the modQuests to your project.
Add the frmEditor_Quest to your project.
Replace your frmEditor_NPC and frmMain with the ones that I provide you.**

**modGameEditors**

In NpcEditorInit find:
```
.txtDamage.text = NPC(EditorIndex).Damage
```Paste:
```
.chkQuest.Value = NPC(EditorIndex).Quest
        .scrlQuest.Value = NPC(EditorIndex).QuestNum
```
**modEnumerations**

Find:
```
SPartyVitals
```Paste:
```
    SQuestEditor
    SUpdateQuest
    SPlayerQuest
    SQuestMessage
```
Find:
```
CPartyLeave
```Paste:
```
    CRequestEditQuest
    CSaveQuest
    CRequestQuests
    CPlayerHandleQuest
    CQuestLogUpdate
```
**modHandleData**

Find:
```
HandleDataSub(SPartyVitals) = GetAddress(AddressOf HandlePartyVitals)
```Paste:
```
    HandleDataSub(SQuestEditor) = GetAddress(AddressOf HandleQuestEditor)
    HandleDataSub(SUpdateQuest) = GetAddress(AddressOf HandleUpdateQuest)
    HandleDataSub(SPlayerQuest) = GetAddress(AddressOf HandlePlayerQuest)
    HandleDataSub(SQuestMessage) = GetAddress(AddressOf HandleQuestMessage)
```
At the end of the module, paste this:
```
Private Sub HandleQuestEditor()
    Dim i As Long

    With frmEditor_Quest
        Editor = EDITOR_TASKS
        .lstIndex.Clear

        ' Add the names
        For i = 1 To MAX_QUESTS
            .lstIndex.AddItem i & ": " & Trim$(Quest(i).Name)
        Next

        .Show
        .lstIndex.ListIndex = 0
        QuestEditorInit
    End With

End Sub

Private Sub HandleUpdateQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim n As Long
    Dim Buffer As clsBuffer
    Dim QuestSize As Long
    Dim QuestData() As Byte
    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    n = Buffer.ReadLong
    ' Update the Quest
    QuestSize = LenB(Quest(n))
    ReDim QuestData(QuestSize - 1)
    QuestData = Buffer.ReadBytes(QuestSize)
    CopyMemory ByVal VarPtr(Quest(n)), ByVal VarPtr(QuestData(0)), QuestSize
    Set Buffer = Nothing
End Sub

Private Sub HandlePlayerQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer
    Dim i As Long

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()

    For i = 1 To MAX_QUESTS
        Player(MyIndex).PlayerQuest(i).Status = Buffer.ReadLong
        Player(MyIndex).PlayerQuest(i).ActualTask = Buffer.ReadLong
        Player(MyIndex).PlayerQuest(i).CurrentCount = Buffer.ReadLong
    Next

    RefreshQuestLog

    Set Buffer = Nothing
End Sub

Private Sub HandleQuestMessage(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer
    Dim i As Long, QuestNum As Long, QuestNumForStart As Long
    Dim Message As String

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    QuestNum = Buffer.ReadLong
    Message = Trim$(Buffer.ReadString)
    QuestNumForStart = Buffer.ReadLong

    frmMain.lblQuestName = Trim$(Quest(QuestNum).Name)
    frmMain.lblQuestSay = Message
    frmMain.lblQuestSubtitle = "Info:"
    frmMain.picQuestDialogue.Visible = True

    If QuestNumForStart > 0 And QuestNumForStart <= MAX_QUESTS Then
        frmMain.lblQuestAccept.Visible = True
        frmMain.lblQuestAccept.Tag = QuestNumForStart
    End If

    Set Buffer = Nothing
End Sub
```
**modInput**

Find:
```
SendRequestEditSpell
```Paste:
```
                Case "/editquest"
                    If GetPlayerAccess(MyIndex) < ADMIN_DEVELOPER Then GoTo Continue
                    SendRequestEditQuest
```
**modTypes**

In Private Type PlayerRec, find:
```
Step As Byte
```Paste:
```
PlayerQuest(1 To MAX_QUESTS) As PlayerQuestRec
```
In Private Type NpcRec, find:
```
Level As Long
```Paste:
```
    Quest As Byte
    QuestNum As Long
```
**modText**

In DrawNpcName find this:
```
Call DrawText(TexthDC, TextX, TextY, Name, color)
```Paste this:
```
Dim i As Long

    For i = 1 To MAX_QUESTS
        'check if the npc is the next task to any quest: [?] symbol
        If Quest(i).Name <> "" Then
            If Player(MyIndex).PlayerQuest(i).Status = QUEST_STARTED Then
                If Quest(i).Task(Player(MyIndex).PlayerQuest(i).ActualTask).NPC = npcNum Then
                    Name = "[?]"
                    TextX = ConvertMapX(MapNpc(Index).x * PIC_X) + MapNpc(Index).XOffset + (PIC_X \ 2) - getWidth(TexthDC, (Trim$(Name)))
                    If NPC(npcNum).Sprite < 1 Or NPC(npcNum).Sprite > NumCharacters Then
                        TextY = ConvertMapY(MapNpc(Index).y * PIC_Y) + MapNpc(Index).YOffset - 16
                    Else
                        TextY = ConvertMapY(MapNpc(Index).y * PIC_Y) + MapNpc(Index).YOffset - (DDSD_Character(NPC(npcNum).Sprite).lHeight / 4)
                    End If
                    Call DrawText(TexthDC, TextX, TextY, Name, QBColor(Yellow))
                    Exit For
                End If
            End If

            'check if the npc is the starter to any quest: [!] symbol
            'can accept the quest as a new one?
            If Player(MyIndex).PlayerQuest(i).Status = QUEST_NOT_STARTED Or Player(MyIndex).PlayerQuest(i).Status = QUEST_COMPLETED_BUT Then
                'the npc gives this quest?
                If NPC(npcNum).QuestNum = i Then
                    Name = "[!]"
                    TextX = ConvertMapX(MapNpc(Index).x * PIC_X) + MapNpc(Index).XOffset + (PIC_X \ 2) - getWidth(TexthDC, (Trim$(Name)))
                    If NPC(npcNum).Sprite < 1 Or NPC(npcNum).Sprite > NumCharacters Then
                        TextY = ConvertMapY(MapNpc(Index).y * PIC_Y) + MapNpc(Index).YOffset - 16
                    Else
                        TextY = ConvertMapY(MapNpc(Index).y * PIC_Y) + MapNpc(Index).YOffset - (DDSD_Character(NPC(npcNum).Sprite).lHeight / 4)
                    End If
                    Call DrawText(TexthDC, TextX, TextY, Name, QBColor(Yellow))
                    Exit For
                End If
            End If
        End If
    Next
```
**modConstants**

Find:
```
Public Const MAX_MAINBUTTONS As Long = 6
```Replace the 6 for a 7.

**modGeneral**

In LoadGUI find
```
frmMain.picHotbar.Picture = LoadPicture(App.Path & "\data files\graphics\gui\main\hotbar.jpg")
```Paste:
```
frmMain.picQuestLog.Picture = LoadPicture(App.Path & "\data files\graphics\gui\main\questlog.jpg")
    frmMain.picQuestDialogue.Picture = LoadPicture(App.Path & "\data files\graphics\gui\main\questdialogue.jpg")

```
In cacheButtons find:
```
' main - party
    With MainButton(6)
        .fileName = "party"
        .state = 0 ' normal
    End With
```
Paste:
```
' main - quest
    With MainButton(7)
        .fileName = "quest"
        .state = 0 ' normal
    End With
```

* * *

And that's all! Tell me if anything goes wrong. I hope that this system could be useful to your project, and if you use it please give credits  ;)

**_- Alatar_**

* * *

Special thanks to Erwin and people who help here bugfixing while I was inactive. :)
And to the people who reported bugs ^^

* * *

**All Versions**

* Alatar's Quest System v1.2: [Link](http://www.touchofdeathforums.com/smf2/index.php/topic,70502.msg863386.html#msg863386)
* Alatar's Quest System v1.1: [Link](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg809248.html#msg809248)
* Alatar's Quest System v1.0: [Link](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg758371.html#msg758371).

* * *

**Extras**

* [Convert quests from v1.0 to v1.1](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg809345.html#msg809345)
* [Update your whole system from v1.0 to v1.1](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg809347.html#msg809347)
Link to comment
Share on other sites

  • Replies 703
  • Created
  • Last Reply

Top Posters In This Topic

Version 1.0:

>! **Alatar's Quest System v1.0**
>! >! ![](http://i51.tinypic.com/2r5ruky.jpg)
>! Hello and welcome. This is a tutorial for EO 2.0, and also includes the entire project if you wan't to use it right away without the need of following the tutorial. I've started with the idea of this system months ago, and although I abandon it a few times and moved to other things, finally in the past few days I've manage to finish it. I'm just learning to program like many here, so this was my first 'big' personal challenge. So please report any error or suggestion and I will try to do my best ^^
Ok, let's go to the important. (And please forgive me, English is not my main language)
>! **Features**
>! This quest system is a bit different to others due to the fact that it allow developers to create dinamyc quests with different purpose and itinerary, like "_go talk to X npc, then kill X amount of X npc, then talk to Y npc and gather X amount of X item, finally come back and talk to me_".
Each quest can have several tasks to do, each of one fully customizable. The quest system also has a fully working QuestLog and QuestSpeech window.
>! **Types of Tasks**
>! * **GoSlay**: Kill **X** amount of **X** npc's.
* **GoGather**: Gather **X** amount of **X** item.
* **GoTalk**: Interact with **X** npc.
* **GoTravel**: Reach **X** map.
* **GoGive**: Give **X** amount of **X** item to **X** npc.
* **GoKill**: Kill **X** amount of players.
* **GoTrain**: Hit **X** amount of times **X** resource.
* **GoGet**: Get **X** amount of **X** item from **X** npc.
>! **To-Do List**
>! * Take and Give items when the quest starts.
* Multiple rewards.
>! **How it Works**
Temporary, it's working this way, but you could add buttons if you wish, and edit the ugly GUI forms and stuff. To open the Quest Editor type /editquest, to open the QuestLog press key End.
>! Ok, let's go with the code.  :huh:
>! There are two ways to use this.
>! **Way 1** (old, not updated)
[Download the full system](http://www.mediafire.com/?4jyp8m1b4g657l4) already added to a blank EO and go test it. That's all, you don't need to follow the steps.
>! **Way 2**
Install the system on your own EO manually, following the steps below and **remember** to [download the extra files](http://www.mediafire.com/?pz31rx4b29is4l0) and add them to your project:
>! **Server Side**
>! **Add the modSvQuest to your project.**
>! **modCombat**
>! Sub CanPlayerAttackNpc, Find:
```
If NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_FRIENDLY And NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_SHOPKEEPER Then
```Replace with
```
If NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_FRIENDLY And NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_SHOPKEEPER And NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_QUEST Then
```Note: there are 2 of this, replace both!
>! Find:
```
If Len(Trim$(NPC(npcNum).AttackSay)) > 0 Then
```Above, after the Else, put
```
                        If NPC(npcNum).Behaviour = NPC_BEHAVIOUR_QUEST Then
                            Call ShowQuest(attacker, NPC(npcNum).QuestNum)
                            Exit Function
                        End If
                        If NPC(npcNum).Behaviour = NPC_BEHAVIOUR_FRIENDLY Then
                            Call CheckTasks(attacker, QUEST_TYPE_GOTALK, npcNum)
                            Call CheckTasks(attacker, QUEST_TYPE_GOGIVE, npcNum)
                            Call CheckTasks(attacker, QUEST_TYPE_GOGET, npcNum)
                        End If
```
Sub PlayerAttackNpc, find:
```
' send death to the map
```Above place this:
```
Call CheckTasks(attacker, QUEST_TYPE_GOSLAY, npcNum)
```
Sub PlayerAttackNpc, find:
```
Call OnDeath(victim)
```Above place this:
```
Call CheckTasks(attacker, QUEST_TYPE_GOKILL, 0)
```
**modGeneral**
>! In InitServer find:
```
ChkDir App.Path & "\Data\", "spells"
```past this below:
```
ChkDir App.Path & "\Data\", "quests"
```
In ClearGameData find:
```
Call ClearAnimations
```past this below:
```
Call SetStatus("Clearing quests...")
Call ClearQuests
```
In LoadGameData find:
```
Call LoadAnimations
```past this below:
```
Call SetStatus("Loading quests...")
Call LoadQuests
```
**modHandleData**
>! Find:
```
HandleDataSub(CPartyLeave) = GetAddress(AddressOf HandlePartyLeave)
```Paste:
```
    HandleDataSub(CRequestEditQuest) = GetAddress(AddressOf HandleRequestEditQuest)
    HandleDataSub(CSaveQuest) = GetAddress(AddressOf HandleSaveQuest)
    HandleDataSub(CRequestQuests) = GetAddress(AddressOf HandleRequestQuests)
    HandleDataSub(CPlayerHandleQuest) = GetAddress(AddressOf HandlePlayerHandleQuest)
    HandleDataSub(CQuestLogUpdate) = GetAddress(AddressOf HandleQuestLogUpdate)
```
At the end of the module add this:
>! ```
Sub HandleRequestEditQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer
>!     ' Prevent hacking
    If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
        Exit Sub
    End If
>!     Set Buffer = New clsBuffer
    Buffer.WriteLong SQuestEditor
    SendDataTo Index, Buffer.ToArray()
    Set Buffer = Nothing
End Sub
>! Sub HandleSaveQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim n As Long
    Dim Buffer As clsBuffer
    Dim QuestSize As Long
    Dim QuestData() As Byte
    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
>!     ' Prevent hacking
    If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
        Exit Sub
    End If
>!     n = Buffer.ReadLong 'CLng(Parse(1))
>!     If n < 0 Or n > MAX_QUESTS Then
        Exit Sub
    End If

    ' Update the Quest
    QuestSize = LenB(Quest(n))
    ReDim QuestData(QuestSize - 1)
    QuestData = Buffer.ReadBytes(QuestSize)
    CopyMemory ByVal VarPtr(Quest(n)), ByVal VarPtr(QuestData(0)), QuestSize
    Set Buffer = Nothing

    ' Save it
    Call SendUpdateQuestToAll(n)
    Call SaveQuest(n)
    Call AddLog(GetPlayerName(Index) & " saved Quest #" & n & ".", ADMIN_LOG)
End Sub
>! Sub HandleRequestQuests(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    SendQuests Index
End Sub
>! Sub HandlePlayerHandleQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer
    Dim QuestNum As Long, Order As Long

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    QuestNum = Buffer.ReadLong
    Order = Buffer.ReadLong '1 = accept, 2 = cancel

    If Order = 1 Then
        Player(Index).PlayerQuest(QuestNum).Status = QUEST_STARTED '1
        Player(Index).PlayerQuest(QuestNum).ActualTask = 1
        Player(Index).PlayerQuest(QuestNum).CurrentCount = 0
        PlayerMsg Index, "New quest accepted: " & Trim$(Quest(QuestNum).Name) & "!", BrightGreen
    ElseIf Order = 2 Then
        Player(Index).PlayerQuest(QuestNum).Status = QUEST_NOT_STARTED '2
        PlayerMsg Index, Trim$(Quest(QuestNum).Name) & " has been canceled!", BrightGreen
    End If

    SavePlayer Index
    SendPlayerData Index
    SendPlayerQuest Index, QuestNum

    Set Buffer = Nothing
End Sub
>! Sub HandleQuestLogUpdate(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    SendPlayerQuests Index
End Sub
```
**modTypes**
>! In Private Type PlayerRec, find:
```
Dir As Byte
```Paste:
```
PlayerQuest(1 To MAX_QUESTS) As PlayerQuestRec
```
In Private Type NpcRec, find:
```
Level As Long
```Paste:
```
QuestNum As Long
```
**modEnumerations**
>! Find:
```
SPartyVitals
```Paste:
```
    SQuestEditor
    SUpdateQuest
    SPlayerQuest
    SQuestMessage
```
Find:
```
CPartyLeave
```Paste:
```
    CRequestEditQuest
    CSaveQuest
    CRequestQuests
    CPlayerHandleQuest
    CQuestLogUpdate
```
**modPlayer**
>! Find:
```
Call SendHotbar(Index)
```Paste:
```
Call SendQuests(Index)
```
In PlayerWarp, find:
```
TempPlayer(Index).GettingMap = YES
```Paste:
```
Call CheckTasks(Index, QUEST_TYPE_GOREACH, mapNum)
```
In PlayerMapGetItem, find:
```
SendActionMsg GetPlayerMap(Index), Msg, White, 1, (GetPlayerX(Index) * 32), (GetPlayerY(Index) * 32)
```Paste:
```
Call CheckTasks(Index, QUEST_TYPE_GOGATHER, GetItemNum(Trim$(Item(GetPlayerInvItemNum(Index, n)).Name)))
```
In CheckResource find:
```
SendMapSound Index, rX, rY, SoundEntity.seResource, Resource_index
```Paste:
```
Call CheckTasks(Index, QUEST_TYPE_GOTRAIN, Resource_index)
```
>! **Client Side**
>! **Add the modQuests to your project.
Add the frmEditor_Quest to your project.
Replace your frmEditor_NPC and frmMain with the ones that I provide you.**
>! **modGameEditors**
>! In NpcEditorInit find:
```
.txtDamage.text = NPC(EditorIndex).Damage
```Paste:
```
.scrlQuest.Value = NPC(EditorIndex).QuestNum
```
**modEnumerations**
>! Find:
```
SPartyVitals
```Paste:
```
    SQuestEditor
    SUpdateQuest
    SPlayerQuest
    SQuestMessage
```
Find:
```
CPartyLeave
```Paste:
```
    CRequestEditQuest
    CSaveQuest
    CRequestQuests
    CPlayerHandleQuest
    CQuestLogUpdate
```
**modHandleData**
>! Find:
```
HandleDataSub(SPartyVitals) = GetAddress(AddressOf HandlePartyVitals)
```Paste:
```
    HandleDataSub(SQuestEditor) = GetAddress(AddressOf HandleQuestEditor)
    HandleDataSub(SUpdateQuest) = GetAddress(AddressOf HandleUpdateQuest)
    HandleDataSub(SPlayerQuest) = GetAddress(AddressOf HandlePlayerQuest)
    HandleDataSub(SQuestMessage) = GetAddress(AddressOf HandleQuestMessage)
```
At the end of the module, past this:
>! ```
Private Sub HandleQuestEditor()
    Dim i As Long

    With frmEditor_Quest
        Editor = EDITOR_TASKS
        .lstIndex.Clear
>!         ' Add the names
        For i = 1 To MAX_QUESTS
            .lstIndex.AddItem i & ": " & Trim$(Quest(i).Name)
        Next
>!         .Show
        .lstIndex.ListIndex = 0
        QuestEditorInit
    End With
>! End Sub
>! Private Sub HandleUpdateQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim n As Long
    Dim Buffer As clsBuffer
    Dim QuestSize As Long
    Dim QuestData() As Byte
    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    n = Buffer.ReadLong
    ' Update the Quest
    QuestSize = LenB(Quest(n))
    ReDim QuestData(QuestSize - 1)
    QuestData = Buffer.ReadBytes(QuestSize)
    CopyMemory ByVal VarPtr(Quest(n)), ByVal VarPtr(QuestData(0)), QuestSize
    Set Buffer = Nothing
End Sub
>! Private Sub HandlePlayerQuest(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer
    Dim i As Long
>!     Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()

    For i = 1 To MAX_QUESTS
        Player(Index).PlayerQuest(i).Status = Buffer.ReadLong
        Player(Index).PlayerQuest(i).ActualTask = Buffer.ReadLong
        Player(Index).PlayerQuest(i).CurrentCount = Buffer.ReadLong
    Next

    RefreshQuestLog

    Set Buffer = Nothing
End Sub
>! Private Sub HandleQuestMessage(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer
    Dim i As Long, QuestNum As Long, QuestNumForStart As Long
    Dim Message As String

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    QuestNum = Buffer.ReadLong
    Message = Trim$(Buffer.ReadString)
    QuestNumForStart = Buffer.ReadLong

    frmMain.lblQuestNameVisual = Trim$(Quest(QuestNum).Name)
    frmMain.lblQuestSay = Message
    frmMain.picQuestSpeech.Visible = True

    If QuestNumForStart > 0 And QuestNumForStart <= MAX_QUESTS Then
        frmMain.lblQuestAccept.Visible = True
        frmMain.lblQuestAccept.Tag = QuestNumForStart
    End If

    LoadQuestLogPage
    ShowQuestLogPage 1

    Set Buffer = Nothing
End Sub
>! ```
**modInput**
>! Find:
```
SendRequestEditSpell
```Paste:
```
                Case "/editquest"
                    If GetPlayerAccess(MyIndex) < ADMIN_DEVELOPER Then GoTo Continue
                    SendRequestEditQuest
```
**modTypes**
>! In Private Type PlayerRec, find:
```
Step As Byte
```Paste:
```
PlayerQuest(1 To MAX_QUESTS) As PlayerQuestRec
```
In Private Type NpcRec, find:
```
Level As Long
```Paste:
```
QuestNum As Long
```
>! * * *
>! And that's all! Tell me if anything goes wrong. I hope that this system could be useful to your project, and if you use it please give credits  ;)
>! **_- Alatar_**
>! * * *
>! **BugFixes by Users** (not tested by me)
>! [QuestLog Bug](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg776144.html#msg776144) (by sotvotkong)
[Quest Editor Form Load](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg777731.html#msg777731) (by Ryoku Hasu)
[Taking/Giving items on the Start](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg786374.html#msg786374) (by Erwin)
[QuestLog / Train Resource](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg788565.html#msg788565) (by Erwin)
[Kill player bugfix](http://www.touchofdeathforums.com/smf/index.php/topic,70502.msg808775.html#msg808775) (by Erwin)
>! PS: I will fix the bugs myself and re-upload the next version when I manage to get some time to work on it xD
Link to comment
Share on other sites

Thx to all  :cheesy:

@Captain Wabbit: lol I forgot to compile it xD, i will re-upload it later I'm just leaving right now.

@alvin: So… the errors are still there or you've solved it? I'm thinking on adding multi-reward to the next version.
Link to comment
Share on other sites

Ok wait, this might just be me but where's SaveQuest's sub? I'm looking at the tutorial and i see a Call SaveQuest  but i can't actually find savequest…

(might just be me with something stupid, like i didn't see it or something but i really can't find it, if this is a stupid question sorry)

I'm seriously thinking that I'm hallucinating because alvin didn't report a message saying that the sub doesn't exist.So I don't know what to believe.
Link to comment
Share on other sites

The SaveQuests and those subs are stored in the modQuests that i say you have to download and add to your project.
About the item editor, I haven't touch anything there, I'm going to check that later when i come back from work.
Link to comment
Share on other sites

What was changed in the resource editor? I made some changes to mine already and Don't feel like having to redo them. If its something simple enough to bring over to my edited resource editor.

Edit: Your instructions say to replace the frmeditor_npc. but you provided the frmeditor_resource for the extra files. You may want to fix that lol
Link to comment
Share on other sites

@crzyone9584:

> What was changed in the resource editor? I made some changes to mine already and Don't feel like having to redo them. If its something simple enough to bring over to my edited resource editor.

There are no edits in resource editor, i've looked in the code and i saw nothing.

@crzyone9584:

> Edit: Your instructions say to replace the frmeditor_npc. but you provided the frmeditor_resource for the extra files. You may want to fix that lol

Yes, but you could download the compiled version and copy/paste frmEditor_NPC ;)
Link to comment
Share on other sites

@erkro1:

> There are no edits in resource editor, i've looked in the code and i saw nothing

Thats why i was asking. And I am downloading the full version. Its just a waste of time to download two versions. Also i edited my first post i just didnt delete the part asking about the resource editor lol
Link to comment
Share on other sites

@crzyone9584:

> Edit: Your instructions say to replace the frmeditor_npc. but you provided the frmeditor_resource for the extra files. You may want to fix that lol

LOL! epic fail xD
I've reuploaded it: http://www.mediafire.com/?pz31rx4b29is4l0
Link to comment
Share on other sites

Now the only problem is I'm still able to attack even though they are quest npc… i guess I'll have to double check the server edits make sure got them all.

EDIT: wow do i feel stupid i only put <> NPC_BEHAVIOR_QUEST and not the entire code... now that was an epic fail.
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share


×
×
  • Create New...