20-02-2008, 06:55 PM
OK! This is my tutorial on how to add options to your game. These will be simple On/Off options such as when the player want to display the FPS or not. OK! The tutorial will show you how to add a frmOptions that displays when the user types '/opt' and the ability to turn all options on or off by typing '/opt on' or '/opt off'. This tutorial was bade for MSE Build 1. Remember to back up your source!
Difficulty: 2/5 (C/P really, try to understand it though)
Creator: Stomach Pulser
::Client Side::
We will start off in 'modConstants'. At the very bottom add the following five constants:
Why is OPT_FINAL the same as DISP_PLR_MP_BARS? Well, it is set that so we can always use OPT_FINAL as the last one, if we want to add more options in later, we just change OPT_FINAL to whatever the last constant is.
Now head over to 'modTypes'. Go into the PlayerRec and add an array to the bottom, so that it starts at 0 and ends at OPT_FINAL:
This is here to hold the player's option choices (on or off).
Open up 'modGameLogic'. At the very bottom add these functions/subs:
Woah! That's a good bit of code. Let's take it apart now...
The function GetPlayerOption does just that. It takes the player and the option given (0 ~ 4) and the returns whether it is on (true) or off (false).
The sub SetPlayerOption is similar. It takes the player and set the option given (0 ~ 4) to on or off.
The function ReadPlayerOption returns the option back as a string. This is where our constants come into play. By using the select case with our constants, it makes the code more readable in case you want to add more options or take some out.
The sub PlayerOptionsInit is going to be used to set up our frmOptions to display the users current options.
The sub PlayerOptionsOK is going to be used to get what the player selects in frmOptions and send it to the client for saving. It is only called if the user clicks OK in frmOptions.
Now, let's set up our packet system. Go into 'modClientTCP' and add the following subs at the very bottom:
These will be used later, but we should discuss what they do anyways...
The sub SendGetPlayerOptions is a request. It asks the server to send over the player's saved data for their options. It is used to load the player.
The sub SendUpdatePlayerOptions takes the player's option choices and then send them to the server, asking for the server to save them.
OK, now go into the 'modHandleData' and add this at the very bottom, right before where it says 'end sub':
Basically, this says that if the server sends a packet called updatepoptions then we are going to take the data in it and save it to the player. This is how we load saved data from the server.
Head back over to 'modGameLogic'. Inside the sub 'HandleData', find:
After that add this:
If you don't understand it it's OK! Let me draw it out for you...
First off, we check to see if the user typed in “/optâ€. If they did, then we check to see if they added anything after that. If they did, we assign it to the variable chat text. Next, we check to see what chat text is. If it is on or off then we set all of the player's option choices to on or off, respectively and then send a packet to the server telling it to save that. If they didn't type in chat text, then we open up our frmOptions through the InitPlayerOptions. Because we added:
The code will not execute until frmOptions is closed (when we either click OK or Cancel). After frmOptions is closed, we send a packet to the server to save those new options through the use of the sub PlayerOptionsOK, then we display the users option choices so far by using the ReadPlayerOption function. That is it.
The last thing we need to do client wise is add the actual frmOptions itself. To do this click on the Project tab in the menu bar up top. Click on Add Form. Then, make sure the dialog box sets it to Form and hit OK.
Rename this form to frmOptions.
Set the caption to whatever you want and start adding GUI.
Add two command buttons, rename them to cmdSend and cmdCancel. Captions set to whatever you want. Next, add a frame, and name it fraOpt[b]. Set the caption to your longest option (text wise), in this case it would be [b]Display Map Coordinates. Next, add two option buttons to the frame. Name them optOn and optOff. Next, click on the frame and press Ctrl + C to copy it. Then, press Ctrl + V to paste it. A dialog box will pop up asking if you want to make the frame a control array. Press OK. The dialog will ask again for your option buttons, again press OK. Arrange them how you want. The final piece of GUI is a lone label. Set it's name to lblIndex and set the visible property to False. This label will store who the player is. Now, we add the code.
Double click on your cmdSend and add the following under it:
This just says that when you click the button, it will take the options and set them to the player.
Double click on your cmdCancel and add the following under it:
No need to clear the settings as they are reset when we start up frmOptions again.
Phew! That is a lot of things Client Side. But, we are done with that much, the next part is about the same.
::Server Side::
Start off in 'modConstants'. At the very bottom add this:
Go into 'modTypes' and add this at the bottom of PlayerRec:
Go into 'modDatabase' and add the following into the sub SavePlayer at the very bottom, before the 'next i':
This just writes the option data to the player's .ini for their current character.
Find the sub LoadPlayer at the very bottom, before the 'next I' add this:
This simply loads the data from the player's .ini into their current char.
Go into 'modServerTCP' and add the following sub at the very bottom:
This is how we load things into the client. This takes the saved values and send them to the client.
Now, go into your 'modHandleData' and add the following in before the end sub call:
This are things the client tells us to do. If the client wants the information on the player's options (packet 1), we sent it. If the client sent us information, we update it (packet 2).
Go into 'modGameLogic'. Add the following at the very end of the sub ClearChar:
Finally, add the following at the very bottom of 'modGameLogic':
That is it! If you have any questions/comments, post it here or PM me. Here is what my frmOptions looks like:
![[Image: frmoptionsks7.png]](http://img219.imageshack.us/img219/940/frmoptionsks7.png)
Difficulty: 2/5 (C/P really, try to understand it though)
Creator: Stomach Pulser
::Client Side::
We will start off in 'modConstants'. At the very bottom add the following five constants:
Code:
' Player Option Constants
Public Const OPT_DISP_COORDS = 0
Public Const OPT_DISP_FPS = 1
Public Const OPT_DISP_NPC_HP_BARS = 2
Public Const OPT_DISP_PLR_HP_BARS = 3
Public Const OPT_DISP_PLR_MP_BARS = 4
Public Const OPT_FINAL = 4
Now head over to 'modTypes'. Go into the PlayerRec and add an array to the bottom, so that it starts at 0 and ends at OPT_FINAL:
Code:
' Options
POption(0 To OPT_FINAL) As Byte
Open up 'modGameLogic'. At the very bottom add these functions/subs:
Code:
Function GetPlayerOption(ByVal Index As Long, ByVal Opt As Byte) As Byte
GetPlayerOption = Player(Index).POption(Opt)
End Function
Sub SetPlayerOption(ByVal Index As Long, ByVal Opt As Byte, ByVal YesNo As Byte)
Player(Index).POption(Opt) = YesNo
End Sub
Function ReadPlayerOption(ByVal Opt As Byte) As String
Select Case Opt
Case OPT_DISP_COORDS
ReadPlayerOption = "Display FPS: "
Case OPT_DISP_FPS
ReadPlayerOption = "Display Map Coordinates: "
Case OPT_DISP_NPC_HP_BARS
ReadPlayerOption = "Display NPC HP Bars: "
Case OPT_DISP_PLR_HP_BARS
ReadPlayerOption = "Display Player HP Bars: "
Case OPT_DISP_PLR_MP_BARS
ReadPlayerOption = "Display Player MP Bars: "
End Select
End Function
Sub PlayerOptionsInit(ByVal Index As Long)
Dim i
For i = 0 To OPT_FINAL
frmOptions.fraOpt(i).Caption = ReadPlayerOption(i)
If GetPlayerOption(Index, i) = YES Then
frmOptions.optOn(i).Value = True
ElseIf GetPlayerOption(Index, i) = NO Then
frmOptions.optOff(i).Value = True
Else
frmOptions.optOn(i).Value = True
End If
Next i
frmOptions.lblIndex = STR(Index)
frmOptions.Visible = True
End Sub
Sub PlayerOptionsOK(ByVal Index As Long)
Dim i
For i = 0 To OPT_FINAL
If frmOptions.optOn(i).Value = True Then
Call SetPlayerOption(Index, i, YES)
ElseIf frmOptions.optOff(i).Value = True Then
Call SetPlayerOption(Index, i, NO)
Else
Call MsgBox("Deathlycat caught you hacking!!!")
End If
Next i
Call SendUpdatePlayerOptions(Index)
End Sub
The function GetPlayerOption does just that. It takes the player and the option given (0 ~ 4) and the returns whether it is on (true) or off (false).
The sub SetPlayerOption is similar. It takes the player and set the option given (0 ~ 4) to on or off.
The function ReadPlayerOption returns the option back as a string. This is where our constants come into play. By using the select case with our constants, it makes the code more readable in case you want to add more options or take some out.
The sub PlayerOptionsInit is going to be used to set up our frmOptions to display the users current options.
The sub PlayerOptionsOK is going to be used to get what the player selects in frmOptions and send it to the client for saving. It is only called if the user clicks OK in frmOptions.
Now, let's set up our packet system. Go into 'modClientTCP' and add the following subs at the very bottom:
Code:
Sub SendGetPlayerOptions(ByVal Index As Long)
Dim CatPacket As String
CatPacket = "GETPOPTIONS" & SEP_CHAR & END_CHAR
Call SendData(CatPacket)
End Sub
Sub SendUpdatePlayerOptions(ByVal Index As Long)
Dim CatPacket As String
Dim i As Byte
CatPacket = "UPDATEPOPTIONS" & SEP_CHAR
For i = 0 To OPT_FINAL
CatPacket = CatPacket & STR(GetPlayerOption(Index, i)) & SEP_CHAR
Next i
CatPacket = CatPacket & END_CHAR
Call SendData(CatPacket)
End Sub
The sub SendGetPlayerOptions is a request. It asks the server to send over the player's saved data for their options. It is used to load the player.
The sub SendUpdatePlayerOptions takes the player's option choices and then send them to the server, asking for the server to save them.
OK, now go into the 'modHandleData' and add this at the very bottom, right before where it says 'end sub':
Code:
' ::::::::::::::::::::::::::::
' :: Update POptions packet ::
' ::::::::::::::::::::::::::::
If LCase(Parse(0)) = "updatepoptions" Then
n = 1
For i = 0 To OPT_FINAL
Call SetPlayerOption(MyIndex, i, Val(Parse(n)))
n = n + 1
Next i
Exit Sub
End If
Head back over to 'modGameLogic'. Inside the sub 'HandleData', find:
Code:
' Leave party
If LCase(Mid(MyText, 1, 6)) = "/leave" Then
Call SendLeaveParty
MyText = ""
Exit Sub
End If
Code:
' Options Request
If LCase(Mid(MyText, 1, 4)) = "/opt" Then
If Len(MyText) > 5 Then
ChatText = Mid(MyText, 6, Len(MyText) - 5)
If LCase(ChatText) = "on" Then
For i = 0 To OPT_FINAL
Call SetPlayerOption(MyIndex, i, YES)
Next i
Call SendUpdatePlayerOptions(MyIndex)
ElseIf LCase(ChatText) = "off" Then
For i = 0 To OPT_FINAL
Call SetPlayerOption(MyIndex, i, NO)
Next i
Call SendUpdatePlayerOptions(MyIndex)
End If
Else
Call PlayerOptionsInit(MyIndex)
End If
For i = 0 To OPT_FINAL
If GetPlayerOption(MyIndex, i) = NO Then
Call AddText(ReadPlayerOption(i) & "No", Red)
ElseIf GetPlayerOption(MyIndex, i) = YES Then
Call AddText(ReadPlayerOption(i) & "Yes", White)
Else
Call AddText(ReadPlayerOption(i) & "Invalid", AlertColor)
End If
Next i
MyText = ""
Exit Sub
End If
First off, we check to see if the user typed in “/optâ€. If they did, then we check to see if they added anything after that. If they did, we assign it to the variable chat text. Next, we check to see what chat text is. If it is on or off then we set all of the player's option choices to on or off, respectively and then send a packet to the server telling it to save that. If they didn't type in chat text, then we open up our frmOptions through the InitPlayerOptions. Because we added:
Code:
frmOptions.Show vbModal
The last thing we need to do client wise is add the actual frmOptions itself. To do this click on the Project tab in the menu bar up top. Click on Add Form. Then, make sure the dialog box sets it to Form and hit OK.
Rename this form to frmOptions.
Set the caption to whatever you want and start adding GUI.
Add two command buttons, rename them to cmdSend and cmdCancel. Captions set to whatever you want. Next, add a frame, and name it fraOpt[b]. Set the caption to your longest option (text wise), in this case it would be [b]Display Map Coordinates. Next, add two option buttons to the frame. Name them optOn and optOff. Next, click on the frame and press Ctrl + C to copy it. Then, press Ctrl + V to paste it. A dialog box will pop up asking if you want to make the frame a control array. Press OK. The dialog will ask again for your option buttons, again press OK. Arrange them how you want. The final piece of GUI is a lone label. Set it's name to lblIndex and set the visible property to False. This label will store who the player is. Now, we add the code.
Double click on your cmdSend and add the following under it:
Code:
Call PlayerOptionsOK(frmOptions.lblIndex)
Me.Visible = False
Double click on your cmdCancel and add the following under it:
Code:
Me.Visible = False
Phew! That is a lot of things Client Side. But, we are done with that much, the next part is about the same.
::Server Side::
Start off in 'modConstants'. At the very bottom add this:
Code:
' Player Option Constants
Public Const OPT_DISP_COORDS = 0
Public Const OPT_DISP_FPS = 1
Public Const OPT_DISP_NPC_HP_BARS = 2
Public Const OPT_DISP_PLR_HP_BARS = 3
Public Const OPT_DISP_PLR_MP_BARS = 4
Public Const OPT_FINAL = 4
Code:
POption(0 To OPT_FINAL) As Byte
Code:
' Options
For n = 0 To OPT_FINAL
Call PutVar(FileName, "CHAR" & i, "OPTION" & n, STR(Player(Index).Char(i).POption(n)))
Next n
Find the sub LoadPlayer at the very bottom, before the 'next I' add this:
Code:
' Options
For n = 0 To OPT_FINAL
Player(Index).Char(i).POption(n) = Val(GetVar(FileName, "CHAR" & i, "OPTION" & n))
Next n
Go into 'modServerTCP' and add the following sub at the very bottom:
Code:
Sub SendPlayerOptions(ByVal Index As Long)
Dim CatPacket As String
Dim i As Byte
CatPacket = "UPDATEPOPTIONS" & SEP_CHAR
For i = 0 To OPT_FINAL
CatPacket = CatPacket & STR(GetPlayerOption(Index, i)) & SEP_CHAR
Next i
CatPacket = CatPacket & END_CHAR
Call SendDataTo(Index, CatPacket)
End Sub
Now, go into your 'modHandleData' and add the following in before the end sub call:
Code:
' :::::::::::::::::::::::::
' :: Send POptions packet::
' :::::::::::::::::::::::::
If LCase(Parse(0)) = "getpoptions" Then
Call SendPlayerOptions(Index)
Exit Sub
End If
' :::::::::::::::::::::::::::
' :: Update POptions packet::
' :::::::::::::::::::::::::::
If LCase(Parse(0)) = "updatepoptions" Then
n = 1
For i = 0 To OPT_FINAL
Call SetPlayerOption(Index, i, Val(Parse(n)))
n = n + 1
Next i
Call SavePlayer(Index)
Exit Sub
End If
End Sub
Go into 'modGameLogic'. Add the following at the very end of the sub ClearChar:
Code:
For n = 0 To OPT_FINAL
Player(Index).Char(CharNum).POption(n) = NO
Next n
Finally, add the following at the very bottom of 'modGameLogic':
Code:
Function GetPlayerOption(ByVal Index As Long, ByVal Opt As Byte)
GetPlayerOption = Player(Index).Char(Player(Index).CharNum).POption(Opt)
End Function
Sub SetPlayerOption(ByVal Index As Long, ByVal Opt As Byte, ByVal YesNo As Byte)
Player(Index).Char(Player(Index).CharNum).POption(Opt) = YesNo
End Sub
That is it! If you have any questions/comments, post it here or PM me. Here is what my frmOptions looks like:
![[Image: frmoptionsks7.png]](http://img219.imageshack.us/img219/940/frmoptionsks7.png)
Code:
Version Log
v1.0 ~ 2/20/08 - Guide created and posted
v1.1 ~ Fixed up a weird error while loading/saving and an error whilst opening frmOptions