DJMaxus Posted December 22, 2011 Author Share Posted December 22, 2011 This is a tutorial for Crystalshire Developer's Edition. It will show you how to add basic character customization into your game upon selecting a class. This tutorial will go nicely with this one: [[CS:DE] Paperdoll & Gender Based Paperdoll](http://www.touchofdeathforums.com/smf/index.php/topic,76976.0.html) This may be a long tutorial for some._**How It Works:**_This will allow you to choose the Gender and Hair of your character when you are creating them. After you have selected a class, you are able to cycle between hair and gender options for your character using buttons. Hair is a separate declaration and will appear independent from the sprite, it can be changed throughout the game. This is just a simple customization you could refer to so that you can add extra customization options if you wish. Please see attachments for the buttons you'll need to use this tutorial. To fully utilize this tutorial, you should have a set of base characters for use with your project, if anything, you can just extract the gender part out of this tutorial and forget about the hair part._**Screenshots:**_>! ![](http://img543.imageshack.us/img543/8045/hairone.png)>! ![](http://img851.imageshack.us/img851/5172/hare2.png)>! ![](http://img14.imageshack.us/img14/7545/hayaire.png)_**The Code:**_==============**Server Side**==============First let's add the "Hair" declaration to the PlayerRecIn **modTypes**Find : **Private Type PlayerRec**Find:```Level As Byte```Underneath it Add:```Hair As Long```In **modConstants**Change **MAX_BUTTONS** Value to equal 39 instead of 35In **modPlayer**We're going to add a function and sub that will return the value of and set the hair, could be used for other source edits in the future.Find: **Function GetPlayerLevel**Above that entire function, add this:```Function GetPlayerHair(ByVal index As Long) As Long If index <= 0 Or index > MAX_PLAYERS Then Exit Function GetPlayerHair = Player(index).HairEnd FunctionSub SetPlayerHair(ByVal index As Long, ByVal Hair As Long) If index <= 0 Or index > MAX_PLAYERS Then Exit Sub Player(index).Hair = HairEnd Sub```In **modDatabase**Find the **AddChar** SubWe're going to modify our AddChar sub so it can know which hair will be sent from the client, look for this on the same line as the name of the sub:```ByVal Sprite As Long```Directly after it on the same line, we're going to add this:```, ByVal Hair As Long```That whole line should look like this:```Sub AddChar(ByVal index As Long, ByVal Name As String, ByVal Sex As Byte, ByVal ClassNum As Long, ByVal Sprite As Long, ByVal Hair As Long)```This will set the hair for the player on the server so it can be saved, in the same sub find this:```Player(index).Level = 1```Underneath it, add this:```Player(index).Hair = Hair```The next two additions we'll make are so that the server saves the hair value.In the **SavePlayer** sub,Find:```PutVar filename, "ACCOUNT", "Level", Val(Player(index).Level)```Underneath it add this:```PutVar filename, "ACCOUNT", "Hair", Val(Player(index).Hair)```In the **LoadPlayer** sub,Find:```Player(index).Level = Val(GetVar(filename, "ACCOUNT", "Level"))```Underneath it add this:```Player(index).Hair = Val(GetVar(filename, "ACCOUNT", "Hair"))```Now we handle the sub that actually receives player data from the client. We need to tell it to read the hair value.In **modHandleData**Find the **HandleAddChar** sub.Find:```Dim Sprite As Long```Underneath it add this:```Dim Hair As Long```Find:```Sprite = Buffer.ReadLong```Underneath it add this:```Hair = Buffer.ReadLong```Now we tell the AddChar sub to include hair as wellFind:```Call AddChar(index, Name, Sex, Class, Sprite)```Replace it with:```Call AddChar(index, Name, Sex, Class, Sprite, Hair)```In **modServerTCP**Find the **PlayerData** functionHere, were going to send our saved hair value back to the client so it can load it every time.Find:```Buffer.WriteLong GetPlayerLevel(index)```Underneath it add this:```Buffer.WriteLong GetPlayerHair(index)```That's it for server side! On to the client.==============**Client Side**==============Doing the same thing as the server here…In **modTypes**Find : **Private Type PlayerRec**Find:```Level As Byte```Underneath it Add:```Hair As Long```In **modClientTCP**Here we'll modify our SendAddChar to include a hair value to send to the server.Replace the entire **SendAddChar** sub with this:```Public Sub SendAddChar(ByVal name As String, ByVal Sex As Long, ByVal ClassNum As Long, ByVal Sprite As Long, ByVal Hair As Long)Dim Buffer As clsBuffer ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler Set Buffer = New clsBuffer Buffer.WriteLong CAddChar Buffer.WriteString name Buffer.WriteLong Sex Buffer.WriteLong ClassNum Buffer.WriteLong Sprite Buffer.WriteLong Hair SendData Buffer.ToArray() Set Buffer = Nothing ' Error handler Exit Suberrorhandler: HandleError "SendAddChar", "modClientTCP", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit SubEnd Sub```In **modDatabase**Now we'll add two subs that return or set the hair value.Add this to the bottom:```Function GetPlayerHair(ByVal index As Long) As Long ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If index > MAX_PLAYERS Then Exit Function GetPlayerHair = Player(index).Hair ' Error handler Exit Functionerrorhandler: HandleError "GetPlayerSprite", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit FunctionEnd FunctionSub SetPlayerHair(ByVal index As Long, ByVal Hair As Long) ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If index > MAX_PLAYERS Then Exit Sub Player(index).Hair = Hair ' Error handler Exit Suberrorhandler: HandleError "SetPlayerSprite", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit SubEnd Sub```In **modGlobals**Adding in declarations that hold our gender and hair constants, can't remember if the "newCharSex" already exists or not, if it does, ignore it and don't add it.Find:```' New charPublic newCharSprite As LongPublic newCharClass As Long```Underneath it add this:```Public newCharSex As LongPublic newCharHair As Long```In **modGeneral**Find the **MenuState** subWe send our hair constant to the server with our modified SendAddChar sub. Also, we tell it to select the gender we've picked at character creation.Find:```Call SendAddChar(sChar, SEX_MALE, newCharClass, newCharSprite)```And Replace it with:```Call SendAddChar(sChar, newCharSex, newCharClass, newCharSprite, newCharHair)```In **modHandleData**Find the **HandlePlayerData** sub,Here we receive the saved hair constant from the server.Find:```Call SetPlayerLevel(i, Buffer.ReadLong)```Underneath it, add this:```Call SetPlayerHair(i, Buffer.ReadLong)```Add this to the bottom of the entire modGeneral module:```Public Sub ChangeGender() If newCharSex = SEX_MALE Then newCharSex = SEX_FEMALE Else newCharSex = SEX_MALE End IfEnd Sub```Now we add the graphical functions of hair.In **modDirectX8**Find:```Public Tex_Fader As Long```Underneath it add:```' HairPublic Tex_Hair() As Long```Find:```Public Count_Fog As Long```Underneath it add this:```Public Count_Hair As Long```Find:```Public Const Path_Fog As String = "\data files\graphics\fog\"```Underneath it add:```Public Const Path_Hair As String = "\data files\graphics\characters\hair\"```Find:```' Surfaces Count_Surface = 1 Do While FileExist(App.Path & Path_Surface & Count_Surface & ".png") ReDim Preserve Tex_Surface(0 To Count_Surface) Tex_Surface(Count_Surface).Path = App.Path & Path_Surface & Count_Surface & ".png" Count_Surface = Count_Surface + 1 Loop Count_Surface = Count_Surface - 1```Underneath it add this:```' Hair Textures Count_Hair = 1 Do While FileExist(App.Path & Path_Hair & Count_Hair & ".png") ReDim Preserve Tex_Hair(0 To Count_Hair) Tex_Hair(Count_Hair) = SetTexturePath(App.Path & Path_Hair & Count_Hair & ".png") Count_Hair = Count_Hair + 1 Loop Count_Hair = Count_Hair - 1```Find your **DrawPlayer** subFind:```RenderTexture Tex_Char(Sprite), ConvertMapX(x), ConvertMapY(y), rec.left, rec.top, rec.Width, rec.height, rec.Width, rec.height```Underneath it add this:```DrawHair x, y, GetPlayerHair(index), Anim, spritetop```Underneath the entire **DrawPlayer** sub, add this:```Public Sub DrawHair(ByVal x2 As Long, ByVal y2 As Long, ByVal Hair As Long, ByVal Anim As Long, ByVal spritetop As Long)Dim rec As GeomRec If Hair < 1 Or Hair > Count_Hair Then Exit Sub With rec .top = spritetop * (D3DT_TEXTURE(Tex_Hair(Hair)).height / 4) .height = (D3DT_TEXTURE(Tex_Hair(Hair)).height / 4) .left = Anim * (D3DT_TEXTURE(Tex_Hair(Hair)).Width / 4) .Width = (D3DT_TEXTURE(Tex_Hair(Hair)).Width / 4) End With ' Clip to screen If y2 < 0 Then With rec .top = .top - y2 End With y2 = 0 End If If x2 < 0 Then With rec .left = .left - x2 End With x2 = 0 End If RenderTexture Tex_Hair(Hair), ConvertMapX(x2), ConvertMapY(y2), rec.left, rec.top, rec.Width, rec.height, rec.Width, rec.heightEnd Sub```Up next, we will be moving some things around in the New Character screen, as well as adding in our buttons and defining what they do.Find your **DrawNewChar** subFind:```' sprite preview sprite = Class(newCharClass).MaleSprite(newCharSprite) 'EngineRenderRectangle Tex_Char(sprite), x + 235, y + 123, 32, 0, 32, 32, 32, 32, 32, 32 RenderTexture Tex_Char(sprite), x + 235, y + 123, 32, 0, 32, 32, 32, 32```Replace it with this:```RenderChar RenderTexture Tex_Hair(newCharHair), x + 265, y + 120, 32, 0, 32, 32, 32, 32```This sub will render the correct sprite based on gender on character creation. Above the entire **DrawNewChar** sub, add this:```Public Sub RenderChar()Dim Sprite As LongDim x As LongDim y As Long x = GUIWindow(GUI_MAINMENU).x y = GUIWindow(GUI_MAINMENU).y If newCharSex = SEX_MALE Then Sprite = Class(newCharClass).MaleSprite(newCharSprite) Else Sprite = Class(newCharClass).FemaleSprite(newCharSprite) End If RenderTexture Tex_Char(Sprite), x + 265, y + 120, 32, 0, 32, 32, 32, 32End Sub```Time to draw our four buttons. Back in the **DrawNewChar** sub, were going to **add this just above the last "End If"**```' position For buttonnum = 36 To 39 x = GUIWindow(GUI_MAINMENU).x + Buttons(buttonnum).x y = GUIWindow(GUI_MAINMENU).y + Buttons(buttonnum).y Width = Buttons(buttonnum).Width height = Buttons(buttonnum).height ' render accept button If Buttons(buttonnum).state = 2 Then ' we're clicked boyo 'EngineRenderRectangle Tex_Buttons_c(Buttons(buttonnum).PicNum), x, y, 0, 0, width, height, width, height, width, height RenderTexture Tex_Buttons(Buttons(buttonnum).PicNum), x, y, 0, 0, Width, height, Width, height ElseIf (GlobalX >= x And GlobalX <= x + Buttons(buttonnum).Width) And (GlobalY >= y And GlobalY <= y + Buttons(buttonnum).height) Then ' we're hoverin' 'EngineRenderRectangle Tex_Buttons_h(Buttons(buttonnum).PicNum), x, y, 0, 0, width, height, width, height, width, height RenderTexture Tex_Buttons(Buttons(buttonnum).PicNum), x, y, 0, 0, Width, height, Width, height ' play sound if needed If Not lastButtonSound = buttonnum Then Play_Sound Sound_ButtonHover lastButtonSound = buttonnum End If Else ' we're normal 'EngineRenderRectangle Tex_Buttons(Buttons(buttonnum).PicNum), x, y, 0, 0, width, height, width, height, width, height RenderTexture Tex_Buttons(Buttons(buttonnum).PicNum), x, y, 0, 0, Width, height, Width, height ' reset sound if needed If lastButtonSound = buttonnum Then lastButtonSound = 0 End If Next```In **modGeneral**Find the **InitialiseGUI** subThis is where we defined our buttons, their sizes and position. At the very bottom of the sub but above "End Sub", were going to add in our new buttons:``` ' main - Select Gender Left With Buttons(36) .state = 0 'normal .x = 175 .y = 114 .Width = 19 .height = 19 .visible = True .PicNum = 23 End With ' main - Select Gender Right With Buttons(37) .state = 0 'normal .x = 211 .y = 114 .Width = 19 .height = 19 .visible = True .PicNum = 24 End With ' main - Select Hair Left With Buttons(38) .state = 0 'normal .x = 175 .y = 141 .Width = 19 .height = 19 .visible = True .PicNum = 23 End With ' main - Select Gender Right With Buttons(39) .state = 0 'normal .x = 211 .y = 141 .Width = 19 .height = 19 .visible = True .PicNum = 24 End With```In **modInput**Find the **MainMenu_MouseDown** subThis will check if we're clicking a button.Add this at the bottom before "End Sub"```For i = 36 To 39 x = GUIWindow(GUI_MAINMENU).x + Buttons(i).x y = GUIWindow(GUI_MAINMENU).y + Buttons(i).y ' check if we're on the button If (GlobalX >= x And GlobalX <= x + Buttons(i).Width) And (GlobalY >= y And GlobalY <= y + Buttons(i).height) Then Buttons(i).state = 2 ' clicked End If Next```Find the **MainMenu_MouseUp** subThis will check if we clicked a button and what the button will do once we've clicked it.Find:```' reset buttons resetClickedButtons```Above it, add this:``` ' Character Customization Buttons ' find out which button we're clicking For i = 36 To 39 x = GUIWindow(GUI_MAINMENU).x + Buttons(i).x y = GUIWindow(GUI_MAINMENU).y + Buttons(i).y ' check if we're on the button If (GlobalX >= x And GlobalX <= x + Buttons(i).Width) And (GlobalY >= y And GlobalY <= y + Buttons(i).height) Then If Buttons(i).state = 2 Then ' do stuffs Select Case i Case 36 If curMenu = MENU_NEWCHAR Then ' do eet ChangeGender RenderChar End If Case 37 If curMenu = MENU_NEWCHAR Then ' do eet ChangeGender RenderChar End If Case 38 If curMenu = MENU_NEWCHAR Then ' Select Hair newCharHair = newCharHair - 1 If newCharHair < 0 Then newCharHair = Count_Hair End If End If Case 39 If curMenu = MENU_NEWCHAR Then ' Cycle Hair newCharHair = newCharHair + 1 If newCharHair > Count_Hair Then newCharHair = 1 End If End If End Select ' play sound Play_Sound Sound_ButtonClick End If End If Next```_**Non-Code Work:**_1\. In your graphics folder, create a new folder in your "characters" folder called "hair"2\. Add 26.png to your /graphics/gui/ folder and replace the old one3\. Add 23.png and 24.png to your graphics/gui/buttons/ folder.I think that's it but I'm not sure. I have a bad habit of adding in things then forgetting what all I did to get it working, if you have trouble with the tutorial, have any questions, or find I left something out, let me know. Congrats, you now have a basic character customization screen. I hope this helps you further your project, and I hope its understandable enough for you to add your own customization options. I'll try to do my tutorials with a bit more explanation in the future. Link to comment Share on other sites More sharing options...
Techos Posted December 22, 2011 Share Posted December 22, 2011 Look awesome… i'll try this after school(IF THIS WORKS YOU'RE MY GOD) Link to comment Share on other sites More sharing options...
Recoil Posted December 22, 2011 Share Posted December 22, 2011 In modConstants(client)I had to change the max buttons from 35:Public Const MAX_BUTTONS As Long = 39When I go to make the exe file, it raises an error modHandleData, Sub HandlePlayerData:Call SetPlayerHair(i, Buffer.ReadLong)"Sub or Function not defined"Edit: my mistake. I did not add all of the modDatabase changes. Link to comment Share on other sites More sharing options...
DJMaxus Posted December 22, 2011 Author Share Posted December 22, 2011 @Recoil:> In modConstants(client)> I had to change the max buttons from 35:> Public Const MAX_BUTTONS As Long = 39Ah thank you for pointing that out, I forgot about that. Added to original post. Link to comment Share on other sites More sharing options...
Recoil Posted December 22, 2011 Share Posted December 22, 2011 I have a question while I am at it. I followed the tutorial exactly, + the minor change I suggested, compiles and works. Now when I go to create a character I will select the class, I hit "Accept" then I get an error "Object variable or With block variable not set".So I went back through VB6, caught the error: "Subscript out of range"modDirectX8 - DrawNewChar Sub = RenderTexture Tex_Hair(newCharHair), x + 265, y + 120, 32, 0, 32, 32, 32, 32I did not do the first tutorial that was listed for the paper dolling. Also, I do not have any images in the folders. I was hoping that I could get pointed to an idea of what I am doing wrong? Thanks Link to comment Share on other sites More sharing options...
DJMaxus Posted December 22, 2011 Author Share Posted December 22, 2011 You will need some images in your hairs folder. Count_Hair, which is the number of hair graphics in the folder, needs to return a positive value. 0 and any negative value will be out of range.In the Resources section, you will find some CS:DE paperdolling graphics packs for you to use with your project.You do not need any prerequisite tutorial for this one to work, but it works nicely with the Paperdolling tut. Link to comment Share on other sites More sharing options...
Recoil Posted December 22, 2011 Share Posted December 22, 2011 Okay, to make sure I am getting this correct, (since I went ahead and installed the other tutorial as well), All the body party go in the paperdoll folder, and the hair goes in the male/female folders depending on what it is, and I just have to rename all the images: 1.png, 2.png, 3.png, etc? Link to comment Share on other sites More sharing options...
Recoil Posted December 22, 2011 Share Posted December 22, 2011 Alright, I am still having difficulty. I have installed all hair and gender images from the graphics pack…they are all the same to make sure the names are the same for testing.When I debug I keep having issues with this line:```RenderChar RenderTexture Tex_Hair(newCharHair), x + 265, y + 120, 32, 0, 32, 32, 32, 32```I have went back through all the tutorial and ensured that I followed the lines correctly. Is anyone else running into this issue because I cannot seem to locate how to resolve it. Link to comment Share on other sites More sharing options...
Ulyx Posted December 22, 2011 Share Posted December 22, 2011 OMG, i love this ! This is working very well :) Link to comment Share on other sites More sharing options...
Recoil Posted December 22, 2011 Share Posted December 22, 2011 Is it possible to post the working Public Sub DrawNewChar() from client-modDirectX8? Link to comment Share on other sites More sharing options...
Recoil Posted December 23, 2011 Share Posted December 23, 2011 Nevermind. I had the "hair" folder in the "graphics" folder. This is supposed to go into "characters"(client\data files\graphics\characters\hair).I thought I had it in there but had overlooked which directory I was creating my files in. Sorry for all the trouble and unnecessary posts :( Link to comment Share on other sites More sharing options...
DJMaxus Posted December 23, 2011 Author Share Posted December 23, 2011 @Recoil:> Nevermind. I had the "hair" folder in the "graphics" folder. This is supposed to go into "characters"(client\data files\graphics\characters\hair).> > I thought I had it in there but had overlooked which directory I was creating my files in. Sorry for all the trouble and unnecessary posts :(Glad you got it figured out. ;) Link to comment Share on other sites More sharing options...
Emy Posted December 23, 2011 Share Posted December 23, 2011 Works like a charm, thank you!I got one question though, if you could help me with it. When you make a new character, it starts with no hair, how and what do I change/add so you can't make a char without hair? Link to comment Share on other sites More sharing options...
PVJsquad Posted December 24, 2011 Share Posted December 24, 2011 whether this also applies to EO 2.0 :huh: Link to comment Share on other sites More sharing options...
DJMaxus Posted December 24, 2011 Author Share Posted December 24, 2011 @Couture:> Works like a charm, thank you!> I got one question though, if you could help me with it. When you make a new character, it starts with no hair, how and what do I change/add so you can't make a char without hair?You can make newCharHair = 1 when the menu is drawn.@GoldSide:> whether this also applies to EO 2.0 :huh:No it does not, every tutorial I do in the future will also be for CS:DE. EO and CS:DE are very similar, so you could convert using many of the same procedures. Link to comment Share on other sites More sharing options...
PVJsquad Posted December 24, 2011 Share Posted December 24, 2011 but whether this procedure can apply to EO? Link to comment Share on other sites More sharing options...
DJMaxus Posted December 24, 2011 Author Share Posted December 24, 2011 @GoldSide:> but whether this procedure can apply to EO?Not the exact procedures. You'll have to make modifications. Link to comment Share on other sites More sharing options...
PVJsquad Posted December 24, 2011 Share Posted December 24, 2011 okay :) Link to comment Share on other sites More sharing options...
DJMaxus Posted December 25, 2011 Author Share Posted December 25, 2011 Fixed a bug, the original post was updated.If you have already implemented the tutorial, replace your DrawHair sub with the one in the first post. Thanks. Link to comment Share on other sites More sharing options...
Domino_ Posted December 27, 2011 Share Posted December 27, 2011 Ohh, great code, If only I could convert it to EO xD Link to comment Share on other sites More sharing options...
kibbelz Posted December 27, 2011 Share Posted December 27, 2011 @ThereIsNoDomino_:> Ohh, great code, If only I could convert it to EO xDIt shouldn't be too hard. Really all you have to do is look how EO does the rendering with the EO paper doll system and make the scroll bars manually. I have already converted it. Nice tutorial :3\. Keep them coming! Link to comment Share on other sites More sharing options...
handsomenicor Posted December 28, 2011 Share Posted December 28, 2011 Does it work on EO? Link to comment Share on other sites More sharing options...
erkro1 Posted December 28, 2011 Share Posted December 28, 2011 @handsomenicor:> Does it work on EO?Read the post above yours. >.> Link to comment Share on other sites More sharing options...
gdog12356 Posted December 30, 2011 Share Posted December 30, 2011 How would i make it so instead of the 32x32 square, it displays a bigger sprite. Would i have to use powers of 2 when i display it(obviously)? I was fooling around with this```RenderTexture Tex_Hair(newCharHair), x + 265, y + 120, 32, 0, 32, 32, 32, 32```I'm not too sure what changing these values will do. Instead i would rather have it show a standing version of my sprite, as i do not know what it is showing because it cuts off at the head. ive been trying to figure this out for a while. if anyone has any solutions, or ideas, please let me know :]!also im not sure if it was this specific tutorial, but the password confirmation doesnt work. When you need to retype your password, if you mess up it still accepts it. Link to comment Share on other sites More sharing options...
Ruins of Hell Posted December 30, 2011 Share Posted December 30, 2011 @✖:> ```> RenderTexture Tex_Hair(newCharHair), x + 265, y + 120, 32, 0, 32, 32, 32, 32> ```> > I'm not too sure what changing these values will do.Make a backup and fool around with them. Better yet: search for "Sub RenderTexture" in your client so you can see the names of the values used, and adjust accordingly. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now