vbGore Free Online RPG Engine

Revolutionizing Visual Basic ORPG Development
It is currently Tue May 21, 2013 9:04 am

All times are UTC - 8 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: In Game Character Editor
PostPosted: Sun Oct 12, 2008 9:05 am 
Bytewise Operator

Joined: Wed Oct 08, 2008 8:09 am
Posts: 148
After much work, I managed to make an in game editor to change the character's appearance (head, body, hair). What happens is that the changes affect your "default" body and hair (i didn't bother making a default head state). Reasoning behind this is that the default hair and body is your unclothed versions. Hair, despite the name, can work as a helmet or other head gear layed over the head graphic, and the same goes for the body with armor and clothes. Now, there are a ton of steps to doing this, and I might easily miss a few. If there are any problems, just message them and I'll post what I missed. Btw, I also made it so that you can specify which heads, hair, and bodies the user can select from.


First thing to do is download the GRH files and put them into your GRH directory.

Now open the GrhRaw.txt file and add this to the bottom:
Code:
'**** Appearance Change Screen ****
Grh44=1-145-0-0-56-80

'**** Head Icon ****
Grh45=1-146-0-0-16-16


Now open the BlueWave.ini (or appropriate skin file and add this:
Code:
[COSMETIC]
ScreenX=372
ScreenY=255
ScreenWidth=56
ScreenHeight=80

Arrow1X=0
Arrow1Y=16
Arrow1Width=9
Arrow1Height=9

Arrow2X=0
Arrow2Y=33
Arrow2Width=9
Arrow2Height=9

Arrow3X=0
Arrow3Y=50
Arrow3Width=9
Arrow3Height=9

Arrow4X=47
Arrow4Y=16
Arrow4Width=9
Arrow4Height=9

Arrow5X=47
Arrow5Y=33
Arrow5Width=9
Arrow5Height=9

Arrow6X=47
Arrow6Y=50
Arrow6Width=9
Arrow6Height=9

SaveX=15
SaveY=66
SaveWidth=25
SaveHeight=10

Grh=44


... and in the [StatWindow] block of code, add this:
Code:
FaceGrh=45
FaceX=7
FaceY=218
FaceWidth=16
FaceHeight=16
FaceLblX=25
FaceLblY=218



Now open the bluewave.dat file and add this:
Code:

[COSMETIC]
ScreenX=372
ScreenY=255


you can save and close those files if you haven't already. Now run the ToolGrhDatMaker.exe.


Ok, onto the client side. (doing this in no particular order... :rofl: )
Go to Tile Engine.bas and find "'Important: Windows are ordered by priority, where 1 = highest!" and add this to the block of code:
Code:
Public Const CosmeticWindow As Byte = 15

Change 15 to whatever the highest number is there and update NumGameWindows to reflect that.

Now locate "Public Type GameWindow". Above that add:
Code:
Public Type CosmeticWindow
    Screen As Rectangle
    Arrow1 As Rectangle 'Left Arrow (Hair Select)
    Arrow2 As Rectangle 'Left Arrow (Head Select)
    Arrow3 As Rectangle 'Left Arrow (Body Select)
    Arrow4 As Rectangle 'Right Arrow (Hair Select)
    Arrow5 As Rectangle 'Left Arrow (Head Select)
    Arrow6 As Rectangle 'Right Arrow (Body Select)
    Save As Rectangle   'Saves changes and updates other clients
    Hair As Integer     'Hair To Display
    Head As Integer     'Head To Display
    Body As Integer     'Body To Display
    HairList(1 To 2) As Integer  'List Of Hair
    HeadList(1 To 2) As Integer  'List of Heads
    BodyList(1 To 1) As Integer  'List of Bodies
    SkinGrh As Grh
End Type


for HairList, HeadList, BodyLilst, adjust the length of these arrays to however many heads, hair, and bodies you wish to let the user select from.

Ok, locate "Public Type GameWindow" again. Inside that block of code, add this:
Code:
    Cosmetic As CosmeticWindow


Now locate the "Private Type StatWindow" block of code. add this to it:
Code:

    Face As Rectangle
    FaceLbl As Rectangle
    FaceGrh As Grh





Now locate Engine_Init_Gui. Under this block of code:
Code:
    s = DataPath & "Skins\" & CurrentSkin & ".ini"
    t = DataPath & "Skins\" & CurrentSkin & ".dat"


add this:
Code:
    'Load Cosmetic Menu
    With GameWindow.Cosmetic
        .Screen.X = Val(Var_Get(t, "COSMETIC", "ScreenX"))
        .Screen.Y = Val(Var_Get(t, "COSMETIC", "ScreenY"))
        .Screen.Width = Val(Var_Get(s, "COSMETIC", "ScreenWidth"))
        .Screen.Height = Val(Var_Get(s, "COSMETIC", "ScreenHeight"))
        Engine_Init_Grh .SkinGrh, Val(Var_Get(s, "COSMETIC", "Grh"))
       
        .Body = 1
        .Head = 1
        .Hair = 1
       
        'Hair/Head/Body Lists
        'List of Hair allowed to be chosen
        .HairList(1) = 1
        .HairList(2) = 2
       
        'List of Heads allowed to be chosen
        .HeadList(1) = 1
        .HeadList(2) = 2
       
        'List of Bodies allowed to be chosen
        .BodyList(1) = 1
    End With
    With GameWindow.Cosmetic.Arrow1
        .X = Val(Var_Get(s, "COSMETIC", "Arrow1X"))
        .Y = Val(Var_Get(s, "COSMETIC", "Arrow1Y"))
        .Width = Val(Var_Get(s, "COSMETIC", "Arrow1Width"))
        .Height = Val(Var_Get(s, "COSMETIC", "Arrow1Height"))
    End With
    With GameWindow.Cosmetic.Arrow2
        .X = Val(Var_Get(s, "COSMETIC", "Arrow2X"))
        .Y = Val(Var_Get(s, "COSMETIC", "Arrow2Y"))
        .Width = Val(Var_Get(s, "COSMETIC", "Arrow2Width"))
        .Height = Val(Var_Get(s, "COSMETIC", "Arrow2Height"))
    End With
    With GameWindow.Cosmetic.Arrow3
        .X = Val(Var_Get(s, "COSMETIC", "Arrow3X"))
        .Y = Val(Var_Get(s, "COSMETIC", "Arrow3Y"))
        .Width = Val(Var_Get(s, "COSMETIC", "Arrow3Width"))
        .Height = Val(Var_Get(s, "COSMETIC", "Arrow3Height"))
    End With
    With GameWindow.Cosmetic.Arrow4
        .X = Val(Var_Get(s, "COSMETIC", "Arrow4X"))
        .Y = Val(Var_Get(s, "COSMETIC", "Arrow4Y"))
        .Width = Val(Var_Get(s, "COSMETIC", "Arrow4Width"))
        .Height = Val(Var_Get(s, "COSMETIC", "Arrow4Height"))
    End With
    With GameWindow.Cosmetic.Arrow5
        .X = Val(Var_Get(s, "COSMETIC", "Arrow5X"))
        .Y = Val(Var_Get(s, "COSMETIC", "Arrow5Y"))
        .Width = Val(Var_Get(s, "COSMETIC", "Arrow5Width"))
        .Height = Val(Var_Get(s, "COSMETIC", "Arrow5Height"))
    End With
    With GameWindow.Cosmetic.Arrow6
        .X = Val(Var_Get(s, "COSMETIC", "Arrow6X"))
        .Y = Val(Var_Get(s, "COSMETIC", "Arrow6Y"))
        .Width = Val(Var_Get(s, "COSMETIC", "Arrow6Width"))
        .Height = Val(Var_Get(s, "COSMETIC", "Arrow6Height"))
    End With
    With GameWindow.Cosmetic.Save
        .X = Val(Var_Get(s, "COSMETIC", "SaveX"))
        .Y = Val(Var_Get(s, "COSMETIC", "SaveY"))
        .Width = Val(Var_Get(s, "COSMETIC", "SaveWidth"))
        .Height = Val(Var_Get(s, "COSMETIC", "SaveHeight"))
    End With


and then locate "'Load stats window" and under that locate
Code:
Engine_Init_Grh .AddGrh, Val(Var_Get(s, "STATWINDOW", "AddGrh"))


above it add this:
Code:
        .Face.X = Val(Var_Get(s, "STATWINDOW", "FaceX"))
        .Face.Y = Val(Var_Get(s, "STATWINDOW", "FaceY"))
        .Face.Width = Val(Var_Get(s, "STATWINDOW", "FaceWidth"))
        .Face.Height = Val(Var_Get(s, "STATWINDOW", "FaceHeight"))
        .FaceLbl.X = Val(Var_Get(s, "STATWINDOW", "FaceLblX"))
        .FaceLbl.Y = Val(Var_Get(s, "STATWINDOW", "FaceLblY"))
        Engine_Init_Grh .FaceGrh, Val(Var_Get(s, "STATWINDOW", "FaceGrh"))



Now locate the Engine_Render_Gui_Window function. In there locate "Case TradeWindow" and add this code above it:
Code:

        Case CosmeticWindow
            With GameWindow.Cosmetic
                ' Show the Cosmetic Window
                Engine_Render_Grh .SkinGrh, .Screen.X, .Screen.Y, 0, 1, True, GUIColorValue, GUIColorValue, GUIColorValue, GUIColorValue
            End With


now locate in that same function "Case StatWindow". After this line:
Code:
Engine_Render_Text Font_Default, "Dmg: " & BaseStats(SID.MinHIT) & "+" & ModStats(SID.MinHIT) - BaseStats(SID.MinHIT) & " ~ " & BaseStats(SID.MaxHIT) & "+" & ModStats(SID.MaxHIT) - BaseStats(SID.MaxHIT) & " (" & ModStats(SID.MinHIT) & " ~ " & ModStats(SID.MaxHIT) & ")", .Screen.X + .Dmg.X, .Screen.Y + .Dmg.Y, -1


... add this:
Code:
                Engine_Render_Grh .FaceGrh, .Screen.X + .Face.X, .Screen.Y + .Face.Y, 0, 1
                Engine_Render_Text Font_Default, "Change Appearance", .Screen.X + .FaceLbl.X, .Screen.Y + .FaceLbl.Y, -1



Now Open Input.Bas.
Go to the Input_Keys_Down function. Locate 'Escape Was Pressed and change that block of code to this:
Code:
    'Escape was pressed
    If KeyCode = vbKeyEscape Then
        If LastClickedWindow = 0 Then
            If ShowGameWindow(MenuWindow) = 0 Then
                If EnterText Then
                    EnterTextBuffer = vbNullString
                    EnterTextBufferWidth = 10
                    UpdateShownTextBuffer
                    EnterText = False
                End If
            End If
        Else
            If Not LastClickedWindow = CosmeticWindow Then
                ShowGameWindow(LastClickedWindow) = 0
                LastClickedWindow = 0
            End If
            Exit Sub
        End If
    End If

this just prevents the user from closing the appearance editor with escape. This step is optional, but I recommend it.

Locate Input_Mouse_LeftClick_Window and find "Select Case WindowIndex" Under that add this:
Code:
      Case CosmeticWindow
            If ShowGameWindow(CosmeticWindow) Then
                With GameWindow.Cosmetic
                    If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X, .Screen.Y, .Screen.Width, .Screen.Height) Then
                        Input_Mouse_LeftClick_Window = 1
                        LastClickedWindow = CosmeticWindow
                        SelGameWindow = CosmeticWindow
                       
                        'Hair Left Arrow button
                        If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X + .Arrow1.X, .Screen.Y + .Arrow1.Y, .Arrow1.Width, .Arrow1.Height) Then
                            .Hair = .Hair - 1
                            If .Hair < 1 Then
                                .Hair = UBound(.HairList)
                            End If
                           
                            CharList(UserCharIndex).Hair = HairData(.HairList(.Hair))
                           
                            Exit Function
                        End If
                        'Hair Right Arrow button
                        If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X + .Arrow4.X, .Screen.Y + .Arrow4.Y, .Arrow4.Width, .Arrow4.Height) Then
                            .Hair = .Hair + 1
                            If .Hair > UBound(.HairList) Then
                                .Hair = 1
                            End If
                           
                            CharList(UserCharIndex).Hair = HairData(.HairList(.Hair))
                           
                            Exit Function
                        End If
                       
                        'Head Left Arrow button
                        If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X + .Arrow2.X, .Screen.Y + .Arrow2.Y, .Arrow2.Width, .Arrow2.Height) Then
                            .Head = .Head - 1
                            If .Head < 1 Then
                                .Head = UBound(.HeadList)
                            End If
                           
                            CharList(UserCharIndex).Head = HeadData(.HeadList(.Head))
                           
                            Exit Function
                        End If
                        'Head Right Arrow button
                        If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X + .Arrow5.X, .Screen.Y + .Arrow5.Y, .Arrow5.Width, .Arrow5.Height) Then
                            .Head = .Head + 1
                            If .Head > UBound(.HeadList) Then
                                .Head = 1
                            End If
                           
                            CharList(UserCharIndex).Head = HeadData(.HeadList(.Head))
                           
                            Exit Function
                        End If
                       
                        'Body Left Arrow button
                        If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X + .Arrow3.X, .Screen.Y + .Arrow3.Y, .Arrow3.Width, .Arrow3.Height) Then
                            .Body = .Body - 1
                            If .Body < 1 Then
                                .Body = UBound(.BodyList)
                            End If
                           
                            CharList(UserCharIndex).Body = BodyData(.BodyList(.Body))
                           
                            Exit Function
                        End If
                        'Body Right Arrow button
                        If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X + .Arrow6.X, .Screen.Y + .Arrow6.Y, .Arrow6.Width, .Arrow6.Height) Then
                            .Body = .Body + 1
                            If .Body > UBound(.BodyList) Then
                                .Body = 1
                            End If
                           
                            CharList(UserCharIndex).Body = BodyData(.BodyList(.Body))
                           
                            Exit Function
                        End If
                       
                        'Save Button
                        If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X + .Save.X, .Screen.Y + .Save.Y, .Save.Width, .Save.Height) Then
                            'send update to server (update clients and database)
                            sndBuf.Allocate 7
                            sndBuf.Put_Byte DataCode.Server_ChangeChar
                            sndBuf.Put_Integer .Hair
                            sndBuf.Put_Integer .Head
                            sndBuf.Put_Integer .Body
                           
                            ShowGameWindow(LastClickedWindow) = 0
                            LastClickedWindow = 0
                            Exit Function
                        End If
                    End If
                End With
            End If


