This was based on the following script at:
http://www.touchofdeathproductions.com/scripts.html
By Unknown_raven
Difficulty: 4/5 (Requires some programming ability)
It uses a flag system which can become confusing but I'll leave a sample quest at the end of this tutorial for all to see.
Server Side
Create a new Module.
Name it modQuest and add the folowing:
Code:
Option Explicit
Function GetFlagHeight(ByVal index As Integer, ByVal Flagnum As Integer) As Long
Dim X
Dim filename As String
filename = App.Path & "\flags\" & getplayername(index) & ".ini"
X = GetVar(filename, GetPlayerName(index), "Flag" & Flagnum)
GetFlagHeight = X
Call SendDataTo(index, ("FLAGHEIGHT" & SEP_CHAR & X & SEP_CHAR & Flagnum & SEP_CHAR & END_CHAR))
End Function
Sub RaiseFlag(ByVal index As Integer, ByVal Flagnum As Integer, ByVal height As Integer)
Dim filename As String
filename = App.Path & "\flags\" & getplayername(index) & ".ini"
Call PutVar(filename, GetPlayerName(index), "Flag" & Flagnum, STR(GetVar(filename, GetPlayerName(index), "Flag" & Flagnum) + height))
End Sub
Sub LowerFlag(ByVal index As Integer, ByVal Flagnum As Integer, ByVal height As Integer)
Dim filename As String
filename = App.Path & "\flags\" & getplayername(index) & ".ini"
Call PutVar(filename, GetPlayerName(index), "Flag" & Flagnum, STR(GetVar(filename, GetPlayerName(index), "Flag" & Flagnum) - height))
End Sub
Sub SetFlag(ByVal index As Integer, ByVal Flagnum As Integer, ByVal height As Integer)
Dim filename As String
filename = App.Path & "\flags\" & getplayername(index) & ".ini"
Call PutVar(filename, GetPlayerName(index), "Flag" & Flagnum, STR(0))
Call PutVar(filename, GetPlayerName(index), "Flag" & Flagnum, STR(GetVar(filename, GetPlayerName(index), "Flag" & Flagnum) + height))
Call PutVar(filename, GetPlayerName(index), "Flag" & Flagnum, STR(height))
End Sub
Now I'll explain how this works. Basically you are using a system of flags to detrmine how much of the quest has been completed, and it also prevents parts of the quest which were allready finished from being done again, such as recieveing the reward for the quest.
Function GetFlagHeight - This function is pretty self explanatory. It access the file 'flags.ini" and checks to see what the current flag's height is. This is specified by the "flagnum". An example of how this could be used is:
Code:
If GetFlagHeight(index, 1) = 0 Then [b] ' Check the height of flag 1[/b]
Call PlayerMsg(index, "Janelle Says: 'Hi, could you do this quest for me? I need you to go to the forest and see if it is muddy.'", 10) ' Give the player the quest.
Call RaiseFlag(index, 1, 1) ' Raise the flag by one so that flag 1's height now = 1, and since it = 1 and not 0, the above event can't happen again.
End If
Sub RaiseFlag - This again is quite obvious. It raises the flag specified by "flagnum" so that any event that allready happened cannot happen again. See the above code example to see how it works.
Sub LowerFlag - This again is quite obvious. It lowers the flag specified by "flagnum" so that any event that allready happened can happen again. I haven't exactly thought of any real way this might come into play during a quest but maybe someone else can.
Sub SetFlag - This is used to set the height of a flag to a specific height. I haven't needed to use it in my quests yet because they're all hide and go seek quests, so a few IF statements with the getflagheight and raiseflag commands is suitable.
There, now that we have a basic understanding of what each function/sub routine does, let's move on to getting these quests to work.
First fo all we want to make sure that each players has some flags, otherwise the quests won't work.
Open up modGameLogic (still server side):
Find:
Code:
Sub JoinGame(ByVal index As Long)
And right under it add:
Code:
Dim BeenFlagged As Boolean, Num As Integer
Dim filename1 As String
filename1 = App.Path & "\flags\" & GetPlayerName(index) & ".ini"
If Not FileExist(filename1) Then
BeenFlagged = False
End If
If BeenFlagged = False Then
Num = 1
'Change the 3 to number of flags you want per player
Do While Num <= 3
Call PutVar(filename1, GetPlayerName(index), "Flag" & Num, 0)
Call PlayerMsg(index, "Added to flags.ini", 10)
Num = Num + 1
Loop
End If
Now, what this does is check to see fi the file exists, and if not it creates it then adds the flags for that character. The original version of the script checks to see if the player is level 1 and if so then checks to se eif the players has 0 experience, then adds the flags if both conditions apply. This didn't very suitable because if you were to implement this into a game which has been running allready, you would have to wipe out all the accounts and have the users starts from scratch. Of course this isn't the best way to do this, but if someone wants to expand on it IE: add support for more quests being added, then try it :). The best way to avoid this would be to change the number of flags from 3 to 200 or something like that.
Now, in modGameLogic, find:
Code:
Sub PlayerWarp
in that sub find:
Code:
' Sets it so we know to process npcs on the map
PlayersOnMap(MapNum) = YES
And directly under that add this:
Code:
Call CheckQuestMap(index)
Now in modQuest, add the following at the very bottom:
Code:
'*********************************************************************************
'Find out if the player is on a quest map!
'*********************************************************************************
Sub CheckQuestMap(ByVal index As Integer)
Select Case GetPlayerMap(index)
Case 5
<Add your quest code here>
<Somewhere here you are told to travel to a new area (map 6 maybe)
Case 6
<Add your conditions here, IE: raise flags etc.>
End Select
End Sub
Now, here's what this does:
Whenever a player warps to a new map, via a warp spot on the map or the /warp command, the server checks to see if that map is a quest map, by using the above select statement. This is where the programming knowledge is required. So if you planned on a copy and paste quest system, good bye :).
For each map you wish to have a quest on you need to make a "Case". So I want to travel to map 5, the server see's it's a quest map and sends the information needed to start the quest. Then you raise a flag so that event can't repeat. To finish the quest you need to travel to map 6. So say we raise dthe flag to 2. We do something like so:
Code:
Case 6
If GetFlagHeight(index, 1) = 2
Call Playermsg(index, "You found map 6!", 10)
Call RaiseFlag(index, 1, 1) 'Add +1 to the flag height
End If
So, now that the flag height =3 we can go back to map and in the case there, add the commands that will reward the player, as long as the flag height =3.
Now, you should have a working quest system. Whenever you want to add a new quest, simply hard code it into the select statement shown above. You could go so far as to modify that above statement and check for a certain x and y on that map. Say a dungeon entrance. The character stands on the dungeon entrance and is warped to map(#). There's a million and one things you do with this system so the only limits are you imagination and coding skills.
Here's an example of the quest used in the original script, modified to work with MSE:
Code:
'*********************************************************************************
'Find out if the player is on a quest map!
'*********************************************************************************
Sub CheckQuestMap(ByVal index As Integer)
Select Case GetPlayerMap(index)
Case 5
If GetFlagHeight(index, 1) = 0 Then 'this checks the height of Flag1
Call PlayerMsg(index, "Janelle Says: 'Hi, could you do this quest for me? I need you to go to the forest and see if it is muddy.'", 10)
Call RaiseFlag(index, 1, 1) 'raises the flag a level so the event cannot be repeated.
End If
If GetFlagHeight(index, 1) = 1 Then
Call PlayerMsg(index, "Janelle Says: 'Please hurry to the forest!'", 10)
End If
If GetFlagHeight(index, 1) = 2 Then
Call PlayerMsg(index, "Janelle Says: 'Oh thank you please take this reward.'", 10)
If FindOpenInvSlot(index, 1) = 0 Then 'looks for an empty slot
Call PlayerMsg(index, "Janelle Says: 'I am sorry but your inventory is full.'", 10)
Call PlayerMsg(index, "Janelle Says: 'Come back when you've got some room.'", 10)
Else
Call GiveItem(index, 1, 100) 'gives them item 20
Call PlayerMsg(index, "You recieved some gold.", BrightYellow)
Call PlayerMsg(index, "You completed this quest!.", BrightYellow)
Call RaiseFlag(index, 1, 1) 'raises the flag a level so the event cannot be repeated.
End If
End If
If GetFlagHeight(index, 1) = 3 Then
Call PlayerMsg(index, "Janelle Says: 'I'll never forget you, " & GetPlayerName(index) & ".'", 10)
End If
Exit Sub
Case 6 ' The Forest Map
' This represents the Forest Trigger.
If GetFlagHeight(index, 1) = 1 Then
Call PlayerMsg(index, "You notice that the forest is not very muddy.", 10)
Call RaiseFlag(index, 1, 1)
End If
Exit Sub
End Select
End Sub
If anyone has any issues please tell me about them. If you want to expand on this and post the code I'd b happy to update it as well.
Hope this helps some people.