Print Page | Close Window

Signs

Printed From: Mirage Source
Category: Tutorials
Forum Name: Approved Tutorials
Forum Discription: All tutorials shown to actually work with MSE are moved here.
URL: http://ms.shannaracorp.com/backup-forums/forum_posts.asp?TID=56
Printed Date: 20 December 2006 at 6:01pm
Software Version: Web Wiz Forums 8.01 - http://www.webwizforums.com


Topic: Signs
Posted By: Sync
Subject: Signs
Date Posted: 07 February 2006 at 6:39pm
Originally posted by Dark Echo

MSE does not come with signs, so i thought for those people who want signs in their game here is a easy to follow tutorial i decided to write up.. I tried to do it so signs saved on the actually map, as in data1, date2 and data3, etc.. But that was much too comlicated, so i just made it a basic sign system with a .ini file..

Difficulty: 1/5

Part 1 - Server Side
Go into modConstants and add:
Public Const MAX_SIGNS = 255

Find:
Public Const TILE_TYPE_KEYOPEN = 6

And add below it:
Public Const TILE_TYPE_SIGN = 7

Go into modDatabase and add:
Sub SaveSign(ByVal SignNum As Long)
Dim FileName As String
Dim i As Long

    FileName = App.Path & "\data\signs.ini"
   
    Call PutVar(FileName, "SIGN" & SignNum, "Name", Trim(Sign(SignNum).Name))
    Call PutVar(FileName, "SIGN" & SignNum, "Line1", Trim(Sign(SignNum).Line1))
    Call PutVar(FileName, "SIGN" & SignNum, "Line2", Trim(Sign(SignNum).Line2))
End Sub

Sub SaveSigns()
Dim i As Long

    For i = 1 To MAX_SIGNS
        Call SaveSign(i)
    Next i
End Sub

Sub LoadSigns()
Dim FileName As String
Dim i As Long

    Call CheckSigns
   
    FileName = App.Path & "\data\signs.ini"
   
    For i = 1 To MAX_SIGNS
        Sign(i).Name = Trim(GetVar(FileName, "SIGN" & i, "Name"))
        Sign(i).Line1 = Trim(GetVar(FileName, "SIGN" & i, "Line1"))
        Sign(i).Line2 = Trim(GetVar(FileName, "SIGN" & i, "Line2"))
       
        DoEvents
    Next i
End Sub

Sub CheckSigns()
    If Not FileExist("data\signs.ini") Then
        Call SaveSigns
    End If
End Sub

Go into modGameLogic and add:
Sub ClearSign(ByVal Index As Long)
    Sign(Index).Name = ""
    Sign(Index).Line1 = ""
    Sign(Index).Line2 = ""
End Sub

Sub ClearSigns()
Dim i As Long

    For i = 1 To MAX_SIGNS
        Call ClearSign(i)
    Next i
End Sub

Go into modGeneral and find:
    Call SetStatus("Loading spells...")
    Call LoadSpells

And add below it:
    Call SetStatus("Loading signs...")
    Call LoadSigns

Go into modGlobals and add:
Public Sign(1 To MAX_SIGNS) As SignRec

