Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Mondo

Members
  • Posts

    44
  • Joined

  • Last visited

    Never

Everything posted by Mondo

  1. @Robin: > The centralisation problem comes because you ported over the DX8 font width method rather than using the DD7 native to EO. > > ``` > Public Function EngineGetTextWidth(ByRef UseFont As String, ByVal text As String) As Integer > Dim LoopI As Integer > > 'Make sure we have text > If LenB(text) = 0 Then Exit Function > > 'Loop through the text > For LoopI = 1 To Len(text) > EngineGetTextWidth = EngineGetTextWidth + LetterWidth(Mid$(text, LoopI, 1)) > Next LoopI > > End Function > > Public Function LetterWidth(ByVal text As String) As Integer > ' You can use this function to specify the width of each letter you'll be using, if unspecified space will be 4 pixels. > > Select Case text > Case "!", "1", "I", "i", "|", "l", "¡", "'", ".", ",", ";", ":" > LetterWidth = 2 > Case Else > LetterWidth = 4 > End Select > End Function > > ``` > Remove all that. > > Replace all calls with getWidth(). Pass through the DC and the string as the parameters. Will perfectly centralise everything. Yep, noticed that and posted it on reply #34… I've updated the tutorial reflecting that. Much appreciated.
  2. @tslusny: > i said before no error popups im on windows 7 and it just white the server window and shows window with option to debug or close exe I'm on Windows 7 too, and my VB6 does not crash and ask for a debug… are you running this from Visual Basic 6, or are you just running the Eclipse Origins.exe ?
  3. @tslusny: > this totorial still not working for me My friend, I told you before, you need to provide error number, error description, module, and subroutine or function as well as where the program breaks if you expect me to provide assistance… Just saying that it doesn't work for you does not get you any closer to making it work.
  4. Ok this is the corrected DrawChatBubble routine, it does center now. ``` ' CHAT BUBBLE HACK Public Sub DrawChatBubble(ByVal Index As Long) Dim theArray() As String, x As Long, Y As Long, i As Long, MaxWidth As Long, xwidth As Long, yheight As Long, colour As Long, x3 As Long, y3 As Long Dim MMx As Long Dim MMy As Long Dim TOPLEFTrect As RECT Dim TOPCENTERrect As RECT Dim TOPRIGHTrect As RECT Dim MIDDLELEFTrect As RECT Dim MIDDLECENTERrect As RECT Dim MIDDLERIGHTrect As RECT Dim BOTTOMLEFTrect As RECT Dim BOTTOMCENTERrect As RECT Dim BOTTOMRIGHTrect As RECT Dim TIPrect As RECT ' DESIGNATE CHATBUBBLE SECTIONS FROM CHATBUBBLE IMAGE With TOPRIGHTrect .top = 0 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4 End With With TOPCENTERrect .top = 0 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4 End With With TOPLEFTrect .top = 0 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4 End With With MIDDLERIGHTrect .top = 4 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4 End With With MIDDLECENTERrect .top = 4 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4 End With With MIDDLELEFTrect .top = 4 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4 End With With BOTTOMRIGHTrect .top = 8 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4 End With With BOTTOMCENTERrect .top = 8 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4 End With With BOTTOMLEFTrect .top = 8 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4 End With With TIPrect .top = 12 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4 End With Call DDS_BackBuffer.SetForeColor(RGB(255, 255, 255)) With chatBubble(Index) If .targetType = TARGET_TYPE_PLAYER Then ' it's a player If GetPlayerMap(.target) = GetPlayerMap(MyIndex) Then ' change the colour depending on access colour = QBColor(Yellow) ' it's on our map - get co-ords x = ConvertMapX((Player(.target).x * 32) + Player(.target).XOffset) + 16 Y = ConvertMapY((Player(.target).Y * 32) + Player(.target).YOffset) - 16 ' word wrap the text WordWrap_Array .Msg, ChatBubbleWidth, theArray ' find max width For i = 1 To UBound(theArray) If getWidth(TexthDC, theArray(i)) > MaxWidth Then MaxWidth = getWidth(TexthDC, theArray(i)) Next ' calculate the new position xwidth relative to DDS_ChatBubble and yheight relative to DDS_ChatBubble xwidth = 10 + MaxWidth ' the first five is just air. yheight = 3 + (UBound(theArray) * 7) ' the first three are just air. ' Compensate the yheight drift Y = Y - yheight ' render bubble ' top left ' RenderTexture Tex_GUI(37), xwidth - 9, yheight - 5, 0, 0, 9, 5, 9, 5 Call Engine_BltFast(x + (xwidth + 4), Y - (yheight - 4), DDS_ChatBubble, TOPLEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' top center ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, yheight - 5, 119, 0, 9, 5, 9, 5 For x3 = x - (xwidth - 8) To x + (xwidth) Call Engine_BltFast(x3, Y - (yheight - 4), DDS_ChatBubble, TOPCENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next x3 ' top right ' RenderTexture Tex_GUI(37), xwidth, yheight - 5, 9, 0, MaxWidth, 5, 5, 5 Call Engine_BltFast(x - (xwidth - 4), Y - (yheight - 4), DDS_ChatBubble, TOPRIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' middle left ' RenderTexture Tex_GUI(37), xwidth - 9, y, 0, 19, 9, 6, 9, 6 For y3 = Y - (yheight - 8) To Y + (yheight) Call Engine_BltFast(x + (xwidth + 4), y3, DDS_ChatBubble, MIDDLELEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next y3 ' middle center ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, y, 119, 19, 9, 6, 9, 6 For y3 = Y - (yheight - 8) To Y + (yheight) For x3 = x - (xwidth - 8) To x + (xwidth) Call Engine_BltFast(x3, y3, DDS_ChatBubble, MIDDLECENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next x3 Next y3 ' middle right ' RenderTexture Tex_GUI(37), xwidth, y, 9, 19, (MaxWidth \ 2) - 5, 6, 9, 6 For y3 = Y - (yheight - 8) To Y + (yheight) Call Engine_BltFast(x - (xwidth - 4), y3, DDS_ChatBubble, MIDDLERIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next y3 ' bottom left ' RenderTexture Tex_GUI(37), xwidth + (MaxWidth \ 2) + 6, y, 9, 19, (MaxWidth \ 2) - 5, 6, 9, 6 Call Engine_BltFast(x + (xwidth + 4), Y + (yheight + 4), DDS_ChatBubble, BOTTOMLEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' bottom center ' RenderTexture Tex_GUI(37), xwidth - 9, yheight, 0, 6, 9, (UBound(theArray) * 12), 9, 1 For x3 = x - (xwidth - 8) To x + (xwidth) Call Engine_BltFast(x3, Y + (yheight + 4), DDS_ChatBubble, BOTTOMCENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next x3 ' bottom right ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, yheight, 119, 6, 9, (UBound(theArray) * 12), 9, 1 Call Engine_BltFast(x - (xwidth - 4), Y + (yheight + 4), DDS_ChatBubble, BOTTOMRIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' little pointy bit ' RenderTexture Tex_GUI(37), x - 5, y, 58, 19, 11, 11, 11, 11 Call Engine_BltFast(x, Y + (yheight + 8), DDS_ChatBubble, TIPrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' Lock the backbuffer so we can draw text and names TexthDC = DDS_BackBuffer.GetDC ' render each line centralised Y = Y - (yheight - 5) For i = 1 To UBound(theArray) DrawTextNoShadow TexthDC, x - (getWidth(TexthDC, theArray(i)) - 10), Y, theArray(i), QBColor(Black) ' .colour Y = Y + 12 Next ' Release DC DDS_BackBuffer.ReleaseDC TexthDC End If End If ' check if it's timed out - close it if so If .Timer + 5000 < GetTickCount Then .active = False End If End With End Sub ' CHAT BUBBLE HACK ``` The real change was only to call the old getwidth function, passing the texthdc and the message as parameters and it gets you back the real size, no guesstimating anymore. Try it out…
  5. @Lumiere: > Uhm when i write something and press enter the game closes,there is no error ,weird. It did that to me once, the game closes when its broken in a routine that has no error handler… When it happened to me it was that my game didn't know how to handle the server message to open a bubble... So it could be somewhere in handlechatbubble routine or the declarations of the SChatBubble in the serverpackets.
  6. @Domino_: > Smtn works > > ``` > ' render each line centralised > Y = Y - (yheight - 5) > For i = 1 To UBound(theArray) > DrawTextNoShadow TexthDC, x - (xwidth - (x / xwidth)), Y, theArray(i), QBColor(Black) ' .colour > Y = Y + 12 > Next > > ``` > P.S. _**THIS WORKS ONLY WITH ~ 5+ LETTERS!**_ :( Its a bit more complicated than that, you need to calculate the TextDC width, and then half that and substract that amount from the bubble's xwidth divided by half… or something fo the sort... ;) I'll review it tonight after work.
  7. @or3o: > Do you by chance know how to edit the maps files so ya dont have to delete all you maps? Sorry unfortunately I have no clue on how to do that… I'd suggest Commenting Server Step 3\. hence you don't read the animation attribute (nor will it mess up when it tries to render)... Once the map is in memory you save it again, this WILL write the Animation record in each tile... Do this for all your maps and then uncomment the Step 3. Its a long shot but it might just work...
  8. @Erwin: > It looks like something that can be fixed by using Trim$ a few times, but I'm not sure that will work. Yeah the problem really is that the text width is "calculated" by guess estimating the pixel sizes of each letter, so you calculate the bubble size to be say 150 pixels, but the reality is that your text is only 100 pixels long (o's being wider that i's). And since the text is placed on the left border of the bubble you get 50 pixels of air. I've been thinking to fix it, just never came around it. The magic will happen at: ``` ' render each line centralised y = y - (yheight - 5) For i = 1 To UBound(theArray) DrawTextNoShadow TexthDC, x - (xwidth - 10), y, theArray(i), QBColor(Black) ' .colour y = y + 12 Next ``` I just need to figure out how to better calculate x - (xwidth - 10).
  9. Minor correction to routine BltMapAnimation. ``` FrameCount = 15 ' Animation(animNum).Frames(layer) ``` Should be: ``` FrameCount = Animation(animNum).Frames(layer) ``` I hard coded 15 frames to test, forgot to uncomment. The Fix already reflected in the tutorial.
  10. @tslusny: > i tried it another time and my server just freeze when i add animation to map, do you tested this if it really works? i think there is infinite loop or something like that I have it working on my on EO 2.0 and works quite well, even if the whole map is filled with animations… I think you need to set up a break point in the bltmapanimation routine and start debugging from there...
  11. @Erwin: > ``` > size = size + EngineGetTextWidth(Font_Default, Mid$(text, i, 1)) > ``` That is correct, I missed that one. :D Fixed on the Tutorial.
  12. @Erwin: > This still doesn't work perfect, I get Sub or Function not Defined at: > ``` > Call DeleteObject(GameFont) > ``` This requires that your EO 2.0 be loaded with the the Font Memory Leak fix ALREADY applied ( http://www.touchofdeathforums.com/smf/index.php/topic,71691.0.html) if you haven't applied the FIX then DO SO before you begin with this. The Font Memory Leak Fix has that declaration: ``` Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long ```
  13. Works Great! Thank you for sharing! :D
  14. Works Great! Thank you for Sharing! :D
  15. @tslusny: > Do you tested this? becouse this code has some mess with frames for me and when i tryied to change frames on animation in animation editor my pcs graphic card crashed….. so i think u dont tested it :confused: Really, what mess did you find in the frames? Coz the tutorial only asked to create ONE new frame, and edit an existing one and all this it had to be done on frmedit_map, I never touched a thing in the animation editor… So if its crashing on you I'd suggest rolling back the changes or going back to a backup and running through the tutorial again. If you need assistance please provide printscreens of the errors, or error numbers and descriptions and the module, routine and line of code where you get the error. cheers
  16. @Riftguy: > So will this store the animations client side so the server does not bombard the client with packets constantly? Yes sir, they're only sent once when the map is read… after that they're stored in the local map and just replayed.
  17. Hello, This is my second tutorial so I haven't practiced this enough, I might still mess up. Anyhow, I never found complete Map Animations Tutorial on the forums and certainly found no information about it except for (again) a quick suggestion from Robin on how to place the sprite animations in the map and again some comments from other programmers regarding this already being done on Robin's Amazing Package. Robin's Map Animation does not overload the server/client with network traffic, it just sends the map once, which includes all the animations in it, and they're all handled on client side. So I spent a couple hours again hacking the Amazing Package code looking for what I needed to make this work on EO 2.0 and now that I found it I thought I'd share it with the EO community. As always, credits for this superb piece of software engineering go to Robin Perris, author of Robin's Amazing Package ([http://www.touchofdeathforums.com/smf/index.php/topic,74117.0.html](http://www.touchofdeathforums.com/smf/index.php/topic,74117.0.html)) where I grabbed the Map Animation code from. On that note I invite again you to review Robin's bundle, its filled with tons of lessons and good stuff lying there ready for the grabbing if you are patient enough to look for it. Try not just to copy paste what you see, and go a step further and try to understand what the code actually does. Disclaimer: Please keep in mind this is a crude implementation and may probably need some major tweaking, again i hope it will help anyone who is looking for simple map animations and can't find how to make'em work. What you'll need: VB6 Enterprise Edition EO 2.0 Source Code. The ability to DEBUG, set a breakpoint and follow steps. Skills to use the "find" function, or have a good eye for the nested code. Tons, and tons, and tons of patience. So again lets get messy… **ON SERVER SIDE** **STEP1\. On modTypes in Type TileRec** Find: ``` DirBlock As Byte ```Add BELOW That: ``` Animation As Long ``` **STEP 2\. On modHandleData in HandleMapData** Find: ``` Map(mapNum).Tile(x, y).DirBlock = Buffer.ReadByte ```Add BELOW That: ``` ' MAP ANIMATION HACK Map(mapNum).Tile(x, y).Animation = Buffer.ReadLong ' MAP ANIMATION HACK ``` **STEP 3\. On modServerTCP in MapCache_Creat** Find: ``` Buffer.WriteByte .DirBlock ```Add BELOW that: ``` ' MAP ANIMATION HACK Buffer.WriteLong .Animation ' MAP ANIMATION HACK ``` **ON CLIENT SIDE** **STEP 1\. on ModTypes un Public Type TileRec** Find: ``` DirBlock As Byte ``` Add BELOW that: ``` ' MAP ANIMATION HACK Animation As MapAnimRec ' MAP ANIMATION HACK ``` Before the Public Type TileRec add the following code: ``` ' MAP ANIMATION HACK Public Type MapAnimRec Animation As Long Timer(0 To 1) As Long FrameIndex(0 To 1) As Long End Type ' MAP ANIMATION HACK ``` **STEP 2\. On modHandleData in HandleMapData** Find: ``` Map.Tile(x, y).DirBlock = Buffer.ReadByte ``` Add BELOW that: ``` ' MAP ANIMATION HACK Map.Tile(x, y).Animation.Animation = Buffer.ReadLong ' MAP ANIMATION HACK ``` **STEP 3\. on ModDirectDraw7 add a new routine** ``` ' MAP ANIMATION HACK Public Sub BltMapAnimation(ByVal x As Long, ByVal y As Long, ByVal layer As Long) Dim animNum As Long Dim Sprite As Integer Dim sRECT As DxVBLib.RECT Dim dRECT As DxVBLib.RECT Dim i As Long Dim width As Long, height As Long Dim FrameCount As Long animNum = Map.Tile(x, y).Animation.Animation If animNum = 0 Or animNum > MAX_ANIMATIONS Then Exit Sub Sprite = Animation(animNum).Sprite(layer) If Sprite < 1 Or Sprite > NumAnimations Then Exit Sub FrameCount = Animation(animNum).Frames(layer) AnimationTimer(Sprite) = GetTickCount + SurfaceTimerMax If DDS_Animation(Sprite) Is Nothing Then Call InitDDSurf("animations\" & Sprite, DDSD_Animation(Sprite), DDS_Animation(Sprite)) End If ' total width divided by frame count width = DDSD_Animation(Sprite).lWidth / FrameCount height = DDSD_Animation(Sprite).lHeight sRECT.top = 0 sRECT.Bottom = height sRECT.left = (Map.Tile(x, y).Animation.FrameIndex(layer)) * width sRECT.Right = sRECT.left + width x = ConvertMapX(x * 32) + 16 - (width / 2) y = ConvertMapY(y * 32) + 16 - (height / 2) ' Clip to screen If y < 0 Then With sRECT .top = .top - y End With y = 0 End If If x < 0 Then With sRECT .left = .left - x End With x = 0 End If If y + height > DDSD_BackBuffer.lHeight Then sRECT.Bottom = sRECT.Bottom - (y + height - DDSD_BackBuffer.lHeight) End If If x + width > DDSD_BackBuffer.lWidth Then sRECT.Right = sRECT.Right - (x + width - DDSD_BackBuffer.lWidth) End If Call Engine_BltFast(x, y, DDS_Animation(Sprite), sRECT, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) End Sub ' MAP ANIMATION HACK ``` **STEP 4\. On modDirectDraw7 modify Render_Graphics function add call to BltMapAnimation** Right after: ``` ' Blit out the items ``` And Before ``` 'draw animations ``` Add the following code: ``` ' MAP ANIMATION HACK ' draw low-level map animations this is layer 0 (BELOW PLAYER) For x = 0 To Map.MaxX For y = 0 To Map.MaxY BltMapAnimation x, y, 0 Next Next ' MAP ANIMATION HACK ``` Then Find: ``` ' animations If NumAnimations > 0 Then ``` Add ABOVE that: ``` ' MAP ANIMATION HACK ' draw low-level map animations this is layer 1 above the player. For x = 0 To Map.MaxX For y = 0 To Map.MaxY BltMapAnimation x, y, 1 Next Next ' MAP ANIMATION HACK ``` **STEP 5\. On ModGameLogic add routine** ``` ' MAP ANIMATION HACK Public Sub CheckMapAnim(ByVal x As Long, ByVal y As Long) Dim animNum As Long Dim layer As Long Dim loopTime As Long Dim FrameCount As Long animNum = Map.Tile(x, y).Animation.Animation ' if it doesn't exist then exit sub If animNum = 0 Or animNum > MAX_ANIMATIONS Then Exit Sub For layer = 0 To 1 loopTime = Animation(animNum).loopTime(layer) FrameCount = Animation(animNum).Frames(layer) -1 ' This is to prevent an odd flicker in the animations. ' make sure we don't have an extra frame If Map.Tile(x, y).Animation.FrameIndex(layer) = 0 Then Map.Tile(x, y).Animation.FrameIndex(layer) = 1 If Map.Tile(x, y).Animation.Timer(layer) + loopTime
  18. @crzy: > First its Cause and second shouldn't you automatically add the fix for the leak to the tutorial instead of forcing people to add it? First thank you for correcting my grammar the last thing I want is to confuse someone with my poor spelling. Second, no I won't do a tutorial of something that's already been explained elsewhere. However I will fix my noshadow routine to include the fix and indicate that its a prerequisite for this tutorial that you MUST have the Font Memory Leak fix in place in order for this to work. Thank you for your input.
  19. @Justn: > K gonna play around with it later thanks for sharing > > This is what I was asking about http://www.touchofdeathforums.com/smf/index.php/topic,71691.0.html Awesome! Now I can use a different font! :D I tested it the Chat Bubbles with the Font Fix and it works ok, however you'll need to modify the DrawTextNoShadow. Copy the Memory Leak Free DrawText function in it, and then remove the shadow effect again.
  20. @Justn: > Very cool mondo.. does this work/look any better with text rendering memory leak fix? Well it should work with any DrawText function you provide… You only need to change the DrawTextNoShadow with in the DrawChatBubble function with whatever you use to draw text now... I didn't know there was a text rendering memory leak fix!
  21. @Owen: > You say credits go to "Rober Perris" > You might want to fix that. (It's Robin Perris by the way) My bad, thank you!
  22. You're right! :) Tutorial is at: http://www.touchofdeathforums.com/smf/index.php/topic,79790.0.html
  23. Hello, UPDATE: JULY 8th, 2012… If you already applied this tutorial and you're having centering text issues you MIGHT want to review it and apply it again, I've modified the tutorial to get rid of some old deprecated functions in favor for something better. However if you're already satisfied with what you have then by all means leave it AS IS. This is my first tutorial so I urge you to bear with me. I never found a Chat Bubble tutorial and found no information on how to build one except for a quick suggestion from Robin on how to make it work and some comments regarding this already being available on CrystalShire. So I went and hacked my way through CrystalShire to get one for my game… And now that I got it I thought I'd be able to give a little helping hand back to the EO community, from whom I've learned a lot, by sharing what I learned. As always, credits for this superb piece of software engineering go to Robin Perris, author of EO and CrystalShire where I grabbed the Bubble Chat code from, and Debbie The Fabulous for her 7's Upgraded Minimap Tutorial (http://www.touchofdeathforums.com/smf/index.php/topic,75443.0.html) from where I learned how to work the Direct Draw Surfaces. On that note I invite you to review as many tutorials as you can and try not just to copy/paste what you see in them. Go a step further and try to understand what the code actually does in hope that you can understand how pieces work, and how they'd behave if you combine them differently. In the end you'll get something like this... ![](http://www.touchofdeathforums.com/smf/index.php?action=dlattach;topic=79790.0;attach=20955;image) **Disclaimer: Please keep in mind this is a crude implementation and it needs major tweaking, I'm sharing it in hope that it will help anyone who is looking for simple the Bubble Chats to build from.** What you'll need: VB6 Enterprise Edition EO 2.0 Source Code _**with the Font Memory Leak fix ALREADY applied ( http://www.touchofdeathforums.com/smf/index.php/topic,71691.0.html) if you haven't applied it then DO SO before you begin with this.**_ Debugging skills (yep, you'll need to know how to set a breakpoint and understand errors). Tons of patience. So lets get messy… **SERVER SIDE** **STEP 1\. On modEnumerations modify the ServerPackets** Find: ``` ' Make sure SMSG_COUNT is below everything else SMSG_COUNT ``` Add the following code ABOVE that: ``` ' CHAT BUBBLE HACK SChatBubble ' CHAT BUBBLE HACK ``` **STEP 2\. On ModHandleData Edit HandleSayMsg Sub** Find the following code at the end of the subroutine: ``` Set Buffer = Nothing ``` Add the following code ABOVE that. ``` ' CHAT BUBBLE HACK Call SendChatBubble(GetPlayerMap(index), index, TARGET_TYPE_PLAYER, Msg, White) ' CHAT BUBBLE HACK ``` **STEP 3\. On modServerTCP add Sub SendChatBubble anywhere in the module.** ``` ' CHAT BUBBLE HACK Sub SendChatBubble(ByVal mapNum As Long, ByVal target As Long, ByVal targetType As Long, ByVal message As String, ByVal Colour As Long) Dim Buffer As clsBuffer Set Buffer = New clsBuffer Buffer.WriteLong SChatBubble Buffer.WriteLong target Buffer.WriteLong targetType Buffer.WriteString message Buffer.WriteLong Colour SendDataToMap mapNum, Buffer.ToArray() Set Buffer = Nothing End Sub ' CHAT BUBBLE HACK ``` And thats it on this end. **CLIENT SIDE** MOST IMPORTANT Download the attached file "chatbubble.bmp" to your folder /data files/graphics **STEP 1\. On modEnumerations modify the ServerPackets** Find: ``` ' Make sure SMSG_COUNT is below everything else SMSG_COUNT ``` Add the following code ABOVE that: ``` ' CHAT BUBBLE HACK SChatBubble ' CHAT BUBBLE HACK ``` **STEP 2\. on modHandleData add the following code on the InitMessages** Find: ``` ' Error handler Exit Sub ``` Add the following code ABOVE that. ``` ' CHAT BUBBLE HACK HandleDataSub(SChatBubble) = GetAddress(AddressOf HandleChatBubble) ' CHAT BUBBLE HACK ``` **STEP 3\. On modHandleData add the following subroutine anywhere in the module.** ``` ' CHAT BUBBLE HACK Private Sub HandleChatBubble(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long) Dim Buffer As clsBuffer, targetType As Long, target As Long, message As String, colour As Long Set Buffer = New clsBuffer Buffer.WriteBytes Data() target = Buffer.ReadLong targetType = Buffer.ReadLong message = Buffer.ReadString colour = Buffer.ReadLong AddChatBubble target, targetType, message, colour Set Buffer = Nothing End Sub ' CHAT BUBBLE HACK ``` **STEP 4\. On modTEXT add the following sub at the bottom of the module** ``` ' BUBBLE CHAT HACK Public Sub WordWrap_Array(ByVal text As String, ByVal MaxLineLen As Long, ByRef theArray() As String) Dim lineCount As Long, i As Long, size As Long, lastSpace As Long, b As Long 'Too small of text If Len(text) < 2 Then ReDim theArray(1 To 1) As String theArray(1) = text Exit Sub End If ' default values b = 1 lastSpace = 1 size = 0 For i = 1 To Len(text) ' if it's a space, store it Select Case Mid$(text, i, 1) Case " ": lastSpace = i Case "_": lastSpace = i Case "-": lastSpace = i End Select 'Add up the size size = size + getWidth(TexthDC, Mid$(Text, i, 1)) 'Check for too large of a size If size > MaxLineLen Then 'Check if the last space was too far back If i - lastSpace > 12 Then 'Too far away to the last space, so break at the last character lineCount = lineCount + 1 ReDim Preserve theArray(1 To lineCount) As String theArray(lineCount) = Trim$(Mid$(text, b, (i - 1) - b)) b = i - 1 size = 0 Else 'Break at the last space to preserve the word lineCount = lineCount + 1 ReDim Preserve theArray(1 To lineCount) As String theArray(lineCount) = Trim$(Mid$(text, b, lastSpace - b)) b = lastSpace + 1 'Count all the words we ignored (the ones that weren't printed, but are before "i") size = getWidth(TexthDC, Mid$(text, lastSpace, i - lastSpace)) End If End If ' Remainder If i = Len(text) Then If b i Then lineCount = lineCount + 1 ReDim Preserve theArray(1 To lineCount) As String theArray(lineCount) = theArray(lineCount) & Mid$(text, b, i) End If End If Next End Sub Public Function WordWrap(ByVal text As String, ByVal MaxLineLen As Integer) As String Dim TempSplit() As String Dim TSLoop As Long Dim lastSpace As Long Dim size As Long Dim i As Long Dim b As Long 'Too small of text If Len(text) < 2 Then WordWrap = text Exit Function End If 'Check if there are any line breaks - if so, we will support them TempSplit = Split(text, vbNewLine) For TSLoop = 0 To UBound(TempSplit) 'Clear the values for the new line size = 0 b = 1 lastSpace = 1 'Add back in the vbNewLines If TSLoop < UBound(TempSplit()) Then TempSplit(TSLoop) = TempSplit(TSLoop) & vbNewLine 'Only check lines with a space If InStr(1, TempSplit(TSLoop), " ") Or InStr(1, TempSplit(TSLoop), "-") Or InStr(1, TempSplit(TSLoop), "_") Then 'Loop through all the characters For i = 1 To Len(TempSplit(TSLoop)) 'If it is a space, store it so we can easily break at it Select Case Mid$(TempSplit(TSLoop), i, 1) Case " ": lastSpace = i Case "_": lastSpace = i Case "-": lastSpace = i End Select 'Add up the size size = size + getwidth(TexthDC, Mid$(TempSplit(TSLoop), i, 1))) 'Check for too large of a size If size > MaxLineLen Then 'Check if the last space was too far back If i - lastSpace > 12 Then 'Too far away to the last space, so break at the last character WordWrap = WordWrap & Trim$(Mid$(TempSplit(TSLoop), b, (i - 1) - b)) & vbNewLine b = i - 1 size = 0 Else 'Break at the last space to preserve the word WordWrap = WordWrap & Trim$(Mid$(TempSplit(TSLoop), b, lastSpace - b)) & vbNewLine b = lastSpace + 1 'Count all the words we ignored (the ones that weren't printed, but are before "i") size = getwidth(TexthDC, Mid$(TempSplit(TSLoop), lastSpace, i - lastSpace)) End If End If 'This handles the remainder If i = Len(TempSplit(TSLoop)) Then If b i Then WordWrap = WordWrap & Mid$(TempSplit(TSLoop), b, i) End If End If Next i Else WordWrap = WordWrap & TempSplit(TSLoop) End If Next TSLoop End Function Public Function getWidth(ByVal DC As Long, ByVal text As String) As Long ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler getWidth = frmMain.TextWidth(text) \ 2 ' Error handler Exit Function errorhandler: HandleError "getWidth", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Function End Function ' CHANGE FONT FIX ' PLEASE NOTE THIS WILL FAIL MISERABLY IF YOU DIDN'T APPLY THE FONT MEMORY LEAK FIX FIRST ' CHAT BUBBLE HACK ' I ONLY DID THIS COZ THE CHATBUBBLE TEXT LOOKS BETTER WITHOUT SHADOW OVER WHITE BUBBLES! Public Sub DrawTextNoShadow(ByVal hdc As Long, ByVal x, ByVal y, ByVal text As String, color As Long) ' If debug mode, handle error then exit out Dim OldFont As Long ' HFONT If Options.Debug = 1 Then On Error GoTo errorhandler Call SetFont(FONT_NAME, FONT_SIZE) OldFont = SelectObject(hdc, GameFont) Call SetBkMode(hdc, vbTransparent) Call SetTextColor(hdc, color) Call TextOut(hdc, x, y, text, Len(text)) Call SelectObject(hdc, OldFont) Call DeleteObject(GameFont) ' Error handler Exit Sub errorhandler: HandleError "DrawTextNoShadow", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Sub End Sub ' CHAT BUBBLE HACK ' CHANGE FONT FIX ``` **STEP 5\. On modTypes add the following type anywhere** ``` ' CHAT BUBBLE HACK Public Type ChatBubbleRec Msg As String colour As Long target As Long targetType As Byte timer As Long active As Boolean End Type ' CHAT BUBBLE HACK ``` **Step 6\. On modGameLogic add this subroutine anywhere in the module** ``` ' CHAT BUBBLE HACK Public Sub AddChatBubble(ByVal target As Long, ByVal targetType As Byte, ByVal Msg As String, ByVal colour As Long) Dim i As Long, Index As Long ' set the global index chatBubbleIndex = chatBubbleIndex + 1 If chatBubbleIndex < 1 Or chatBubbleIndex > MAX_BYTE Then chatBubbleIndex = 1 ' default to new bubble Index = chatBubbleIndex ' loop through and see if that player/npc already has a chat bubble For i = 1 To MAX_BYTE If chatBubble(i).targetType = targetType Then If chatBubble(i).target = target Then ' reset master index If chatBubbleIndex > 1 Then chatBubbleIndex = chatBubbleIndex - 1 ' we use this one now, yes? Index = i Exit For End If End If Next ' set the bubble up With chatBubble(Index) .target = target .targetType = targetType .Msg = Msg .colour = colour .timer = GetTickCount .active = True End With End Sub ' CHAT BUBBLE HACK ``` **STEP 7\. On modConstants add the following constant anywhere in the module.** ``` ' CHAT BUBBLE HACK Public Const ChatBubbleWidth As Long = 200 Public Const Font_Default As String = "Default" ' CHAT BUBBLE HACK ``` **STEP 8\. On modGlobals add the following global variables anywhere in the module.** ``` ' chat bubble hack Public chatBubble(1 To MAX_BYTE) As ChatBubbleRec Public chatBubbleIndex As Long ' chat bubble hack ``` **STEP 9\. On modDirectDraw7 add the following variables on the declarations section (anywhere on top of the module).** ``` ' CHAT BUBBLE HACK Public DDS_ChatBubble As DirectDrawSurface7 Public DDSD_ChatBubble As DDSURFACEDESC2 ' CHAT BUBBLE HACK ``` **STEP 10\. On modDirectDraw7 add the following code in the InitSurfaces subroutine.** Find: ``` ' count the blood sprites BloodCount = DDSD_Blood.lWidth / 32 ``` Add this code ABOVE that. ``` ' CHAT BUBBLE HACK If FileExist(App.Path & "\data files\graphics\chatbubble.bmp", True) Then Call InitDDSurf("chatbubble", DDSD_ChatBubble, DDS_ChatBubble) ' CHAT BUBBLE HACK ``` **STEP 11\. On modDirectDraw7 add the following code to the DestroyDirectDraw subroutine.** Find: ``` Set DDS_BackBuffer = Nothing ``` Add the following code ABOVE that. ``` ' CHAT BUBBLE HACK Set DDS_ChatBubble = Nothing ZeroMemory ByVal VarPtr(DDSD_ChatBubble), LenB(DDSD_ChatBubble) ' CHAT BUBBLE HACK ``` **STEP 12\. on modDirectDraw7 add the following code on the Render_Graphics subroutine** Find: ``` ' Release DC DDS_BackBuffer.ReleaseDC TexthDC ``` Add the following code BELOW that: ``` ' CHAT BUBBLES HACK ' draw the messages at the very top! For i = 1 To MAX_BYTE If chatBubble(i).active Then DrawChatBubble i End If Next ' CHAT BUBBLES HACK ``` **STEP 13\. On modDirectDraw7 add the following subroutine anywhere in the module.** ``` ' CHAT BUBBLE HACK Public Sub DrawChatBubble(ByVal Index As Long) Dim theArray() As String, x As Long, Y As Long, i As Long, MaxWidth As Long, xwidth As Long, yheight As Long, colour As Long, x3 As Long, y3 As Long Dim MMx As Long Dim MMy As Long Dim TOPLEFTrect As RECT Dim TOPCENTERrect As RECT Dim TOPRIGHTrect As RECT Dim MIDDLELEFTrect As RECT Dim MIDDLECENTERrect As RECT Dim MIDDLERIGHTrect As RECT Dim BOTTOMLEFTrect As RECT Dim BOTTOMCENTERrect As RECT Dim BOTTOMRIGHTrect As RECT Dim TIPrect As RECT ' DESIGNATE CHATBUBBLE SECTIONS FROM CHATBUBBLE IMAGE With TOPRIGHTrect .top = 0 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4 End With With TOPCENTERrect .top = 0 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4 End With With TOPLEFTrect .top = 0 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4 End With With MIDDLERIGHTrect .top = 4 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4 End With With MIDDLECENTERrect .top = 4 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4 End With With MIDDLELEFTrect .top = 4 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4 End With With BOTTOMRIGHTrect .top = 8 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4 End With With BOTTOMCENTERrect .top = 8 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4 End With With BOTTOMLEFTrect .top = 8 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4 End With With TIPrect .top = 12 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4 End With Call DDS_BackBuffer.SetForeColor(RGB(255, 255, 255)) With chatBubble(Index) If .targetType = TARGET_TYPE_PLAYER Then ' it's a player If GetPlayerMap(.target) = GetPlayerMap(MyIndex) Then ' change the colour depending on access colour = QBColor(Yellow) ' it's on our map - get co-ords x = ConvertMapX((Player(.target).x * 32) + Player(.target).XOffset) + 16 Y = ConvertMapY((Player(.target).Y * 32) + Player(.target).YOffset) - 16 ' word wrap the text WordWrap_Array .Msg, ChatBubbleWidth, theArray ' find max width For i = 1 To UBound(theArray) If getWidth(TexthDC, theArray(i)) > MaxWidth Then MaxWidth = getWidth(TexthDC, theArray(i)) Next ' calculate the new position xwidth relative to DDS_ChatBubble and yheight relative to DDS_ChatBubble xwidth = 10 + MaxWidth ' the first five is just air. yheight = 3 + (UBound(theArray) * 7) ' the first three are just air. ' Compensate the yheight drift Y = Y - yheight ' render bubble ' top left ' RenderTexture Tex_GUI(37), xwidth - 9, yheight - 5, 0, 0, 9, 5, 9, 5 Call Engine_BltFast(x + (xwidth + 4), Y - (yheight - 4), DDS_ChatBubble, TOPLEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' top center ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, yheight - 5, 119, 0, 9, 5, 9, 5 For x3 = x - (xwidth - 8) To x + (xwidth) Call Engine_BltFast(x3, Y - (yheight - 4), DDS_ChatBubble, TOPCENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next x3 ' top right ' RenderTexture Tex_GUI(37), xwidth, yheight - 5, 9, 0, MaxWidth, 5, 5, 5 Call Engine_BltFast(x - (xwidth - 4), Y - (yheight - 4), DDS_ChatBubble, TOPRIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' middle left ' RenderTexture Tex_GUI(37), xwidth - 9, y, 0, 19, 9, 6, 9, 6 For y3 = Y - (yheight - 8) To Y + (yheight) Call Engine_BltFast(x + (xwidth + 4), y3, DDS_ChatBubble, MIDDLELEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next y3 ' middle center ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, y, 119, 19, 9, 6, 9, 6 For y3 = Y - (yheight - 8) To Y + (yheight) For x3 = x - (xwidth - 8) To x + (xwidth) Call Engine_BltFast(x3, y3, DDS_ChatBubble, MIDDLECENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next x3 Next y3 ' middle right ' RenderTexture Tex_GUI(37), xwidth, y, 9, 19, (MaxWidth \ 2) - 5, 6, 9, 6 For y3 = Y - (yheight - 8) To Y + (yheight) Call Engine_BltFast(x - (xwidth - 4), y3, DDS_ChatBubble, MIDDLERIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next y3 ' bottom left ' RenderTexture Tex_GUI(37), xwidth + (MaxWidth \ 2) + 6, y, 9, 19, (MaxWidth \ 2) - 5, 6, 9, 6 Call Engine_BltFast(x + (xwidth + 4), Y + (yheight + 4), DDS_ChatBubble, BOTTOMLEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' bottom center ' RenderTexture Tex_GUI(37), xwidth - 9, yheight, 0, 6, 9, (UBound(theArray) * 12), 9, 1 For x3 = x - (xwidth - 8) To x + (xwidth) Call Engine_BltFast(x3, Y + (yheight + 4), DDS_ChatBubble, BOTTOMCENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) Next x3 ' bottom right ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, yheight, 119, 6, 9, (UBound(theArray) * 12), 9, 1 Call Engine_BltFast(x - (xwidth - 4), Y + (yheight + 4), DDS_ChatBubble, BOTTOMRIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' little pointy bit ' RenderTexture Tex_GUI(37), x - 5, y, 58, 19, 11, 11, 11, 11 Call Engine_BltFast(x, Y + (yheight + 8), DDS_ChatBubble, TIPrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) ' Lock the backbuffer so we can draw text and names TexthDC = DDS_BackBuffer.GetDC ' render each line centralised Y = Y - (yheight - 5) For i = 1 To UBound(theArray) DrawTextNoShadow TexthDC, x - (getWidth(TexthDC, theArray(i)) - 10), Y, theArray(i), QBColor(Black) ' .colour Y = Y + 12 Next ' Release DC DDS_BackBuffer.ReleaseDC TexthDC End If End If ' check if it's timed out - close it if so If .Timer + 5000 < GetTickCount Then .active = False End If End With End Sub ' CHAT BUBBLE HACK ``` And we're done! _**WARNING: I ADDED A DRAWTEXTNOSHADOW FUNCTION ~~COZ~~ BECAUSE THE CHATBUBBLE TEXT LOOKS BETTER WITHOUT SHADOW OVER WHITE BUBBLES! IF YOU HAVE NOT APPLIED THE FONT MEMORY LEAK FIX YOU'LL NEED TO DO SO OTHERWISE THIS ROUTINE WILL FAIL!**_ The How's and Why's… On the server side we did the following create a new package so we can send it to the client whenever we'll fire a message from a user into the map (handled by HandleSayMsg subroutine), and the function that sends this package and the message to the client. On the client side we created a new package so we can understand the server, created a Direct Draw Surface named BubbleChat where we'll do the drawing and texting. Added a couple constants so we know the chat bubble size and for compatibility with a function that expects a font name. Added a Chat bubble rec type, where we store message, player that owns it, color, etc. Added a function that handles the reception of the bubble chat package. Added a routine to add a new bubble if it does not exist or recycle an old bubble. Modified the rendering routine to add for the call to the chatboxes if they're active Added a function to split the length of the message to fit in 200 pixels which we said it was our biggest chat bubble. ~~This one deserves extra attention, since I didn't know how replicate the EngineGetTextWidth function on DD7 (yet!) the Word Wrapper routines would not work. So I build a routine named LetterWidth and this routine will provide an "estimate" pixel size per character (by default I set it to 4 pixels per letter) for characters that are "slim" like ": | ' , . : ;" etc… the bubble size is not 100% accurate, so you might want to build a better map of character sizes for it to be more precise...~~ Added the getWidth function, which uses the textwidth function on the main form to calculate the size of the text, and then just splits that value in half to get a center, I believe you can actually tweak it to be more precise if you specify the form font to match the font you'll be using in your chatbubbles, but I leave that to you. Then added a draw the chat bubbles function that takes a tile, chops it in to 10 pieces each comprising a a side of the bubble, the center and the little tip of it. Each section of the chat bubble is a 4x4 pixel piece, you may modify this by changing the size and then the respective RECTs and recalculate your positions accordingly. And finally added a function that draws text without a shadow so that black text won't look funky with black shadow. And thats it! If you have any questions I'll be happy to try and respond them (provided you give me enough information and not just say "it does not work for me"), and if you run into some problems I'll do my best to assist, but **be reminded this tutorial is delivered AS-IS… it might not work for you, but if you tweak it enough it just might.** Cheers!
  24. I got it! :D I was locking the draw surface for text render and attempted to draw on it, so that didn't budge! It was a tough exercise, specially because I know jack of DD7, and in the end I could not replicate the EngineGetTextWidth function built from DD8 (I never figured out a way to get DD7 to give me back the relative width of each character), so I build a map of my own :P and round up the rest. I know its lame… but functional! Cheers! :)
  25. Hello Eclipse Community, Here is the deal, I'm building a small game in my spare time (ain't we all) to play with my D&D friends and I'd like to add a few extra things to the EO 2.0 engine (like we all do). Things that altho might be simple for the seasoned programmer that knows the code require programming skills for DirectDraw that just elude me. While I've studied and applied half a dozen tutorials shared by cool people in this forums I decided to tackle a bigger challenge… Acquiring the unattainable CrystalShire bubble chat on EO. So yeah, I went and got me a copy of the Robin's CS source code, studied it and I got all that I need it out of it, the packets, the handlers, the functions, and applied it to EO. It all works flawlessly until I get to the call for the dreaded ChatBubbleDraw function... I get the text to pop up and dissapear, like the chat bubble would do... but the drawing of the chat bubble itself simply is not budging! :( As I said, in my limited DD7 knowledge I also made an effort to render the chat bubble (via the Engine_BltFast), I tried to put together the lessons I've learned on many tutorials and even tried my best to downgrade the DD8 code to DD7, but I just hit a mental dead end... And no bubble shows up! So rather than bang my head on a wall for weeks on end looking for all the wrong ways to make this work I'm willing to pay someone some money to take a look at the code I got and not only fix it and tell me where I ducked up, but to also to teach me the DD7 things I don't understand. So if there are any serious takers out there, you have some spare time, the knowledge, the patience and a reasonable price I'd love to hear from you. Cheers!
×
×
  • Create New...