| Mirage Source http://miragesource.net/forums/ |
|
| My Quest System (Updated to use tiles) http://miragesource.net/forums/viewtopic.php?f=210&t=228 |
Page 1 of 1 |
| Author: | Leighland [ Mon Jul 03, 2006 3:17 am ] |
| Post subject: | My Quest System (Updated to use tiles) |
Okay, I've possessed myself to expand on this a bit. Difficulty: 4/5 Requires knowledge of VB/MSE programming Original Post can be found here: http://ms.shannaracorp.com/forums/viewtopic.php?t=174 The flag idea and quest was taken from Unkown_raven This version of the code uses tile, which you can set with the Mapeditor. I'll give an example of how to set up each quest at the end of this tutorial. There are probably easier ways to do what I have but this works for me Let's do the client side first: Open up frmMirage On picMapEditor add an option button to your attributes frame, name it optQuest. Double click it and add this to the code: Code: Private Sub optQuest_Click() frmQuest.Show vbModal End Sub Now, Open up modGameLogic and in the Sub GameLoop find: Code: If .Type = TILE_TYPE_KEYOPEN Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "O", QBColor(White)) Under it add: Code: If .Type = TILE_TYPE_QUEST Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "Q", QBColor(BrightRed)) Then in Sub EditorMouseDown find: Code: If frmMirage.optKeyOpen.Value = True Then .Type = TILE_TYPE_KEYOPEN .Data1 = KeyOpenEditorX .Data2 = KeyOpenEditorY .Data3 = 0 End If Under it, add: Code: If frmMirage.optQuest.Value = True Then .Type = TILE_TYPE_QUEST .Data1 = QuestEditorNum .Data2 = 0 .Data3 = 0 End If Now, open modConstants and find: Code: Public Const TILE_TYPE_KEYOPEN = 6 And under it, add: Code: Public Const TILE_TYPE_QUEST = 7 Now open modGlobals: Anywhere in that module, add: Code: ' Used for Quest Chooser Public QuestEditorNum As Long Okay, now we're going to create the form that will be used to choose which quest we want to start when the player walks over the specified tile. So, add a new form and name it frmQuest Add a scroll bar: Name: scrlQuestNum Max: 250 Add a Label: Name: lblQuestNum Add a command button: Name: cmdOK Caption: Okay Add a command button: Name: cmdCancel Caption: Cancel Double click the form and add the following: Code: Private Sub cmdOk_Click() QuestEditorNum = scrlQuestNum.Value Unload Me End Sub Private Sub cmdCancel_Click() Unload Me End Sub Private Sub scrlQuestNum_Change() lblQuestnum.Caption = STR(scrlQuestNum.Value) End Sub That's all for the client side. Now on to the server. Open frmServer and add a new timer to it. Name: QuestMapNotice Enabled: False Interval: 5000 Double click on it and add the following to its sub routine: Code: CHECKQUEST = True Open modGameLogic and in the PlayerWarp sub find: Code: ' Sets it so we know to process npcs on the map PlayersOnMap(MapNum) = YES Under it, add: Code: frmServer.tmrQuestMapNotice.Enabled = True If CHECKQUEST = True Then If Dir(App.Path & "\Quest Maps\" & GetPlayerName(index) & ".ini") <> "" Then If GetQuestMap(index, GetPlayerMap(index)) = 1 Then Call QuestMapData(index) frmServer.tmrQuestMapNotice.Enabled = False Else frmServer.tmrQuestMapNotice.Enabled = False End If End If End If Now find: Code: ' They tried to hack If Moved = NO Then Call HackingAttempt(index, "Position Modification") End If And under it add: Code: If Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).Type = TILE_TYPE_QUEST Then Call CheckQuestTile(index) End If In Sub JoinGame, find: Code: ' Warp the player to his saved location Call PlayerWarp(index, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index)) and under it add: Code: filename = App.Path & "\Flags\" & GetPlayerName(index) & ".ini" If Dir(filename) = "" Then Num = 1 'Change the 3 to number of flags you want per player Do While Num <= 250 Call PutVar(filename, GetPlayerName(index), "Flag" & Num, 0) Num = Num + 1 Loop Call PlayerMsg(index, "Quest Variables Set - If you see this message again please notify an admin or use the /bug command.", 10) End If filename = App.Path & "\Quest Maps\" & GetPlayerName(index) & ".ini" If Dir(filename) = "" Then Num = 1 'Change the 3 to number of flags you want per player Do While Num <= MAX_MAPS Call PutVar(filename, GetPlayerName(index), "Map" & Num, 0) Num = Num + 1 Loop Call PlayerMsg(index, "Map Variables Set - If you see this message again please notify an admin or use the /bug command.", 10) End If *** Note: in my game we have a bug reporting tool. Every game should have one! :p Now, open mogGeneral, find: Code: ' Check if the accounts directory is there, if its not make it If LCase(Dir(App.Path & "\accounts", vbDirectory)) <> "accounts" Then Call MkDir(App.Path & "\accounts") End If And after it add: Code: ' Check if the Quest maps directory is there, if its not make it If LCase(Dir(App.Path & "\quest maps", vbDirectory)) <> "quest maps" Then Call MkDir(App.Path & "\quest maps") End If ' Check if the Flags directory is there, if its not make it If LCase(Dir(App.Path & "\flags", vbDirectory)) <> "flags" Then Call MkDir(App.Path & "\flags") End If Open modConstants, and add the following: Code: Public Const MAX_QUEST_MAPS = 200 ' You can change this to whatever you choose, 200 seemed sutiable for my game. Find: Code: Public Const TILE_TYPE_KEYOPEN = 6 Under it add: Code: Public Const TILE_TYPE_QUEST = 7 in modGlobals, add: Code: ' Used for checking quest data Public CHECKQUEST As Boolean Now, make a new module and name it modQuest In that module add all of this: 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 Sub SetQuestMap(ByVal index As Long, ByVal MapNum As Long, ByVal QuestMap As Byte) Dim filename As String Dim i As Long filename = App.Path & "\Quest Maps\" & GetPlayerName(index) & ".ini" For i = 1 To MAX_MAPS If GetVar(filename, GetPlayerName(index), "Map" & i) = 0 Then Resume Next Else Call PutVar(filename, GetPlayerName(index), "Map" & i, STR(QuestMap)) End If Next i End Sub Function GetQuestMap(ByVal index As Integer, ByVal MapNum As Integer) As Long Dim X Dim filename As String filename = App.Path & "\Quest Maps\" & GetPlayerName(index) & ".ini" X = GetVar(filename, GetPlayerName(index), "Map" & MapNum) GetQuestMap = X End Function '======================================= 'Hard Code Your Quests Here '======================================= Sub CheckQuestTile(ByVal index As Integer) Select Case Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).Data1 Case 1 ' This is the quest number you will choose with the frmQuest on your client. End Select End Sub Sub QuestMapData(index) Select Case GetPlayerMap(index) Case 1 ' Your Quest Map ' Quest Map Events Go Here End Select End Sub Okay now that thats all done. Let's make ourselves a quest! We're going to use my example from the last tutorial. Janelle wants you to go find out if the forest is muddy :o Okay, so let's make this quest one. Let's start by programming the quest into the sub we just added. Code: Case 1 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. Call SetQuestMap(index, 3, 1) ' sets the map to be a quest map for the player 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) ' 1 = item number, 100=amount of item(1) 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. Call SetQuestMap(index, 3, 0) 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 Okay, parts of the code are commented allready but I'll break this all down anyways. First of all let's examine this block: Code: Case 1 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. Call SetQuestMap(index, 3, 1) ' sets the map to be a quest map for the player End If Line for line, here it is: Case 1 - This checks to see what quest is associated with the tile we stepped on. In this case, it's quest #1. If GetFlagHeight(index, 1) = 0 Then - This gets the height of flag 1, which is our quest flag, because we are doing quest one. Smart huh? This says if it is at a height of 0, to execute the rest of the statement. 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) - this is a cheap way of getting an NPC to talk lol. Worked for me, better ways to do it. Call RaiseFlag(index, 1, 1) - This raises flag 1 to a height of 1 so that this event can't be repeated. Call SetQuestMap(index, 3, 1) - This turns the map into a quest map. In this case, we want map 3 to be the forest, so we set it up this way so we can retrieve that info later. Note that this is saved into an INI file which is specific to the player. Long explanantion short, it makes sure other players cant interfere. End if - Duh :p Okay now we've set the map, it's time to move on to the next part. What if someone hasn't vissted the forest yet, but returns to Janelle. She can't give the quest again because we flagged it, but we don't want a blank response either. So let's throw this is for amusement. Code: If GetFlagHeight(index, 1) = 1 Then Call PlayerMsg(index, "Janelle Says: 'Please hurry to the forest!'", 10) End If Pretty sure that's easy to understand. Now, at this point we're going to program the events for when the user warps to the quest map. In your QuestMapData sub, we want to ads this: Code: Select Case GetPlayerMap(index) Case 3 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 End Select Okay, I wont go into enormous detail here, you should start to get the hang of the flag commands. This checks to see if we are on the quest map, if we are, we make sure the flag height is 1, because if not then we haven' started the quest yet. Then we are going to use the raise flag command to raise flag 1, by 1 more, so now it = 2. Now, we go back into the quest sub and finish off the quest. Code: 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. Call SetQuestMap(index, 3, 0) 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 What this does is tell the game we went to the forest and we found out it wasn't that muddy. But our inventory is full. So she tells us to come back. We hit the bank and drop some stuff, run back to janelle and she rewards us with 100 gold coins! **Note: I know it's commented but I'll say it anyways. The GiveItem(index, 1, 100) command is programmed in relation to my game, where item 1 is gold. You can choose whatever you want as your reward for the quest, so long as you know the item number. Now, we raise the flag to 3 so the quest can never be repeated again, unless the admin deletes the flag files. After that we set the Questmap back to 0 so that it can later be deleted from the INI file. Makes it a bit smaller. And that's it. Now all you need to do is start up the game, and go to the map editor. Choose attributes, click Quest Tile, and select the quest, then select a tile you wish to start it on. If anyone has any issues pleasse tell me. I found minor bugs when doing the tutorial and fixed them without testing |
|
| Author: | Krloz [ Mon Jul 03, 2006 5:56 am ] |
| Post subject: | |
Amagad what a great work from you =) I will be adding this soon |
|
| Author: | Leighland [ Mon Jul 03, 2006 7:22 pm ] |
| Post subject: | |
Don't add it so soon :p, I just tested it this morning and it gave me an error when trying to create the folders. I'll fix it and post back after work. EDIT: Minor Error, the LCase and Ucas eget me every time lol. Fixed it above. |
|
| Author: | Xlithan [ Sun Jan 21, 2007 11:45 pm ] |
| Post subject: | |
Would there be any chance of making a proper editor for this instead of hard-coding it? I'm creating a closed source engine so it would be great to have that ability. |
|
| Author: | William [ Mon Jan 22, 2007 9:35 am ] |
| Post subject: | |
GameBoy wrote: Would there be any chance of making a proper editor for this instead of hard-coding it? I'm creating a closed source engine so it would be great to have that ability.
Would not be hard at all. |
|
| Author: | Leighland [ Thu Jan 25, 2007 9:20 am ] |
| Post subject: | |
William wrote: GameBoy wrote: Would there be any chance of making a proper editor for this instead of hard-coding it? I'm creating a closed source engine so it would be great to have that ability. Would not be hard at all. Sorry haven't been around for a bit. William is right. All the subs are there on the server side, which should make it exceptionally easy to create an editor. |
|
| Author: | Boo [ Fri Mar 23, 2007 9:47 pm ] |
| Post subject: | |
does this work? |
|
| Author: | Reece [ Fri Mar 23, 2007 10:26 pm ] |
| Post subject: | |
Boo wrote: does this work?
Try it and find out. |
|
| Author: | Leighland [ Sat Mar 24, 2007 6:12 am ] |
| Post subject: | |
Yes Boo, it does work. Not very well though I have to admit. I threw this together when I first started with Mirage and it could probably be done a whole lot better, actually I know it can lol. Go ahead and implement it if you wish, but it's verybasic and probably not the most sufficient way of doing this. BTW: 200th post DING DING |
|
| Author: | Boo [ Sat Mar 24, 2007 6:35 am ] |
| Post subject: | |
ya my friend just said he'll program me 1 thats better xD. |
|
| Author: | Leighland [ Sun Mar 25, 2007 6:37 pm ] |
| Post subject: | |
Boo wrote: ya my friend just said he'll program me 1 thats better xD.
THat's probably a good idea |
|
| Page 1 of 1 | All times are UTC |
| Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |
|