Go into modHandleData and add:
    ' ::::::::::::::::::::::::::::::
    ' :: Request edit sign packet ::
    ' ::::::::::::::::::::::::::::::
    If LCase(Parse(0)) = "requesteditsign" Then
        ' Prevent hacking
        If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
             Call HackingAttempt(Index, "Admin Cloning")
             Exit Sub
        End If
       
        Call SendDataTo(Index, "SIGNEDITOR" & SEP_CHAR & END_CHAR)
        Exit Sub
    End If
   
    ' ::::::::::::::::::::::
    ' :: Edit sign packet ::
    ' ::::::::::::::::::::::
    If LCase(Parse(0)) = "editsign" Then
        ' Prevent hacking
        If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
             Call HackingAttempt(Index, "Admin Cloning")
             Exit Sub
        End If
       
        ' The sign #
        n = Val(Parse(1))
       
        ' Prevent hacking
        If n < 0 Or n > MAX_SIGNS Then
             Call HackingAttempt(Index, "Invalid Sign Index")
             Exit Sub
        End If
       
        Call AddLog(GetPlayerName(Index) & " editing sign #" & n & ".", ADMIN_LOG)
        Call SendEditSignTo(Index, n)
    End If
   
    ' ::::::::::::::::::::::
    ' :: Save sign packet ::
    ' ::::::::::::::::::::::
    If (LCase(Parse(0)) = "savesign") Then
        ' Prevent hacking
        If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
             Call HackingAttempt(Index, "Admin Cloning")
             Exit Sub
        End If
       
        ' Sign #
        n = Val(Parse(1))
       
        ' Prevent hacking
        If n < 0 Or n > MAX_SIGNS Then
             Call HackingAttempt(Index, "Invalid Sign Index")
             Exit Sub
        End If
       
        ' Update the sign
        Sign(n).Name = Trim(Parse(2))
        Sign(n).Line1 = Trim(Parse(3))
        Sign(n).Line2 = Trim(Parse(4))
               
        ' Save it
        Call SendUpdateSignToAll(n)
        Call SaveSign(n)
        Call AddLog(GetPlayerName(Index) & " saving sign #" & n & ".", ADMIN_LOG)
        Exit Sub
    End If
   
    ' ::::::::::::::::::
    ' :: Request Sign ::
    ' ::::::::::::::::::
    If (LCase(Parse(0)) = "requestsign") Then
       
        ' Sign #
        n = Val(Parse(1))
       
        ' Prevent hacking
        If n < 0 Or n > MAX_SIGNS Then
             Call HackingAttempt(Index, "Invalid Sign Index")
             Exit Sub
        End If
       
        ' Send sign info
        Call SendSignTo(Index, n)
    End If

Go into modServerTCP and add:
Sub SendSign(ByVal Index As Long)
Dim i As Long

    For i = 1 To MAX_SIGNS
        If Trim(Sign(i).Name) <> "" Then
             Call SendUpdateSignTo(Index, i)
        End If
    Next i
End Sub

Sub SendUpdateSignToAll(ByVal SignNum As Long)
Dim Packet As String

    Packet = "UPDATESIGN" & SEP_CHAR & SignNum & SEP_CHAR & Trim(Sign(SignNum).Name) & SEP_CHAR & END_CHAR
    Call SendDataToAll(Packet)
End Sub

Sub SendUpdateSignTo(ByVal Index As Long, ByVal SignNum As Long)
Dim Packet As String

    Packet = "UPDATESIGN" & SEP_CHAR & SignNum & SEP_CHAR & Trim(Sign(SignNum).Name) & SEP_CHAR & END_CHAR
    Call SendDataTo(Index, Packet)
End Sub

Sub SendEditSignTo(ByVal Index As Long, ByVal SignNum As Long)
Dim Packet As String

    Packet = "EDITSIGN" & SEP_CHAR & SignNum & SEP_CHAR & Trim(Sign(SignNum).Name) & SEP_CHAR & Sign(SignNum).Line1 & SEP_CHAR & Sign(SignNum).Line2 & SEP_CHAR & END_CHAR
    Call SendDataTo(Index, Packet)
End Sub

Sub SendSignTo(ByVal Index As Long, ByVal SignNum As Long)
Dim Packet As String

    Packet = "SIGN" & SEP_CHAR & SignNum & SEP_CHAR & Trim(Sign(SignNum).Name) & SEP_CHAR & Sign(SignNum).Line1 & SEP_CHAR & Sign(SignNum).Line2 & SEP_CHAR & END_CHAR
    Call SendDataTo(Index, Packet)
End Sub

Go into modTypes and add:
Type SignRec
    Name As String * NAME_LENGTH
    Line1 As String * NAME_LENGTH
    Line2 As String * NAME_LENGTH
End Type


Thats all for the server side.. I will post the rest later, i'm tired.. I begun writing this tutorial without posting any code, and just explaining every line you should add in, but without actually telling you how to add it in.. Although, i got lazy and so i just begun posting the code.. Oh well.. Part 2 later..

Ok, i guess i might as well post this part up since well people need it.. Anyway, this part requires you to make two new forms, and a small adjustment to your mapeditor.. But i will explain this later..

Part 2 - Client Side
Go into modClientTCP and add:
Sub SendRequestEditSign()
Dim Packet As String

    Packet = "REQUESTEDITSIGN" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Public Sub SendSaveSign(ByVal SignNum As Long)