Still inside this function, locate "Case StatWindow". Under that find the block of code for "'Raise mag" and add this:
Code:

                        'Change Appearance
                        If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X + .Face.X, .Screen.Y + .Face.Y, .Face.Width, .Face.Height) Then
                            HideShowWindow (CosmeticWindow)
                        End If



... Ok, I believe that's it for the client. There really is a lot to keep track of, so I'm sorry if I forgot something. Let's move onto the Server script:
First thing to do is go to your frmMain Code. go to the function "OnDataArrival" and under this line of code:
Code:
Case .User_Use: Data_User_Use rBuf, Index


... add this:
Code:
Case .Server_ChangeChar: Data_UpdateAppearance rBuf, Index


Now open your Declares.bas file. Locate this line of code:
Code:
Type Char   'Holds data for a user or NPC character


... and in there add this:
Code:
    DefHair As Integer          'Default Hair index
    DefBody As Integer          'Default Body index



Open the Users.bas file. Go to the User_RemoveInvItem function and locate "Case OBJTYPE_ARMOR". In that line of code locate "'Set the paper-dolling'. Change the line of code under that too:
Code:
                'Set the paper-dolling
                User_ChangeChar ToMap, UserIndex, UserIndex, UserList(UserIndex).Char.DefBody, , , UserList(UserIndex).Char.DefHair


