----=====
Chest Tile tutorial =====----
Difficulty:
3/5
All this
tutorial will do is allow chests to be placed on tiles, display them being
opened and closed, allow you to block players from opening them a second time
and update the chests.
This isn’t
exactly based on anything else, though I did advise someone to try copying
what’s already in the code I’m doing it this way because I can implement
features better like this =)
Overview
(Written after finishing this)
When this
is finished you should be able to create a chest with the help of a chest
editor that will display 3 item lists that will also give the name, type of
item and the picture once you’ve clicked on an item. You can also set if a player is able to open
the chest more then once and if the chest is edited then a player is
automatically able to reopen the new chest.
Only problem with this is that if you use two or more of the same chests
anywhere and one is opened, they are all set as opened until the time set to
close after has elapsed, same for if the player is only allowed to open the
chest once, even if they open the same map in a different location it will
count as the same map.
http://img372.imageshack.us/my.php?image=chesteditoraction1hb.png">
^^^ ChestEditor
http://img216.imageshack.us/my.php?image=chestmap6as.png">
^^^ Chest Tile
Ok, Lets
start by adding a Chest type that will basically describe a new data type and
what it will store (Like chest items etc)
Add the
following code to the bottom of modTypes in both server and client
Type
ChestRec
ChestName As String ' ShortHandName
ItemOne As Integer
ItemTwo As Integer
ItemThree As Integer
StayOpen As Integer ' How long it stays
open (Seconds)
OpenOnce As Boolean ' Weither players can
open it more then once
Revision As Byte ' Chest Version (If chest
is editted we might want player to open it again)
' --- Open Chest Anim
OpenTileX As Integer
OpenTileY As Integer
' --- Closed Chest Anim
ClosedTileX As Integer
ClosedTileY As Integer
End Type
Now we need
to add a constant that dictates how many different chests can be made add one
time, so in both Client and server in modConstants find’MAX_PLAYERS’ and under
it, add:
Public
Const MAX_CHESTS = 100
Now we need
to actually make the variable that will store each chests detail so find in
both Server and clients
Public Spell(1 To MAX_SPELLS) As
SpellRec
And add
under it add
Public
Chest(1 To MAX_CHESTS) As ChestRec
Now, add a
new form to the client, and change the following properties
Name -
frmChestEditor
BorderStyle -
1 - Fixed Single
Caption -
Chest Editor
StartUpPosition - 2 - Center Screen
Now, add a
textbox somewhere (This will be the chest name)
Name - txtName
Text - (empty)
Now add three
ListBoxes and for each one change the properties to
Name - lstItem
Index - Give the 1st listbox 1
2nd listbox 2
3rd
listbox 3
Add 3
Labels, each one under the Listboxes above, then Change the properties to
Name - lblItemName
Alignment - 2 - Center
Caption - Item Name
Index - 1, 2, 3 (Corresponding to the
listboxs above them)
Yet again,
add another 3 labels under the above labels
Name - lblItemType
Alignment - 2 - Center
Caption - Item Type
Index - 1, 2, 3 (Corresponding to the
labels above them)
Now we need
some Picture boxes for the items to blt into, so start this off by adding three
picture boxes under the label you’ve just added and change the properties to
these:
Name - picItem
Index - 1, 2, 3 (Same as above, give
it the same index as the objects above it)
Height - 480 (32 pixels)
Width - 480 (32 Pixels)
Yay, still
more to come, add a checkbox and the change the properties to;
Name - chkOpenAgain
Caption - Open Once
Time for
the objects that will help with how the long the chest will be open for =)
Add a
Horizontal Scrollbar (or vertical which ever you prefer)
Name - scrlTime
LargeChange - 100
Max - 32767
Value - 10
Min - 1
Now a label
Name - lblTime
Caption - 10
And a
textbox
Name - txtTime
Text - 10
And finally
add two command buttons
Name - cmdSave and cmdCancel
Cancel - cmdCancel = true
Default - cmdSave = true
Now all you
need to do is add a few labels to show what each thing does.
Once you’ve
done that, you should have a form that looks something like this…
http://img132.imageshack.us/my.php?image=chesteditor9tw.png">
Now a bit
of code for the form, this is all the code that will go into this form, but
it’ll do for now
Double
Click on the cancel button and add
Unload me
Unload frmTiles
Basic line
just closes the form and clears it from memory (It also serves to close a form
I’ll be adding later)
Now we need
the scrollbar to change the textbox and the label that display the same value
so double click the scrollbar and add
' --- Change the values for the txt and
lbls
lblTime.Caption = scrlTime.Value
txtTime.Text = scrlTime.Value
We also
need to do the same for the text box but since we cannot place a limit on the
text box, we need to add some range checks and check if the number is numeric,
so double click the text box and put this code in, it should be self
explanatory.
' --- Check if the time entered is within
range and is actually a number
If Not IsNumeric(txtTime.Text) Then
txtTime.Text = 10
If txtTime.Text > scrlTime.Max Then
txtTime.Text = scrlTime.Max
If txtTime.Text < scrlTime.Min Then
txtTime.Text = scrlTime.Min
' --- Change the values for the txt and
lbls
lblTime.Caption = txtTime.Text
scrlTime.Value = txtTime.Text
Now we need
a way to activate Chest Editor so let’s start with the text command, find
' Map Editor
If LCase(Mid(MyText, 1, 10)) =
"/mapeditor" Then
Call SendRequestEditMap
MyText = ""
Exit Sub
End If
And below
it add;
' Chest Editor
If LCase(Mid(MyText, 1, 12)) =
"/chesteditor" Then
Call SendRequestEditChest
MyText = ""
Exit Sub
End If
Basically,
it checks if the first 12 letters = /chesteditor and if it is, it will send a
packet to the server requesting chest editor and will then clear the text
onscreen.
Now we need
code for the server to run once it’s received the packet so find in the server:
' :::::::::::::::::::::::::::::
' :: Request edit map packet ::
' :::::::::::::::::::::::::::::
If LCase(Parse(0)) =
"requesteditmap" Then
' Prevent hacking
If GetPlayerAccess(Index) <
ADMIN_MAPPER Then
Call HackingAttempt(Index,
"Admin Cloning")
Exit Sub
End If
Call SendDataTo(Index,
"EDITMAP" & SEP_CHAR & END_CHAR)
Exit Sub
End If
And under
it, add;
' :::::::::::::::::::::::::::::::
' :: Request edit Chest packet ::
' :::::::::::::::::::::::::::::::
If LCase(Parse(0)) =
"requesteditchest" Then
' Prevent hacking
If GetPlayerAccess(Index) <
ADMIN_MAPPER Then
Call HackingAttempt(Index,
"Admin Cloning")
Exit Sub
End If
Dim packet As String
packet = "CHESTEDITOR" &
SEP_CHAR
For n = 1 To MAX_CHESTS
packet = packet &
Chest(n).ChestName & SEP_CHAR
Next n
Call SendDataTo(Index, packet &
END_CHAR)
Exit Sub
End If
Now, we
need to allow the client to do something when we receive the packet so find in
the client:
' ::::::::::::::::::::
' :: Social packets ::
'
::::::::::::::::::::
If (LCase(Parse(0)) = "saymsg")
Or (LCase(Parse(0)) = "broadcastmsg") Or (LCase(Parse(0)) =
"globalmsg") Or (LCase(Parse(0)) = "playermsg") Or
(LCase(Parse(0)) = "mapmsg") Or (LCase(Parse(0)) =
"adminmsg") Then
Call AddText(Parse(1), Val(Parse(2)))
Exit Sub
End If
And under
it add:
' :::::::::::::::::::::::::
' :: Chest editor packet ::
' :::::::::::::::::::::::::
If (LCase(Parse(0)) =
"chesteditor") Then
InChestEditor = True
'---Update chest names
For n = 1 To MAX_CHESTS
Chest(n).ChestName = Parse(n + 1)
Next n
frmIndex.Show
frmIndex.lstIndex.Clear
' Add the names
For i = 1 To MAX_CHESTS
frmIndex.lstIndex.AddItem i &
": " & Trim(Chest(i).ChestName)
Next i
frmIndex.lstIndex.ListIndex = 0
Exit Sub
End If
This pretty
much opens up index form and lists all the chest names down in the list and
also set a flag (InChestEditor) so we know what were meant to be editing.
Now, we
need to declare the flag so find: (Still in the client)
Public
InSpellEditor As Boolean
And add:
Public
InChestEditor As Boolean
Now you
also need to find
InSpellEditor = False
And add:
InChestEditor = False
And also
find:
If InSpellEditor = True Then
Call SendData("EDITSPELL"
& SEP_CHAR & EditorIndex & SEP_CHAR & END_CHAR)
End If
And under
that, add
If InChestEditor = True Then
Call SendData("EDITCHEST"
& SEP_CHAR & EditorIndex & SEP_CHAR & END_CHAR)
End If
Now this is
the part where the server actually sends the chest details to the client for
editing so find what you added earlier in the server
' :::::::::::::::::::::::::::::::
' :: Request edit Chest packet ::
' :::::::::::::::::::::::::::::::
If LCase(Parse(0)) =
"requesteditchest" Then
' Prevent hacking
If GetPlayerAccess(Index) <
ADMIN_MAPPER Then
Call HackingAttempt(Index,
"Admin Cloning")
Exit Sub
End If
Dim packet As String
packet = "CHESTEDITOR" &
SEP_CHAR
For n = 1 To MAX_CHESTS
packet = packet &
Chest(n).ChestName & SEP_CHAR
Next n
Call SendDataTo(Index, packet &
END_CHAR)
Exit Sub
End If
Now
underneath it add:
' :::::::::::::::::::::::
' :: Edit chest packet ::
' :::::::::::::::::::::::
If LCase(Parse(0)) = "editchest"
Then
' Prevent hacking
If GetPlayerAccess(Index) <
ADMIN_MAPPER Then
Call HackingAttempt(Index,
"Admin Cloning")
Exit Sub
End If
' The item #
n = Val(Parse(1))
' Prevent hacking
If n < 0 Or n > MAX_CHESTS Then
Call HackingAttempt(Index,
"Invalid Item Index")
Exit Sub
End If
Call AddLog(GetPlayerName(Index) &
" editing item #" & n & ".", ADMIN_LOG)
Call SendEditChestTo(Index, n)
End If
Also find
Sub
SendPlayerXY(ByVal Index As Long)
Dim Packet
As String
Packet = "PLAYERXY" &
SEP_CHAR & GetPlayerX(Index) & SEP_CHAR & GetPlayerY(Index) &
SEP_CHAR & END_CHAR
Call SendDataTo(Index, Packet)
End Sub
And add:
Sub
SendEditChestTo(ByVal Index As Long, ByVal ChestNum As Long)
Dim Packet
As String
Packet = "EDITCHEST" &
SEP_CHAR & ChestNum & SEP_CHAR & Trim(Chest(ChestNum).ChestName)
& SEP_CHAR & Chest(ChestNum).ItemOne & SEP_CHAR &
Chest(ChestNum).ItemTwo & SEP_CHAR & Chest(ChestNum).ItemThree &
SEP_CHAR & Chest(ChestNum).OpenOnce & SEP_CHAR &
Chest(ChestNum).StayOpen & SEP_CHAR & Chest(ChestNum).ClosedTileX &
SEP_CHAR & Chest(ChestNum).ClosedTileY & SEP_CHAR &
Chest(ChestNum).OpenTileX & SEP_CHAR & Chest(ChestNum).OpenTileY &
SEP_CHAR & END_CHAR
Call SendDataTo(Index, Packet)
End Sub
The code
above just sends one of the chests details to the client ready to be viewed and
edited.
The client
needs to interpret this, so find what you did earlier:
' :::::::::::::::::::::::::
' :: Chest editor packet ::
' :::::::::::::::::::::::::
If (LCase(Parse(0)) = "chesteditor")
Then
InChestEditor = True
'---Update chest names
For n = 1 To MAX_CHESTS
Chest(n).ChestName = Parse(n + 1)
Next n
frmIndex.Show
frmIndex.lstIndex.Clear
' Add the names
For i = 1 To MAX_CHESTS
frmIndex.lstIndex.AddItem i &
": " & Trim(Chest(i).ChestName)
Next i
frmIndex.lstIndex.ListIndex = 0
Exit Sub
End If
And add
under it:
' :::::::::::::::::::::::
' :: Edit Chest packet ::
' :::::::::::::::::::::::
If (LCase(Parse(0)) =
"editchest") Then
n = Val(Parse(1))
' Update the chest
Chest(n).ChestName = Parse(2)
Chest(n).ItemOne = Val(Parse(3))
Chest(n).ItemTwo = Val(Parse(4))
Chest(n).ItemThree = Val(Parse(5))
Chest(n).OpenOnce = Parse(6)
Chest(n).StayOpen = Val(Parse(7))
Chest(n).ClosedTileX = Val(Parse(8))
Chest(n).ClosedTileY = Val(Parse(9))
Chest(n).OpenTileX = Val(Parse(10))
Chest(n).OpenTileY = Val(Parse(11))
' Initialize the chest editor
Call ChestEditorInit
Exit Sub
End If
Now, we
need to create the sub ‘ChestEditorInit’ that we’ve called in the above piece
of code, all the sub does is load the details onto the Chest Editor form then
loads the form, so find the sub
Public Sub
ItemEditorBltItem()
And
underneath the sub, add this sub
Public Sub
ChestEditorInit()
Dim n As
Long, i As Long
' --- Set all the basic settings
frmChestEditor.txtName = Chest(EditorIndex).ChestName
If Chest(EditorIndex).OpenOnce = True Then
frmChestEditor.chkOpenAgain = 1
If Chest(EditorIndex).StayOpen <
frmChestEditor.scrlTime.Value Then Chest(EditorIndex).StayOpen =
frmChestEditor.scrlTime.Min
frmChestEditor.scrlTime.Value =
Chest(EditorIndex).StayOpen
' --- Add the items to the listboxes
For n = 1 To 3
frmChestEditor.lstItem(n).AddItem
"No Item"
For i = 1 To MAX_ITEMS
frmChestEditor.lstItem(n).AddItem i
& ": " & Item(i).Name
Next i
Next n
frmChestEditor.lstItem(1).ListIndex =
Chest(EditorIndex).ItemOne
frmChestEditor.lstItem(2).ListIndex =
Chest(EditorIndex).ItemTwo
frmChestEditor.lstItem(3).ListIndex =
Chest(EditorIndex).ItemThree
frmChestEditor.Show
End Sub
Ok, now we
need to add some more code to the chest editor, this new bit of code will add
the ability to view item picture, name and type when we click on it. First let’s deal with getting the item name.
Double
click on one of the listbox on the chest editor window and add this piece of
code:
If frmChestEditor.lstItem(Index).ListIndex
> 0 Then
lblItemName(Index).Caption =
Trim(Item(lstItem(Index).ListIndex).Name)
Else
lblItemName(Index).Caption =
"N/A"
End If
This just
checks if an item is selected, if it is, it will retrieve the item name, if not
it will just replace it with N/A
Now we need
to change the item type label, so under
lblItemName(Index).Caption =
Trim(Item(lstItem(Index).ListIndex).Name)
(Which you
just added) Add this bit:
Select Case Item(lstItem(Index).ListIndex).Type
Case 0
lblItemType(Index).Caption =
"None"
Case 1
lblItemType(Index).Caption =
"Weapon"
Case 2
lblItemType(Index).Caption =
"Armour"
Case 3
lblItemType(Index).Caption =
"Helmet"
Case 4
lblItemType(Index).Caption =
"Shield"
Case 5
lblItemType(Index).Caption =
"Potion Add HP"
Case 6
lblItemType(Index).Caption =
"Potion Add MP"
Case 7
lblItemType(Index).Caption =
"Potion Add SP"
Case 8
lblItemType(Index).Caption =
"Potion SUB HP"
Case 9
lblItemType(Index).Caption =
"Potion SUB MP"
Case 10
lblItemType(Index).Caption =
"Potion SUB SP"
Case 11
lblItemType(Index).Caption =
"Key"
Case 12
lblItemType(Index).Caption =
"Currency"
Case 13
lblItemType(Index).Caption =
"Spell"
End Select
This may
look like quite a bit but its nothing really, all it is checking what type it
is, and depending on the type of item, will change the label to different text
Also, under
the other bit you just added
lblItemName(Index).Caption = "N/A"
Add:
lblItemType(Index).Caption =
"N/A"
TADA
Now the
form displays the item details, but now we can go one step better and display a
picture. I’m not going to do this the
normal way where another copy of the items.bmp is loaded into a picture box
since that wastes so much memory considering its already loaded into a direct
draw surface, so I’m going to do some blting!!
YAY! |