Dim Packet As String

    With Sign(SignNum)
        Packet = "SAVESIGN" & SEP_CHAR & SignNum & SEP_CHAR & Trim(.Name) & SEP_CHAR & Trim(.Line1) & SEP_CHAR & Trim(.Line2) & SEP_CHAR & END_CHAR
    End With
   
    Call SendData(Packet)
End Sub

Go into modConstants and add:
Public Const MAX_SIGNS = 255

Find:
Public Const TILE_TYPE_KEYOPEN = 6

And add below it:
Public Const TILE_TYPE_SIGN = 7

Go into modGameLogic and find:
If .Type = TILE_TYPE_KEYOPEN Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "O", QBColor(White))

And add below it:
If .Type = TILE_TYPE_SIGN Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "S", QBColor(White))

Find:
        ' Request stats
        If LCase(Mid(MyText, 1, 6)) = "/trade" Then
             Call SendData("trade" & SEP_CHAR & END_CHAR)
             MyText = ""
             Exit Sub
        End If

And add below it:
        ' Sign
        Dim SignPacket As String
        If Map.Tile(GetPlayerX(MyIndex), GetPlayerY(MyIndex)).Type = TILE_TYPE_SIGN Then
             SignNum = Map.Tile(GetPlayerX(MyIndex), GetPlayerY(MyIndex)).Data1
             SignPacket = "requestsign" & SEP_CHAR & SignNum & SEP_CHAR & END_CHAR
             Call SendData(SignPacket)
       End If

Find:
             ' Banning a player
             If LCase(Mid(MyText, 1, 4)) = "/ban" Then
                 If Len(MyText) > 5 Then
                     MyText = Mid(MyText, 6, Len(MyText) - 5)
                     Call SendBan(MyText)
                     MyText = ""
                 End If
                 Exit Sub
             End If

And add below it:
             ' Editing sign request
             If Mid(MyText, 1, 10) = "/editsign" Then
                 Call SendRequestEditSign
                 MyText = ""
                 Exit Sub
             End If
        End If

Find:
                     If frmMapEditor.optKeyOpen.Value = True Then
                           .Type = TILE_TYPE_KEYOPEN
                           .Data1 = KeyOpenEditorX
                           .Data2 = KeyOpenEditorY
                           .Data3 = 0
                     End If

And add below it:
                     If frmMapEditor.optSign.Value = True Then
                           .Type = TILE_TYPE_SIGN
                           .Data1 = SignNum
                           .Data2 = 0
                           .Data3 = 0
                     End If

And add in modGameLogic:
Public Sub SignEditorInit()
    frmSignEditor.txtSignName.Text = Trim(Sign(EditorIndex).Name)
    frmSignEditor.txtSignLine1.Text = Trim(Sign(EditorIndex).Line1)
    frmSignEditor.txtSignLine2.Text = Trim(Sign(EditorIndex).Line2)
    frmSignEditor.Show vbModal
End Sub

Public Sub SignEditorOk()
    Sign(EditorIndex).Name = frmSignEditor.txtSignName.Text
    Sign(EditorIndex).Line1 = frmSignEditor.txtSignLine1.Text
    Sign(EditorIndex).Line2 = frmSignEditor.txtSignLine2.Text
   
    Call SendSaveSign(EditorIndex)
    InSignEditor = False
    Unload frmSignEditor
End Sub

Public Sub SignEditorCancel()
    InSignEditor = False
    Unload frmSignEditor
End Sub

Go into modGlobals and add:
' Used for map sign number
Public SignNum As Integer

Find:
Public EditorIndex As Long

And add below it:
Public InSignEditor As Boolean

Find:
Public Spell(1 To MAX_SPELLS) As SpellRec

And add below it:
Public Sign(1 To MAX_SIGNS) As SignRec