Now go to the FileIO.bas file. Locate the "Load_User" function. Now locate this line of code:
Code:
UserList(UserIndex).Char.Body = Val(!char_body)

and under that put:
Code:
        UserList(UserIndex).Char.DefHair = Val(!char_def_hair)
        UserList(UserIndex).Char.DefBody = Val(!char_def_body)


Now locate the "Save_User" function. Locate this line of code:
Code:
DB_RS!char_body = .Char.Body

and under it put this:
Code:
        DB_RS!char_def_body = .Char.DefBody
        DB_RS!char_def_hair = .Char.DefHair



Now go to the TCP.bas file

add this Sub:
Code:
Sub Data_UpdateAppearance(ByRef rBuf As DataBuffer, ByVal UserIndex As Integer)
    Dim Hair As Integer
    Dim Head As Integer
    Dim Body As Integer
    Dim ChangeBody As Boolean
    Dim DisplayHair As Integer
    Dim i As Integer
   
    'Get New Appearance
    Hair = rBuf.Get_Integer
    Head = rBuf.Get_Integer
    Body = rBuf.Get_Integer
   
    'check if user is wearing armor (So that armor refreshes in place of user's new default body)
    ChangeBody = True
    For i = 1 To MAX_INVENTORY_SLOTS Step 1
        If UserList(UserIndex).Object(i).Equipped Then
            If ObjData.SpriteBody(UserList(UserIndex).Object(i).ObjIndex) > 0 Then
                ChangeBody = False
               
                Exit For
            End If
        End If
    Next
   
   
    'Update Clients on same map
    If (ChangeBody) Then
        User_ChangeChar ToMap, UserIndex, UserIndex, Body, Head, , Hair 'change default body
    Else
        UserList(UserIndex).Char.Body = -1 ' Trick server into thinking body did change so it refreshes user's body
       
        ' Check if equiped item replaces hair
        DisplayHair = Hair 'Use new hair
        If ObjData.SpriteHair(UserList(UserIndex).Object(i).ObjIndex) > 0 Then
            DisplayHair = ObjData.SpriteHair(UserList(UserIndex).Object(i).ObjIndex) 'Use Equiped Item
            UserList(UserIndex).Char.Hair = -1 ' Trick server into thinking hair did change so it refreshes user's hair
        End If
           
        User_ChangeChar ToMap, UserIndex, UserIndex, ObjData.SpriteBody(UserList(UserIndex).Object(i).ObjIndex), Head, , DisplayHair
    End If
   
    'Update Appearance
    UserList(UserIndex).Char.Head = Head
    UserList(UserIndex).Char.DefHair = Hair
    UserList(UserIndex).Char.DefBody = Body
   
    ' Save User
    Save_User UserList(UserIndex), UserIndex