Go into modHandleData and add:
    ' ::::::::::::::::::::::::
    ' :: Sign editor packet ::
    ' ::::::::::::::::::::::::
    If (LCase(Parse(0)) = "signeditor") Then
        InSignEditor = True
       
        frmIndex.Show
        frmIndex.lstIndex.Clear
       
        ' Add the names
        For i = 1 To MAX_SIGNS
             frmIndex.lstIndex.AddItem i & ": " & Trim(Sign(i).Name)
        Next i
       
        frmIndex.lstIndex.ListIndex = 0
        Exit Sub
    End If
   
    ' ::::::::::::::::::::::::
    ' :: Update sign packet ::
    ' ::::::::::::::::::::::::
    If (LCase(Parse(0)) = "updatesign") Then
        n = Val(Parse(1))
       
        ' Update the spell name
        Sign(n).Name = Trim(Parse(2))
        Exit Sub
    End If
   
    ' ::::::::::::::::::::::
    ' :: Edit sign packet :: <- Used for sign editor admins only
    ' ::::::::::::::::::::::
    If (LCase(Parse(0)) = "editsign") Then
        n = Val(Parse(1))
       
        ' Update the spell
        Sign(n).Name = Trim(Parse(2))
        Sign(n).Line1 = Trim(Parse(3))
        Sign(n).Line2 = Trim(Parse(4))
                          
        ' Initialize the spell editor
        Call SignEditorInit

        Exit Sub
    End If

   ' ::::::::::
   ' :: Sign ::
   ' ::::::::::
   If LCase(Parse(0)) = "sign" Then
       frmMirage.picSign.Visible = True
       'put all the data into the correct area
       frmMirage.lblSignName.Caption = Trim(Parse(2))
       frmMirage.txtSignLine1.Text = Trim(Parse(3))
       frmMirage.txtSignLine2.Text = Trim(Parse(4))
       Exit Sub
   End If

Go into modTypes and add:
Type SignRec
    Name As String * NAME_LENGTH
    Line1 As String * NAME_LENGTH
    Line2 As String * NAME_LENGTH
End Type

Go into your mapeditor pic or form and add a new option button called:
optSign

Double click it and add:
    frmSignChooser.Show vbModal

Go into your frmIndex coding and find:
    If InSpellEditor = True Then
        Call SendData("EDITSPELL" & SEP_CHAR & EditorIndex & SEP_CHAR & END_CHAR)
    End If

And add below it:
    If InSignEditor = True Then
        Call SendData("EDITSIGN" & SEP_CHAR & EditorIndex & SEP_CHAR & END_CHAR)
    End If

Find:
    InSpellEditor = False

And add below it:
    InSignEditor = False

Go into your frmMirage and add a new picture box called:
picSign

Make the visibility 'false'
And add in the picture box one label called:
lblSignName

And add in the picture box two text boxes called:
txtSignLine1

And
txtSignLine2

Make the two text boxes have 'multiline'
And add in the picture box a command button called:
cmdSignClose

Double click the command button and add:
    If picSign.Visible = True Then
        picSign.Visible = False
    End If

Now, make a new form called:
frmSignChooser

Add a new horizontal scroll bar called:
scrlSignNum

Change the min and max value to '1' and '255'
Add a new label called:
lblSignNum

Change the caption to '1'
Add two new command buttons call them:
cmdOk

And
cmdCancel

Go into the coding and add:
Private Sub cmdCancel_Click()
    Unload Me
End Sub

Private Sub cmdOk_Click()
    SignNum = scrlSignNum.Value
    Unload Me
End Sub

Private Sub scrlSignNum_Change()
    lblSignNum.Caption = STR(scrlSignNum.Value)
End Sub

Now, make a new form called:
frmSignEditor

And add three new labels and label them Sign Name, Line1 and Line2.
Add three new text boxes and call them:
txtSignName

And
txtSignLine1

And
txtSignLine2

Make the three text boxes have a maximum value of 20.
Add two new command buttons call them:
cmdOk

And
cmdCancel

Go into the coding and add:
Private Sub cmdCancel_Click()
    Call SignEditorCancel
End Sub

Private Sub cmdOk_Click()
    Call SignEditorOk
End Sub

That should be it, if i have missed anything out, please tell me and i will fix it right away.. :D Enjoy!!



Replies:
Posted By: Sync
Date Posted: 07 February 2006 at 6:40pm
Approved



Posted By: shortybsd
Date Posted: 09 February 2006 at 4:34am

jeez man, this is what happens when you work 20 hours in a day heh ... it works fine, forget what i said regarding form load and etc. this example works fine. For any others looking, when you are logged in as a mapper or greater, type /editsign. I fixed the source on the server so when a mapper or > is logged in and types /admin, it will show the new options :)



Posted By: funkynut
Date Posted: 09 February 2006 at 9:35am
"I put frmSignEditor.Show in the form's load"

What, you tryed loading the form again when its already loading?

Anyway, the Sign array doesnt go as low as zero, thats the problem...


Posted By: shortybsd
Date Posted: 09 February 2006 at 1:33pm
I'm sorry, I put frmSignEditor.Visible = True (since it was set visible=false) in the form's load for frmSignChooser. It was late last night as I was delerious hehe.


Posted By: shortybsd
Date Posted: 11 February 2006 at 2:48pm
Has anyone successfully got this to work? I can create the signs and place them, but when a character walks over it, it does nothing. I even tried this on the new source.


Posted By: Sonire
Date Posted: 11 February 2006 at 11:18pm
Excellent tutorial Dark Echo 

Shortybsd, did you hit enter when you stepped on the sign?

By the way, tomorrow I'm gonna add an optional piece of code to the tutorial. Standing on a sign is a little odd, some I'm gonna arrange the sign to appear when your facing it (one tile away from it) and click on it.


-------------
I grant permission for anyone to alter a tutorial previously posted by me for use in a tutorial submission for MSE, so long as "Originally Coded By Sonire" is credited at the top of the tutorial.


Posted By: shortybsd
Date Posted: 11 February 2006 at 11:34pm
Yes, tried everything. If I am being stupid or blind please correct me, but I didn't see any code for hitting enter or an if statement (if you were on sign and hit enter) for it to update the txtChat RichTextBox


Posted By: Sonire
Date Posted: 12 February 2006 at 8:16am

' Sign
        Dim SignPacket As String
        If Map.Tile(GetPlayerX(MyIndex), GetPlayerY(MyIndex)).Type = TILE_TYPE_SIGN Then
             SignNum = Map.Tile(GetPlayerX(MyIndex), GetPlayerY(MyIndex)).Data1
             SignPacket = "requestsign" & SEP_CHAR & SignNum & SEP_CHAR & END_CHAR
             Call SendData(SignPacket)
       End If


That is the code that initially calls to read a sign. It's been placed in Sub HandleKeypresses, most importantly, it's been insterted into a long list of commands that are active upon hitting enter. If you scroll to the top of the sub, you'll see this code:


' Handle when the player presses the return key
    If (KeyAscii = vbKeyReturn) Then
        ' Broadcast message
        If Mid(MyText, 1, 1) = "'" Then
             ChatText = Mid(MyText, 2, Len(MyText) - 1)
             If Len(Trim(ChatText)) > 0 Then
                 Call BroadcastMsg(ChatText)
             End If
             MyText = ""
             Exit Sub
        End If


If I were you, I'd go back through and check to make sure you added all of your packets in ClientTCP and ServerTCP the right way. If you want me to help you trouble shoot some more, we can take this to PMs, or you can add me on your messenger of choice.


-------------
I grant permission for anyone to alter a tutorial previously posted by me for use in a tutorial submission for MSE, so long as "Originally Coded By Sonire" is credited at the top of the tutorial.


Posted By: tosuxo
Date Posted: 12 February 2006 at 8:22am
I got this to work fine, I even modified this to a big extreme and made my own player house script...

...if people ask very nicely I'll make a copy of the code and make a tut on here for it... either that or i sell it :P


Posted By: shortybsd
Date Posted: 13 February 2006 at 5:58am
i had to replace the picture box over the main screen, i had it residing above the 6 buttons, even though it was set (send to front) and others were sent to back, it didn't make a difference (was hidden the whole entire time) signs works great now that i moved it within picScreen! I modifed and made some new constants for the sign rather than being limited to 20 characters. I wanted to put tutorials of the game in ceratain parts of the map to further explain certain things in great detail. I put this is both, the server and the client:
put this in modConstants
Code:

' New Sign constants
Public Const SIGNNAME_LENGTH = 30
Public Const SIGNMSG_LENGTH = 200


in modTypes I put

Code:

Type SignRec
    Name As String * SIGNNAME_LENGTH
    Line1 As String * SIGNMSG_LENGTH
    Line2 As String * SIGNMSG_LENGTH
End Type

on the client I simply edited frmSignEditor and changed the maxlength values to what I have in my constants


Posted By: Renegade
Date Posted: 13 February 2006 at 9:23am
what bit wont work?



Print Page | Close Window

Bulletin Board Software by Web Wiz Forums version 8.01 - http://www.webwizforums.com
Copyright ©2001-2006 Web Wiz Guide - http://www.webwizguide.info