End Sub


Now locate the "User_ConnectNew" function and locate this line:
Code:
UserList(UserIndex).Char.Body = Body

and under it put this:
Code:
    UserList(UserIndex).Char.DefBody = Body
    UserList(UserIndex).Char.DefHair = 1



*sigh* ok, one more thing. to activate, go to your stats window. You'll see a face icon. Click on it and that will open the editor. The editor appears around the user and lets you alter the appearance with the click of a button


I lied, there's still one more thing to do! Go to your database and find your users table. Add 2 columns: "char_def_body" and "char_def_hair". These will have the same attributes as "char_hair" and "char_body".


Last edited by GoreMania on Sun Oct 12, 2008 9:54 am, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: In Game Character Editor
PostPosted: Sun Oct 12, 2008 9:07 am 
Bytewise Operator

Joined: Thu Jul 24, 2008 12:44 pm
Posts: 132
Wow thats very nice GoreMania!
nice going, with making all these awesome tutorials!


Last edited by Tharsten on Sun Oct 12, 2008 9:10 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: In Game Character Editor
PostPosted: Sun Oct 12, 2008 9:08 am 
=^.^= Kitty =^.^=

Joined: Mon Jan 28, 2008 6:03 pm
Posts: 1545
Location: Behind you...
Holy crap, seems like your doing a lot with this!

Nice work! Keep it up dude!


Top
 Profile  
 
 Post subject: Re: In Game Character Editor
PostPosted: Sun Oct 12, 2008 9:16 am 
Bytewise Operator

Joined: Wed Oct 08, 2008 8:09 am
Posts: 148
:D I appreciate the support! Just wait, I have in mind to make a Mount tutorial and a housing tutorial (gulp).

Here's the theory I plan on applying. Maybe someone has input on this:

For the housing:
* Make a simile to the Map Editor. Users login, and retrieve their home from the database. Then they can edit and save to the database. They will only have one home too.
- remove some of the Editor's capabilities so it isn't abused. No item, NPC, quest, or anything that could be used to unfairly get money, items and such.

For Mount:
* Make an armor set that looks like a horse (or some mount). You 'equip' this mount and you 'appear' to be riding it. Then you can apply whatever bonuses the mount may give you (like you would with any armor/weapon).

Yeah, sounds cheesy, but it works.


Top
 Profile  
 
 Post subject: Re: In Game Character Editor
PostPosted: Mon Oct 13, 2008 6:12 am 
Slave to the BB

Joined: Tue Jul 31, 2007 8:45 am
Posts: 3273
Location: United Kingdom
Woah, awesome work. Thanks for posting this all up, and sharing it.


Top
 Profile  
 
 Post subject: Re: In Game Character Editor
PostPosted: Mon Oct 13, 2008 7:44 am 
Bytewise Operator

Joined: Thu Jul 24, 2008 12:44 pm
Posts: 132
I have put all the tutorials of GoreMania on the wiki :)

http://www.vbgore.com/Category:Custom_Features


Top
 Profile  
 
 Post subject: Re: In Game Character Editor
PostPosted: Mon Oct 13, 2008 7:46 am 
Bytewise Operator

Joined: Wed Oct 08, 2008 8:09 am
Posts: 148
Tharsten wrote:
I have put all the tutorials of GoreMania on the wiki :)

http://www.vbgore.com/Category:Custom_Features


Thanks a bunch Tharsten! I appreciate it


Top
 Profile  
 
 Post subject: Re: In Game Character Editor
PostPosted: Fri Oct 17, 2008 4:49 pm 
=^.^= Kitty =^.^=

Joined: Tue Jun 03, 2008 11:01 pm
Posts: 963
Location: In Koredai
GoreMania, you're amazing.


Top
 Profile  
 
 Post subject: Re: In Game Character Editor
PostPosted: Fri Oct 17, 2008 7:00 pm 
Bytewise Operator

Joined: Wed Oct 08, 2008 8:09 am
Posts: 148
8) You know it :lol: thanks :) Btw, there's a minor update in the tutorial (in the vbgore custom scripts page) to allow for the selection of no hair.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 8 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group