Automatic layering system
From VbGORE Visual Basic Online RPG Engine
This was originally part of an upgrade (Version 1.1.0 to be specific), but was omitted due to the complications it would bring to the typical user, and the amount that vbGORE would have to be altered to make it work (such as the help, GUIs, etc).
Contents |
[edit] Pros and Cons
Pros:
- Automatic layering - The layers are decided based on the Y axis along with the height of the Grh. This prevents having to break up certain graphics (like trees) into "behind" and "front" parts.
- Faster mapping - Because you don't have to worry about the layers as much, you will be able to map a lot faster.
- Less Grhs - There will be less Grhs because you won't have to break them into multiple parts.
Cons:
- Automatic layering - This is also a con, since you have to hope the automatic layering gives you what you want. If it does not, you have to do some cheap hacks to get it to work.
- Remake maps - Since the maps work completely different, you will have to remake them all.
[edit] How it works
Here is a copy-and-paste from the original entry in the upgrade guide:
"Added a new rendering system. How this system works is instead of what is drawn being decided on what layer the Grh is on, there are three tile types. These types are always below (layer 1 and 2), mixed (layer 3 to 5) and always above (layer 6). The always below is used for the ground tiles. Mixed is used for anything that has depth - trees, buildings, chairs, etc. Layer 6 is used for special cases, like birds or clouds, though it is not a very common type to have to use, which is why there is only one layer for it. The mixed layer works by sorting on a pseudo-Z axis calculated by the Y + Height of a Grh. This algorithm is also applied to particle effects (ie bless), Grh effects (ie Spike Field), characters (NPCs and PCs both), blood splatters (from when you hit a NPC / get hit) and projectiles (ie Ninja Star). Because of this new system, previously made maps will not function correctly. Though, you no longer have to split up your trees and have part of it on layer 2/3 and the other part on layer 4/5 just so you can walk in front of it and stand behind it, as the engine will do this for you. This also fixes a lot of issues with putting the shadows on these Grhs, since they are now just one Grh, so they cast just one shadow. For those who are worried about performance, there was no FPS drop when tested against ~500 Grhs on layer 3-5, so performance is not a concern."
[edit] Adding guide
Follow this guide just like you would any other upgrade guide, since this is how it was written (which is why it is in 3 parts). Start with the last on the end of the page, and move up to the first.
[edit] Fix - Animations
Open GameClient.vbp.
In module TileEngine, add:
Public Function Engine_GetFrameFromGrh(Grh As Grh) As Long '************************************************************ 'Get a Grh and return the frame (useful for animations) '************************************************************ Dim i As Long 'Check for a valid GrhIndex If Grh.GrhIndex < 1 Then Exit Function If Grh.GrhIndex > NumGrhs Then Exit Function 'Round down on the frame counter i = Int(Grh.FrameCounter) 'Check for a frame count overflow If i > GrhData(Grh.GrhIndex).NumFrames Then Exit Function 'Return the Grh index Engine_GetFrameFromGrh = GrhData(Grh.GrhIndex).Frames(Int(Grh.FrameCounter)) End Function
Find:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, BloodList(j).Grh.GrhIndex, X, Y, _ Y + GrhData(BloodList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, 0, 1, 0
Replace with:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, Engine_GetFrameFromGrh(BloodList(j).Grh), X, Y, _ Y + GrhData(BloodList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, 0, 1, 0
Find:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, OBJList(j).Grh.GrhIndex, X, Y, _ Y + GrhData(OBJList(j).Grh.GrhIndex).pixelHeight, .Light(1), .Light(2), .Light(3), .Light(4), 0, 1, 1
Replace with:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, Engine_GetFrameFromGrh(OBJList(j).Grh), X, Y, _ Y + GrhData(OBJList(j).Grh.GrhIndex).pixelHeight, .Light(1), .Light(2), .Light(3), .Light(4), 0, 1, 1
Find:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, MapData(.TileX, .TileY).Graphic(Layer).GrhIndex, _ .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, .PixelPosY + PixelOffsetY + _ GrhData(MapData(.TileX, .TileY).Graphic(Layer).GrhIndex).pixelHeight, MapData(.TileX, .TileY).Light(1), _ MapData(.TileX, .TileY).Light(2), MapData(.TileX, .TileY).Light(3), MapData(.TileX, .TileY).Light(4), _ 0, 0, MapData(.TileX, .TileY).Shadow(Layer)
Replace with:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, Engine_GetFrameFromGrh(MapData(.TileX, .TileY).Graphic(Layer)), _ .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, .PixelPosY + PixelOffsetY + _ GrhData(MapData(.TileX, .TileY).Graphic(Layer).GrhIndex).pixelHeight, MapData(.TileX, .TileY).Light(1), _ MapData(.TileX, .TileY).Light(2), MapData(.TileX, .TileY).Light(3), MapData(.TileX, .TileY).Light(4), _ 0, 0, MapData(.TileX, .TileY).Shadow(Layer)
Find:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, GrhData(EffectList(j).Grh.GrhIndex).Frames(Int(EffectList(j).Grh.FrameCounter)), X, Y, _ Y + GrhData(EffectList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, EffectList(j).Angle, 0, 1
Replace with:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, Engine_GetFrameFromGrh(EffectList(j).Grh), X, Y, _ Y + GrhData(EffectList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, EffectList(j).Angle, 0, 1
Find:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, ProjectileList(j).Grh.GrhIndex, _ X, Y, Y + GrhData(ProjectileList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, ProjectileList(j).Rotate, 0, 1
Replace with:
Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, Engine_GetFrameFromGrh(ProjectileList(j).Grh), _ X, Y, Y + GrhData(ProjectileList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, ProjectileList(j).Rotate, 0, 1
Open EditorMap.vbp.
In module TileEngine, add:
Public Function Engine_GetFrameFromGrh(Grh As Grh) As Long '************************************************************ 'Get a Grh and return the frame (useful for animations) '************************************************************ Dim i As Long 'Check for a valid GrhIndex If Grh.GrhIndex < 1 Then Exit Function If Grh.GrhIndex > NumGrhs Then Exit Function 'Round down on the frame counter i = Int(Grh.FrameCounter) 'Check for a frame count overflow If i > GrhData(Grh.GrhIndex).NumFrames Then Exit Function 'Return the Grh index Engine_GetFrameFromGrh = GrhData(Grh.GrhIndex).Frames(Int(Grh.FrameCounter)) End Function
Find:
'************** Layer 3 to 5 ************** For Layer = 3 To 5 LightOffset = ((Layer - 1) * 4) + 1 For j = 1 To TileLayer(Layer).NumTiles With TileLayer(Layer).Tile(j) Engine_UpdateGrh MapData(.TileX, .TileY).Graphic(Layer), True Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, MapData(.TileX, .TileY).Graphic(Layer).GrhIndex, _ .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, .PixelPosY + PixelOffsetY + _ GrhData(MapData(.TileX, .TileY).Graphic(Layer).GrhIndex).pixelHeight, MapData(.TileX, .TileY).Light(1), _ MapData(.TileX, .TileY).Light(2), MapData(.TileX, .TileY).Light(3), MapData(.TileX, .TileY).Light(4), _ 0, 0, MapData(.TileX, .TileY).Shadow(Layer) End With Next j Next Layer
Replace with:
'************** Layer 2 to 5 ************** For Layer = 2 To 5 LightOffset = ((Layer - 1) * 4) + 1 For j = 1 To TileLayer(Layer).NumTiles With TileLayer(Layer).Tile(j) Engine_UpdateGrh MapData(.TileX, .TileY).Graphic(Layer), True Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, Engine_GetFrameFromGrh(MapData(.TileX, .TileY).Graphic(Layer)), _ .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, .PixelPosY + PixelOffsetY + _ GrhData(MapData(.TileX, .TileY).Graphic(Layer).GrhIndex).pixelHeight, MapData(.TileX, .TileY).Light(LightOffset), _ MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3), _ 0, 0, MapData(.TileX, .TileY).Shadow(Layer) End With Next j Next Layer
[edit] Fix - Effect rendering
Open GameClient.vbp.
Find:
'************** Grh-Based (Non-Particle) Effects **************
Replace the block of code (from For j = ... to Next j) with:
'************** Grh-Based (Non-Particle) Effects ************** For j = 1 To LastEffect If EffectList(j).Grh.GrhIndex Then X = Engine_PixelPosX(EffectList(j).Pos.X - minX) + PixelOffsetX + TileBufferOffset Y = Engine_PixelPosY(EffectList(j).Pos.Y - minY) + PixelOffsetY + TileBufferOffset 'Time ran out If EffectList(j).Time <> 0 And EffectList(j).Time < timeGetTime Then Engine_Effect_Erase j 'Draw the effect ElseIf Y >= -32 And Y <= (ScreenHeight + 32) And X >= -32 And X <= (ScreenWidth + 32) Then Engine_UpdateGrh EffectList(j).Grh, False If EffectList(j).Animated = 1 Then If EffectList(j).Grh.Started = 0 Then Engine_Effect_Erase j GoTo NextEffect End If End If If EffectList(j).Grh.FrameCounter >= 1 Then If Int(EffectList(j).Grh.FrameCounter) <= GrhData(EffectList(j).Grh.GrhIndex).NumFrames Then Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, GrhData(EffectList(j).Grh.GrhIndex).Frames(Int(EffectList(j).Grh.FrameCounter)), X, Y, _ Y + GrhData(EffectList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, EffectList(j).Angle, 0, 1 End If End If 'Update but not draw Else Engine_UpdateGrh EffectList(j).Grh, False If EffectList(j).Animated = 1 Then If EffectList(j).Grh.Started = 0 Then Engine_Effect_Erase j End If End If End If NextEffect: Next j
[edit] Add - New rendering system
Open \Data\Head.dat.
At the end of the file, add:
'The height is used in the calculation of the overall height of the character for finding the drawing order. 'This is simply just the height of the graphic - the Grh's height is not used because it is often not the 'exact height of the graphic. The height of the head and body are added together. If you have any other 'height contributors (such as large head-wear) I recommend you add height to that layer, too. Height=27
Open \Data\Body.dat.
Find:
[2]
Before, add:
'The height is used in the calculation of the overall height of the character for finding the drawing order. 'This is simply just the height of the graphic - the Grh's height is not used because it is often not the 'exact height of the graphic. The height of the head and body are added together. If you have any other 'height contributors (such as large head-wear) I recommend you add height to that layer, too. Height=34
At the end of the file, add:
Height=34
Open GameClient.vbp.
Find:
Private ChatVA() As TLVERTEX
After, add:
'Render list - used to sort the list of graphics before rendering them Private Type RenderList X As Long Y As Long Z As Integer 'The value used to sort by (Y + Height) Grh As Long Light(0 To 3) As Long Center As Byte Shadow As Byte Angle As Single CharIndex As Long 'If it is a character, this is its index ParticleEffectIndex As Byte 'If it is a particle effect, this is its index End Type
Find:
'Bodies list Public Type BodyData Walk(1 To 8) As Grh Attack(1 To 8) As Grh HeadOffset As Position End Type
Replace with:
'Bodies list Public Type BodyData Walk(1 To 8) As Grh Attack(1 To 8) As Grh HeadOffset As Position Height As Long End Type
Find:
Public Type HeadData Head(1 To 8) As Grh Blink(1 To 8) As Grh AgrHead(1 To 8) As Grh AgrBlink(1 To 8) As Grh End Type
Replace with:
'Heads list Public Type HeadData Head(1 To 8) As Grh Blink(1 To 8) As Grh AgrHead(1 To 8) As Grh AgrBlink(1 To 8) As Grh Height As Long End Type
Find:
BodyData(LoopC).HeadOffset.Y = CLng(Var_Get(DataPath & "Body.dat", LoopC, "HeadOffsetY"))
After, add:
BodyData(LoopC).Height = CLng(Var_Get(DataPath & "Body.dat", LoopC, "Height"))
Find:
'Fill List For LoopC = 1 To NumHeads For i = 1 To 8 Engine_Init_Grh HeadData(LoopC).Head(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, i)), 0 Engine_Init_Grh HeadData(LoopC).Blink(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, "b" & i)), 0 Engine_Init_Grh HeadData(LoopC).AgrHead(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, "a" & i)), 0 Engine_Init_Grh HeadData(LoopC).AgrBlink(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, "ab" & i)), 0 Next i Next LoopC
Replace with:
'Fill List For LoopC = 1 To NumHeads For i = 1 To 8 Engine_Init_Grh HeadData(LoopC).Head(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, i)), 0 Engine_Init_Grh HeadData(LoopC).Blink(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, "b" & i)), 0 Engine_Init_Grh HeadData(LoopC).AgrHead(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, "a" & i)), 0 Engine_Init_Grh HeadData(LoopC).AgrBlink(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, "ab" & i)), 0 Next i HeadData(LoopC).Height = CLng(Var_Get(DataPath & "Head.dat", LoopC, "Height")) Next LoopC
Find:
Engine_Init_Grh HeadData(LoopC).AgrBlink(i), CLng(Var_Get(DataPath & "Head.dat", LoopC, "ab" & i)), 0
After, add:
HeadData(LoopC).Height = CLng(Var_Get(DataPath & "Head.dat", LoopC, "Height"))
Find:
'Grh has a delay, so just update the frame and then leave
Engine_UpdateGrh Grh, LoopAnim
Replace with:
'Grh has a delay, so just update the frame and then leave If Animate Then Engine_UpdateGrh Grh, LoopAnim
At the end of the TileEngine module, add:
Private Sub Engine_AddToRenderList_Char(ByRef RenderList() As RenderList, ByRef RenderListSize As Long, ByRef Index As Long, _ ByVal CharIndex As Long, ByVal X As Long, ByVal Y As Long, ByVal Z As Integer) '***************************************************************** 'Adds a character to the RenderList() 'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_AddToRenderList_Char '***************************************************************** 'Increase the index Index = Index + 1 'Increase array size if needed If Index > RenderListSize Then RenderListSize = RenderListSize + 50 ReDim Preserve RenderList(1 To RenderListSize) End If 'Add the components With RenderList(Index) .CharIndex = CharIndex .X = X .Y = Y .Z = Z End With End Sub Private Sub Engine_AddToRenderList_PE(ByRef RenderList() As RenderList, ByRef RenderListSize As Long, ByRef Index As Long, _ ByVal ParticleEffectIndex As Long, ByVal Z As Integer) '***************************************************************** 'Adds a Particle Effect to the RenderList() 'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_AddToRenderList_PE '***************************************************************** 'Increase the index Index = Index + 1 'Increase array size if needed If Index > RenderListSize Then RenderListSize = RenderListSize + 50 ReDim Preserve RenderList(1 To RenderListSize) End If 'Add the components With RenderList(Index) .ParticleEffectIndex = ParticleEffectIndex .Z = Z End With End Sub Private Sub Engine_AddToRenderList_Grh(ByRef RenderList() As RenderList, ByRef RenderListSize As Long, ByRef Index As Long, _ ByVal Grh As Long, ByVal X As Long, ByVal Y As Long, ByVal Z As Integer, ByVal Light0 As Long, ByVal Light1 As Long, ByVal Light2 As Long, _ ByVal Light3 As Long, ByVal Angle As Single, ByVal Center As Byte, ByVal Shadow As Byte) '***************************************************************** 'Adds a Grh (such as a tile, Grh-based effect, projectile, etc) to the RenderList() 'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_AddToRenderList_Grh '***************************************************************** 'Increase the index Index = Index + 1 'Increase array size if needed If Index > RenderListSize Then RenderListSize = RenderListSize + 50 ReDim Preserve RenderList(1 To RenderListSize) End If 'Add the components With RenderList(Index) .Angle = Angle .Center = Center .Grh = Grh .Light(0) = Light0 .Light(1) = Light1 .Light(2) = Light2 .Light(3) = Light3 .Shadow = Shadow .X = X .Y = Y .Z = Z End With End Sub
Find:
Sub Engine_Render_Screen(ByVal TileX As Integer, ByVal TileY As Integer, ByVal PixelOffsetX As Integer, ByVal PixelOffsetY As Integer)
Replace sub with:
Sub Engine_Render_Screen(ByVal TileX As Integer, ByVal TileY As Integer, ByVal PixelOffsetX As Integer, ByVal PixelOffsetY As Integer) '************************************************************ 'Draw current visible to scratch area based on TileX and TileY 'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_Render_Screen '************************************************************ Dim RenderList() As RenderList Dim RenderListSize As Long Dim RenderListIndex As Long Dim FrameUseMotionBlur As Boolean 'Lets us know if this frame is using motion blur so we don't have to leave support for it on Dim LightOffset As Long Dim Y As Long 'Keeps track of where on map we are Dim X As Long Dim j As Long Dim Angle As Single Dim Layer As Byte Dim pList() As Integer Dim ValueList() As Integer Dim TempGrh As Grh 'Check for valid positions If UserPos.X = 0 Then Exit Sub If UserPos.Y = 0 Then Exit Sub If UserCharIndex = 0 Then Exit Sub 'Check if we need to update the graphics If TileX <> LastTileX Or TileY <> LastTileY Then 'Figure out Ends and Starts of screen ScreenMinY = TileY - (WindowTileHeight \ 2) ScreenMaxY = TileY + (WindowTileHeight \ 2) ScreenMinX = TileX - (WindowTileWidth \ 2) ScreenMaxX = TileX + (WindowTileWidth \ 2) minY = ScreenMinY - TileBufferSize maxY = ScreenMaxY + TileBufferSize minX = ScreenMinX - TileBufferSize maxX = ScreenMaxX + TileBufferSize 'Update the last position LastTileX = TileX LastTileY = TileY 'Re-create the tile layers Engine_CreateTileLayers End If 'Calculate the particle offset values 'Do NOT move this any farther down in the module or you will get "jumps" as the left/top borders on particles ParticleOffsetX = (Engine_PixelPosX(ScreenMinX) - PixelOffsetX) ParticleOffsetY = (Engine_PixelPosY(ScreenMinY) - PixelOffsetY) 'Check if we have the device If D3DDevice.TestCooperativeLevel <> D3D_OK Then 'The worst we can do at this point is avoid an error we can't fix! On Error Resume Next 'Do a loop while device is lost If D3DDevice.TestCooperativeLevel = D3DERR_DEVICELOST Then Exit Sub 'Clear all the textures LastTexture = -999 For j = 1 To NumGrhFiles Set SurfaceDB(j) = Nothing SurfaceTimer(j) = 0 SurfaceSize(j).X = 0 SurfaceSize(j).Y = 0 Next j 'Clear the D3DXSprite If AlternateRenderDefault = 1 Or AlternateRenderMap = 1 Or AlternateRenderText = 1 Then SpriteBegun = 0 Set Sprite = Nothing Set Sprite = D3DX.CreateSprite(D3DDevice) End If Set DeviceBuffer = Nothing Set DeviceStencil = Nothing Set BlurStencil = Nothing Set BlurTexture = Nothing Set BlurSurf = Nothing 'Make sure the scene is ended D3DDevice.EndScene 'Reset the device D3DDevice.Reset D3DWindow Set DeviceBuffer = D3DDevice.GetRenderTarget Set DeviceStencil = D3DDevice.GetDepthStencilSurface Set BlurStencil = D3DDevice.CreateDepthStencilSurface(BufferWidth, BufferHeight, D3DFMT_D16, D3DMULTISAMPLE_NONE) Set BlurTexture = D3DX.CreateTexture(D3DDevice, BufferWidth, BufferHeight, 0, D3DUSAGE_RENDERTARGET, DispMode.Format, D3DPOOL_DEFAULT) Set BlurSurf = BlurTexture.GetSurfaceLevel(0) 'Reset the render states Engine_Init_RenderStates 'Load the particle textures Engine_Init_ParticleEngine True On Error GoTo 0 Else 'We have to bypass the present the first time through here or else we get an error If NotFirstRender Then 'Close off the last sprite If SpriteBegun Then Sprite.End SpriteBegun = 0 LastTexture = -101 End If With D3DDevice 'End the rendering (scene) .EndScene 'Flip the backbuffer to the screen .Present ByVal 0, ByVal 0, 0, ByVal 0 End With Else 'Set NotFirstRender to True so we can start displaying NotFirstRender = True End If End If 'Check if running (turn on motion blur) If UseMotionBlur Then If UserCharIndex > 0 Then If CharList(UserCharIndex).Moving = 1 And CharList(UserCharIndex).Running Then BlurIntensity = 45 Else If BlurIntensity < 255 Then BlurIntensity = BlurIntensity + (ElapsedTime * 0.8) If BlurIntensity > 255 Then BlurIntensity = 255 End If End If End If End If 'Set the motion blur if needed If UseMotionBlur Then If BlurIntensity < 255 Or ZoomLevel > 0 Then FrameUseMotionBlur = True D3DDevice.SetRenderTarget BlurSurf, BlurStencil, 0 End If End If 'Begin the scene D3DDevice.BeginScene 'Clear the screen with a solid color (to prevent artifacts) D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, 0, 1#, 0 '******************************************************** '************ Update and draw layer 1 and 2 ************* '******************************************************** 'Set the alternate rendering for the map on / off AlternateRender = AlternateRenderMap 'Loop through the lower 2 layers For Layer = 1 To 2 LightOffset = ((Layer - 1) * 4) + 1 'Loop through all the tiles we know we will draw for this layer For j = 1 To TileLayer(Layer).NumTiles With TileLayer(Layer).Tile(j) Engine_UpdateGrh MapData(.TileX, .TileY).Graphic(Layer) 'Check if we have to draw with a shadow or not (slighty changes because we have to animate on the shadow, not the main render) If MapData(.TileX, .TileY).Shadow(Layer) = 1 Then Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1 Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 0, True, MapData(.TileX, .TileY).Light(LightOffset), MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3) Else Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 1, True, MapData(.TileX, .TileY).Light(LightOffset), MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3) End If End With Next j Next Layer 'Set the alternate rendering back to what it was before AlternateRender = AlternateRenderDefault '******************************************************** '********** Update and draw the ground objects ********** '******************************************************** For j = 1 To LastObj If OBJList(j).Grh.GrhIndex Then X = Engine_PixelPosX(OBJList(j).Pos.X - minX) + PixelOffsetX + OBJList(j).Offset.X + TileBufferOffset Y = Engine_PixelPosY(OBJList(j).Pos.Y - minY) + PixelOffsetY + OBJList(j).Offset.Y + TileBufferOffset If Y >= -32 Then If Y <= (ScreenHeight + 32) Then If X >= -32 Then If X <= (ScreenWidth + 32) Then Engine_UpdateGrh OBJList(j).Grh, True With MapData(OBJList(j).Pos.X, OBJList(j).Pos.Y) Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, OBJList(j).Grh.GrhIndex, X, Y, _ Y + GrhData(OBJList(j).Grh.GrhIndex).pixelHeight, .Light(1), .Light(2), .Light(3), .Light(4), 0, 1, 1 End With End If End If End If End If End If Next j '******************************************************** '****** Start storing graphics in the RenderList() ****** '****** so it can be sorted by their Y co-ordinate ****** '******************************************************** '************** Characters ************** For j = 1 To LastChar If CharList(j).Active Then X = Engine_PixelPosX(CharList(j).Pos.X - minX) + PixelOffsetX + TileBufferOffset Y = Engine_PixelPosY(CharList(j).Pos.Y - minY) + PixelOffsetY + TileBufferOffset If Y >= -32 And Y <= (ScreenHeight + 32) And X >= -32 And X <= (ScreenWidth + 32) Then 'Update the NPC chat and draw the character Engine_NPCChat_Update j Engine_AddToRenderList_Char RenderList(), RenderListSize, RenderListIndex, j, X, Y, _ Y + CharList(j).Body.Height + CharList(j).Head.Height Else 'Update just the real position CharList(j).RealPos.X = X + CharList(j).MoveOffset.X CharList(j).RealPos.Y = Y + CharList(j).MoveOffset.Y End If End If Next j '************** Layer 3 to 5 ************** AlternateRender = AlternateRenderMap For Layer = 3 To 5 LightOffset = ((Layer - 1) * 4) + 1 For j = 1 To TileLayer(Layer).NumTiles With TileLayer(Layer).Tile(j) Engine_UpdateGrh MapData(.TileX, .TileY).Graphic(Layer), True Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, MapData(.TileX, .TileY).Graphic(Layer).GrhIndex, _ .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, .PixelPosY + PixelOffsetY + _ GrhData(MapData(.TileX, .TileY).Graphic(Layer).GrhIndex).pixelHeight, MapData(.TileX, .TileY).Light(1), _ MapData(.TileX, .TileY).Light(2), MapData(.TileX, .TileY).Light(3), MapData(.TileX, .TileY).Light(4), _ 0, 0, MapData(.TileX, .TileY).Shadow(Layer) End With Next j Next Layer AlternateRender = AlternateRenderDefault '************** Grh-Based (Non-Particle) Effects ************** For j = 1 To LastEffect If EffectList(j).Grh.GrhIndex Then X = Engine_PixelPosX(EffectList(j).Pos.X - minX) + PixelOffsetX + TileBufferOffset Y = Engine_PixelPosY(EffectList(j).Pos.Y - minY) + PixelOffsetY + TileBufferOffset 'Time ran out If EffectList(j).Time <> 0 And EffectList(j).Time < timeGetTime Then Engine_Effect_Erase j 'Draw the effect ElseIf Y >= -32 And Y <= (ScreenHeight + 32) And X >= -32 And X <= (ScreenWidth + 32) Then Engine_UpdateGrh EffectList(j).Grh, False If EffectList(j).Animated = 1 Then If EffectList(j).Grh.Started = 0 Then Engine_Effect_Erase j End If Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, EffectList(j).Grh.GrhIndex, X, Y, _ Y + GrhData(EffectList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, EffectList(j).Angle, 0, 1 'Update but not draw Else Engine_UpdateGrh EffectList(j).Grh, False If EffectList(j).Animated = 1 Then If EffectList(j).Grh.Started = 0 Then Engine_Effect_Erase j End If End If End If Next j '************** Projectiles ************** 'Check if it is close enough to the target to remove For j = 1 To LastProjectile If ProjectileList(j).Grh.GrhIndex Then If Abs(ProjectileList(j).X - ProjectileList(j).tX) < 20 Then If Abs(ProjectileList(j).Y - ProjectileList(j).tY) < 20 Then Engine_Projectile_Erase j End If End If End If Next j For j = 1 To LastProjectile If ProjectileList(j).Grh.GrhIndex Then 'Update the position Angle = DegreeToRadian * Engine_GetAngle(ProjectileList(j).X, ProjectileList(j).Y, ProjectileList(j).tX, ProjectileList(j).tY) ProjectileList(j).X = ProjectileList(j).X + (Sin(Angle) * ElapsedTime * 0.63) ProjectileList(j).Y = ProjectileList(j).Y - (Cos(Angle) * ElapsedTime * 0.63) 'Update the rotation If ProjectileList(j).RotateSpeed > 0 Then ProjectileList(j).Rotate = ProjectileList(j).Rotate + (ProjectileList(j).RotateSpeed * ElapsedTime * 0.01) Do While ProjectileList(j).Rotate > 360 ProjectileList(j).Rotate = ProjectileList(j).Rotate - 360 Loop End If 'Draw if within range X = ((-minX - 1) * 32) + ProjectileList(j).X + PixelOffsetX + TileBufferOffset Y = ((-minY - 1) * 32) + ProjectileList(j).Y + PixelOffsetY + TileBufferOffset If Y >= -32 Then If Y <= (ScreenHeight + 32) Then If X >= -32 Then If X <= (ScreenWidth + 32) Then Engine_UpdateGrh ProjectileList(j).Grh, True Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, ProjectileList(j).Grh.GrhIndex, _ X, Y, Y + GrhData(ProjectileList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, ProjectileList(j).Rotate, 0, 1 End If End If End If End If End If Next j '************** Blood Splatters ************** 'Seperate loop to remove the unused - I dont like removing while drawing For j = 1 To LastBlood If BloodList(j).Grh.GrhIndex Then If BloodList(j).Grh.Started = 0 Then Engine_Blood_Erase j End If Next j 'Loop to do drawing For j = 1 To LastBlood If BloodList(j).Grh.GrhIndex Then X = Engine_PixelPosX(BloodList(j).Pos.X - minX) + PixelOffsetX + TileBufferOffset Y = Engine_PixelPosY(BloodList(j).Pos.Y - minY) + PixelOffsetY + TileBufferOffset If Y >= -32 Then If Y <= (ScreenHeight + 32) Then If X >= -32 Then If X <= (ScreenWidth + 32) Then Engine_UpdateGrh BloodList(j).Grh, True Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, BloodList(j).Grh.GrhIndex, X, Y, _ Y + GrhData(BloodList(j).Grh.GrhIndex).pixelHeight, -1, -1, -1, -1, 0, 1, 0 End If End If End If End If End If Next j '******************************************************** '************ Sort the RenderList() by the Z ************ '*********** value then draw then all in order ********** '******************************************************** If RenderListIndex > 0 Then 'Size the array down ReDim Preserve RenderList(1 To RenderListIndex) RenderListSize = RenderListIndex 'Sort the array ReDim ValueList(1 To RenderListIndex) ReDim pList(1 To RenderListIndex) For j = 1 To RenderListIndex ValueList(j) = RenderList(j).Z pList(j) = j Next j Engine_SortIntArray ValueList(), pList(), 1, RenderListIndex Erase ValueList() 'Erase the ValueList() - we don't need it anymore 'Create a temporary Grh (one without any animations since we don't need to animate) TempGrh.FrameCounter = 1 TempGrh.LastCount = 0 TempGrh.Started = 1 'Loop through all the graphics in the RenderList() For j = 1 To RenderListIndex If RenderList(pList(j)).CharIndex > 0 Then 'Draw a character With RenderList(pList(j)) Engine_Render_Char .CharIndex, .X, .Y End With ElseIf RenderList(pList(j)).ParticleEffectIndex > 0 Then 'Draw a particle effect Effect_Update RenderList(pList(j)).ParticleEffectIndex Else 'Draw a grh With RenderList(pList(j)) TempGrh.GrhIndex = .Grh If .Shadow Then Engine_Render_Grh TempGrh, .X, .Y, .Center, 0, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1, .Angle Engine_Render_Grh TempGrh, .X, .Y, .Center, 0, False, .Light(0), .Light(1), .Light(2), .Light(3), 0, .Angle End With End If Next j 'Done with the RenderList() Erase RenderList End If '******************************************************** '********** Perform the rest of the rendering *********** '******************************************************** '************** Layer 6 ************** Layer = 6 LightOffset = ((Layer - 1) * 4) + 1 For j = 1 To TileLayer(Layer).NumTiles With TileLayer(Layer).Tile(j) Engine_UpdateGrh MapData(.TileX, .TileY).Graphic(Layer) If MapData(.TileX, .TileY).Shadow(Layer) = 1 Then Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1 Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 0, True, MapData(.TileX, .TileY).Light(LightOffset), MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3) Else Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 1, True, MapData(.TileX, .TileY).Light(LightOffset), MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3) End If End With Next j '************** Update weather ************** 'Do the general weather updating Engine_Weather_Update '************** Chat bubbles ************** 'Loop through the chars For j = 1 To LastChar If CharList(j).Active Then If LenB(CharList(j).BubbleStr) <> 0 Then If CharList(j).RealPos.X > -25 Then If CharList(j).RealPos.X < ScreenWidth + 25 Then If CharList(j).RealPos.Y > -25 Then If CharList(j).RealPos.Y < ScreenHeight + 25 Then Engine_Render_ChatBubble CharList(j).BubbleStr, CharList(j).RealPos.X, CharList(j).RealPos.Y CharList(j).BubbleTime = CharList(j).BubbleTime - ElapsedTime If CharList(j).BubbleTime <= 0 Then CharList(j).BubbleTime = 0 CharList(j).BubbleStr = vbNullString End If End If End If End If End If End If End If Next j '************** Damage text ************** 'Loop to do drawing For j = 1 To LastDamage If DamageList(j).Counter > 0 Then DamageList(j).Counter = DamageList(j).Counter - ElapsedTime X = (((DamageList(j).Pos.X - minX) - 1) * TilePixelWidth) + PixelOffsetX + TileBufferOffset Y = (((DamageList(j).Pos.Y - minY) - 1) * TilePixelHeight) + PixelOffsetY + TileBufferOffset If Y >= -32 Then If Y <= (ScreenHeight + 32) Then If X >= -32 Then If X <= (ScreenWidth + 32) Then Engine_Render_Text Font_Default, DamageList(j).Value, X, Y, D3DColorARGB(255, 255, 0, 0) End If End If End If End If DamageList(j).Pos.Y = DamageList(j).Pos.Y - (ElapsedTime * 0.001) End If Next j 'Seperate loop to remove the unused - I dont like removing while drawing For j = 1 To LastDamage If DamageList(j).Width Then If DamageList(j).Counter <= 0 Then Engine_Damage_Erase j End If Next j '************** Misc Rendering ************** 'Update and render particle effects Effect_UpdateAll 'Clear the shift-related variables LastOffsetX = ParticleOffsetX LastOffsetY = ParticleOffsetY 'Render the GUI Engine_Render_GUI '************** Mini-map ************** Const tS As Single = 3 'Size of the mini-map dots 'Check if the mini-map is being shownquit If ShowMiniMap Then 'Make sure the mini-map vertex buffer is valid If MiniMapVBSize > 0 Then 'Clear the texture LastTexture = 0 D3DDevice.SetTexture 0, Nothing 'Draw the map outline D3DDevice.SetStreamSource 0, MiniMapVB, FVF_Size D3DDevice.DrawPrimitive D3DPT_TRIANGLELIST, 0, MiniMapVBSize \ 3 'Draw the characters For X = 1 To LastChar If CharList(X).Active Then 'The user's character If X = UserCharIndex Then j = D3DColorARGB(200, 0, 255, 0) 'User's character Engine_Render_Rectangle CharList(X).Pos.X * tS, CharList(X).Pos.Y * tS, tS, tS, 1, 1, 1, 1, 1, 1, 0, 0, j, j, j, j, , False GoTo NextChar End If 'Part of the user's group or one of the user's slaves If CharList(X).CharType = ClientCharType_Grouped Or (CharList(X).CharType = ClientCharType_Slave And UserCharIndex = CharList(X).OwnerChar) Then If X <> UserCharIndex Then j = D3DColorARGB(200, 100, 220, 100) 'PC (grouped) or the user's slave Engine_Render_Rectangle CharList(X).Pos.X * tS, CharList(X).Pos.Y * tS, tS, tS, 1, 1, 1, 1, 1, 1, 0, 0, j, j, j, j, , False GoTo NextChar End If End If 'Check if the character is in screen, since the only characters drawn outside of the screen are grouped characters If CharList(X).Pos.X > ScreenMinX Then If CharList(X).Pos.X < ScreenMaxX Then If CharList(X).Pos.Y > ScreenMinY Then If CharList(X).Pos.Y < ScreenMaxY Then 'Character is a PC If CharList(X).CharType = ClientCharType_PC Then j = D3DColorARGB(200, 0, 255, 255) 'PC (not grouped) 'Character is a NPC Else j = D3DColorARGB(200, 0, 150, 150) 'NPC End If 'Any character but one part of the user's group Engine_Render_Rectangle CharList(X).Pos.X * tS, CharList(X).Pos.Y * tS, tS, tS, 1, 1, 1, 1, 1, 1, 0, 0, j, j, j, j, , False End If End If End If End If End If NextChar: Next X End If End If 'Show FPS Engine_Render_Text Font_Default, "FPS: " & FPS, ScreenWidth - 80, 2, -1 'Check if using motion blur / zooming If UseMotionBlur Then If FrameUseMotionBlur Then With D3DDevice 'Perform the zooming calculations ' * 1.333... maintains the aspect ratio ' ... / 1024 is to factor in the buffer size BlurTA(0).tU = ZoomLevel * 1.333333333 BlurTA(0).tV = ZoomLevel BlurTA(1).tU = ((ScreenWidth + 1) / 1024) - (ZoomLevel * 1.333333333) BlurTA(1).tV = ZoomLevel BlurTA(2).tU = ZoomLevel * 1.333333333 BlurTA(2).tV = ((ScreenHeight + 1) / 1024) - ZoomLevel BlurTA(3).tU = BlurTA(1).tU BlurTA(3).tV = BlurTA(2).tV 'Draw what we have drawn thus far since the last .Clear LastTexture = -100 .SetRenderTarget DeviceBuffer, DeviceStencil, 0 .SetTexture 0, BlurTexture .SetRenderState D3DRS_TEXTUREFACTOR, D3DColorARGB(BlurIntensity, 255, 255, 255) .SetTextureStageState 0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR .DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, BlurTA(0), FVF_Size .SetTextureStageState 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE End With End If End If End Sub
Find:
Sub Effect_UpdateAll()
Replace sub with:
Sub Effect_UpdateAll() '***************************************************************** 'Updates all of the effects and renders them - a wrapper for Effect_Update to update all effects 'More info: http://www.vbgore.com/CommonCode.Particles.Effect_UpdateAll '***************************************************************** Dim LoopC As Long 'Make sure we have effects If NumEffects = 0 Then Exit Sub 'Update every effect in use For LoopC = 1 To NumEffects If LoopC <> WeatherEffectIndex Then Effect_Update LoopC Next End Sub Sub Effect_Update(ByVal EffectIndex As Byte) '***************************************************************** 'Updates an effect and renders it 'More info: http://www.vbgore.com/CommonCode.Particles.Effect_Update '***************************************************************** 'Make sure the effect is in use If Effect(EffectIndex).Used Then 'Set the render state for the particle effects D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_ONE 'Update the effect position if the screen has moved Effect_UpdateOffset EffectIndex 'Update the effect position if it is binded Effect_UpdateBinding EffectIndex 'Find out which effect is selected, then update it If Effect(EffectIndex).EffectNum = EffectNum_Fire Then Effect_Fire_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_Snow Then Effect_Snow_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_Heal Then Effect_Heal_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_Bless Then Effect_Bless_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_Protection Then Effect_Protection_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_Strengthen Then Effect_Strengthen_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_Rain Then Effect_Rain_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_EquationTemplate Then Effect_EquationTemplate_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_Waterfall Then Effect_Waterfall_Update EffectIndex If Effect(EffectIndex).EffectNum = EffectNum_Summon Then Effect_Summon_Update EffectIndex 'Render the effect Effect_Render EffectIndex, False 'Set the render state back for normal rendering D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA End If End Sub
Open EditorMap.vbp.
Find:
Public InfoLayer As InfoLayer
After, add:
'Render list - used to sort the list of graphics before rendering them Private Type RenderList X As Long Y As Long Z As Integer 'The value used to sort by (Y + Height) Grh As Long Light(0 To 3) As Long Center As Byte Shadow As Byte Angle As Single CharIndex As Long 'If it is a character, this is its index ParticleEffectIndex As Byte 'If it is a particle effect, this is its index End Type
At the end of the TileEngine module, add:
Private Sub Engine_AddToRenderList_Char(ByRef RenderList() As RenderList, ByRef RenderListSize As Long, ByRef Index As Long, _ ByVal CharIndex As Long, ByVal X As Long, ByVal Y As Long, ByVal Z As Integer) '***************************************************************** 'Adds a character to the RenderList() 'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_AddToRenderList_Char '***************************************************************** 'Increase the index Index = Index + 1 'Increase array size if needed If Index > RenderListSize Then RenderListSize = RenderListSize + 50 ReDim Preserve RenderList(1 To RenderListSize) End If 'Add the components With RenderList(Index) .CharIndex = CharIndex .X = X .Y = Y .Z = Z End With End Sub Private Sub Engine_AddToRenderList_PE(ByRef RenderList() As RenderList, ByRef RenderListSize As Long, ByRef Index As Long, _ ByVal ParticleEffectIndex As Long, ByVal Z As Integer) '***************************************************************** 'Adds a Particle Effect to the RenderList() 'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_AddToRenderList_PE '***************************************************************** 'Increase the index Index = Index + 1 'Increase array size if needed If Index > RenderListSize Then RenderListSize = RenderListSize + 50 ReDim Preserve RenderList(1 To RenderListSize) End If 'Add the components With RenderList(Index) .ParticleEffectIndex = ParticleEffectIndex .Z = Z End With End Sub Private Sub Engine_AddToRenderList_Grh(ByRef RenderList() As RenderList, ByRef RenderListSize As Long, ByRef Index As Long, _ ByVal Grh As Long, ByVal X As Long, ByVal Y As Long, ByVal Z As Integer, ByVal Light0 As Long, ByVal Light1 As Long, ByVal Light2 As Long, _ ByVal Light3 As Long, ByVal Angle As Single, ByVal Center As Byte, ByVal Shadow As Byte) '***************************************************************** 'Adds a Grh (such as a tile, Grh-based effect, projectile, etc) to the RenderList() 'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_AddToRenderList_Grh '***************************************************************** 'Increase the index Index = Index + 1 'Increase array size if needed If Index > RenderListSize Then RenderListSize = RenderListSize + 50 ReDim Preserve RenderList(1 To RenderListSize) End If 'Add the components With RenderList(Index) .Angle = Angle .Center = Center .Grh = Grh .Light(0) = Light0 .Light(1) = Light1 .Light(2) = Light2 .Light(3) = Light3 .Shadow = Shadow .X = X .Y = Y .Z = Z End With End Sub
Find:
If TileBufferSize < 2 Then TileBufferSize = 2
After, add:
'Cache the TileBufferOffset value to prevent always having to calculate it on the fly TileBufferOffset = ((10 - TileBufferSize) * 32)
Find:
Public TileBufferSize As Integer
After, add:
Public TileBufferOffset As Long 'Used to calculate offset value in certain cases
Find:
BodyData(LoopC).HeadOffset.Y = CLng(Var_Get(DataPath & "Body.dat", Str$(LoopC), "HeadOffsetY"))
After, add:
BodyData(LoopC).Height = CLng(Var_Get(DataPath & "Body.dat", LoopC, "Height"))
Find:
'Fill List For LoopC = 1 To NumHeads For i = 1 To 8 Engine_Init_Grh HeadData(LoopC).Head(i), CLng(Var_Get(DataPath & "Head.dat", Str$(LoopC), Str(i))), 0 Engine_Init_Grh HeadData(LoopC).Blink(i), CLng(Var_Get(DataPath & "Head.dat", Str$(LoopC), "b" & i)), 0 Engine_Init_Grh HeadData(LoopC).AgrHead(i), CLng(Var_Get(DataPath & "Head.dat", Str$(LoopC), "a" & i)), 0 Engine_Init_Grh HeadData(LoopC).AgrBlink(i), CLng(Var_Get(DataPath & "Head.dat", Str$(LoopC), "ab" & i)), 0 Next i Next LoopC
Replace with:
'Fill List For LoopC = 1 To NumHeads For i = 1 To 8 Engine_Init_Grh HeadData(LoopC).Head(i), CLng(Var_Get(DataPath & "Head.dat", Str$(LoopC), Str(i))), 0 Engine_Init_Grh HeadData(LoopC).Blink(i), CLng(Var_Get(DataPath & "Head.dat", Str$(LoopC), "b" & i)), 0 Engine_Init_Grh HeadData(LoopC).AgrHead(i), CLng(Var_Get(DataPath & "Head.dat", Str$(LoopC), "a" & i)), 0 Engine_Init_Grh HeadData(LoopC).AgrBlink(i), CLng(Var_Get(DataPath & "Head.dat", Str$(LoopC), "ab" & i)), 0 Next i HeadData(LoopC).Height = CLng(Var_Get(DataPath & "Head.dat", LoopC, "Height")) Next LoopC
Find:
'Bodies list Public Type BodyData Walk(1 To 8) As Grh Attack(1 To 8) As Grh HeadOffset As Position End Type
Replace with:
'Bodies list Public Type BodyData Walk(1 To 8) As Grh Attack(1 To 8) As Grh HeadOffset As Position Height As Long End Type
Find:
'Heads list Public Type HeadData Head(1 To 8) As Grh Blink(1 To 8) As Grh AgrHead(1 To 8) As Grh AgrBlink(1 To 8) As Grh End Type
Replace with:
'Heads list Public Type HeadData Head(1 To 8) As Grh Blink(1 To 8) As Grh AgrHead(1 To 8) As Grh AgrBlink(1 To 8) As Grh Height As Long End Type
Find:
Public Sub Engine_SortIntArray(TheArray() As Integer, TheIndex() As Integer, ByVal LowerBound As Integer, ByVal UpperBound As Integer)
Replace sub with:
Public Sub Engine_SortIntArray(TheArray() As Integer, TheIndex() As Integer, ByVal LowerBound As Integer, ByVal UpperBound As Integer) '***************************************************************** 'Sort an array of integers 'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_SortIntArray '***************************************************************** Dim indxt As Long 'Stored index Dim swp As Integer 'Swap variable Dim i As Integer 'Subarray Low Scan Index Dim j As Integer 'Subarray High Scan Index For j = LowerBound + 1 To UpperBound indxt = TheIndex(j) swp = TheArray(indxt) For i = j - 1 To LowerBound Step -1 If TheArray(TheIndex(i)) <= swp Then Exit For TheIndex(i + 1) = TheIndex(i) Next i TheIndex(i + 1) = indxt Next j End Sub
Find:
Sub Engine_Render_Screen(ByVal TileX As Integer, ByVal TileY As Integer, ByVal PixelOffsetX As Integer, ByVal PixelOffsetY As Integer)
Replace sub with:
Sub Engine_Render_Screen(ByVal TileX As Integer, ByVal TileY As Integer, ByVal PixelOffsetX As Integer, ByVal PixelOffsetY As Integer) '*********************************************** 'Draw current visible to scratch area based on TileX and TileY '*********************************************** Dim LightOffset As Long Dim RenderList() As RenderList Dim RenderListSize As Long Dim RenderListIndex As Long Dim ScreenX As Integer 'Keeps track of where to place tile on screen Dim ScreenY As Integer Dim Grh As Grh Dim x2 As Long Dim y2 As Long Dim Y As Long 'Keeps track of where on map we are Dim X As Long Dim j As Long Dim Layer As Byte Dim pList() As Integer Dim ValueList() As Integer Dim TempGrh As Grh minXOffset = 0 minYOffset = 0 'Check if we need to update the graphics If TileX <> LastTileX Or TileY <> LastTileY Then 'Figure out Ends and Starts of screen ScreenMinY = TileY - (WindowTileHeight \ 2) ScreenMaxY = TileY + (WindowTileHeight \ 2) ScreenMinX = TileX - (WindowTileWidth \ 2) ScreenMaxX = TileX + (WindowTileWidth \ 2) minY = ScreenMinY - TileBufferSize maxY = ScreenMaxY + TileBufferSize minX = ScreenMinX - TileBufferSize maxX = ScreenMaxX + TileBufferSize 'Update the last position LastTileX = TileX LastTileY = TileY 'Re-create the tile layers Engine_CreateTileLayers End If 'Calculate the particle offset values 'Do NOT move this any farther down in the module or you will get "jumps" as the left/top borders on particles ParticleOffsetX = (Engine_PixelPosX(ScreenMinX) - PixelOffsetX) * 1 ParticleOffsetY = (Engine_PixelPosY(ScreenMinY) - PixelOffsetY) * 1 'Check if we have the device If Not Engine_ValidateDevice Then Exit Sub Engine_EndScreenRender D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, 0, 1#, 0 D3DDevice.BeginScene DrawingGameScreen = True '******************************************************** '************ Update and draw layer 1 and 2 ************* '******************************************************** 'Loop through the lower 2 layers For Layer = 1 To 2 LightOffset = ((Layer - 1) * 4) + 1 'Loop through all the tiles we know we will draw for this layer For j = 1 To TileLayer(Layer).NumTiles With TileLayer(Layer).Tile(j) Engine_UpdateGrh MapData(.TileX, .TileY).Graphic(Layer) 'Check if we have to draw with a shadow or not (slighty changes because we have to animate on the shadow, not the main render) If MapData(.TileX, .TileY).Shadow(Layer) = 1 Then Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1 Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 0, True, MapData(.TileX, .TileY).Light(LightOffset), MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3) Else Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 1, True, MapData(.TileX, .TileY).Light(LightOffset), MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3) End If End With Next j 'Tile preview If frmSetTile.Visible Then If DrawLayer = Layer Then Grh.FrameCounter = 1 Grh.GrhIndex = Val(frmSetTile.GrhTxt.Text) j = D3DColorARGB(200, 255, 255, 255) If frmSetTile.ShadowChk.Value = 1 Then If Val(frmSetTile.ShadowTxt.Text) = 1 Then Engine_Render_Grh Grh, Engine_PixelPosX(minXOffset + (HovertX - minX)) + TileBufferOffset + PixelOffsetX, Engine_PixelPosY(minYOffset + (HovertY - minY)) + TileBufferOffset + PixelOffsetY, 0, 0, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1 End If Engine_Render_Grh Grh, Engine_PixelPosX(minXOffset + (HovertX - minX)) + TileBufferOffset + PixelOffsetX, Engine_PixelPosY(minYOffset + (HovertY - minY)) + TileBufferOffset + PixelOffsetY, 0, 0, False, j, j, j, j, 0 End If End If Next Layer '******************************************************** '****** Start storing graphics in the RenderList() ****** '****** so it can be sorted by their Y co-ordinate ****** '******************************************************** '************** Characters ************** For j = 1 To LastChar If CharList(j).Active Then X = Engine_PixelPosX(CharList(j).Pos.X - minX) + PixelOffsetX + TileBufferOffset Y = Engine_PixelPosY(CharList(j).Pos.Y - minY) + PixelOffsetY + TileBufferOffset If Y >= -32 And Y <= (ScreenHeight + 32) And X >= -32 And X <= (ScreenWidth + 32) Then 'Update the NPC chat and draw the character 'Engine_NPCChat_Update j Engine_AddToRenderList_Char RenderList(), RenderListSize, RenderListIndex, j, X, Y, _ Y + CharList(j).Body.Height + CharList(j).Head.Height Else 'Update just the real position CharList(j).RealPos.X = X + CharList(j).MoveOffset.X CharList(j).RealPos.Y = Y + CharList(j).MoveOffset.Y End If End If Next j '************** Layer 3 to 5 ************** For Layer = 3 To 5 LightOffset = ((Layer - 1) * 4) + 1 For j = 1 To TileLayer(Layer).NumTiles With TileLayer(Layer).Tile(j) Engine_UpdateGrh MapData(.TileX, .TileY).Graphic(Layer), True Engine_AddToRenderList_Grh RenderList(), RenderListSize, RenderListIndex, MapData(.TileX, .TileY).Graphic(Layer).GrhIndex, _ .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, .PixelPosY + PixelOffsetY + _ GrhData(MapData(.TileX, .TileY).Graphic(Layer).GrhIndex).pixelHeight, MapData(.TileX, .TileY).Light(1), _ MapData(.TileX, .TileY).Light(2), MapData(.TileX, .TileY).Light(3), MapData(.TileX, .TileY).Light(4), _ 0, 0, MapData(.TileX, .TileY).Shadow(Layer) End With Next j Next Layer '************** Tile preview ************** If frmSetTile.Visible Then j = D3DColorARGB(200, 255, 255, 255) If Val(frmSetTile.GrhTxt.Text) > 0 Then If Val(frmSetTile.GrhTxt.Text) < NumGrhs Then Engine_AddToRenderList_Grh RenderList, RenderListSize, RenderListIndex, Val(frmSetTile.GrhTxt.Text), _ Engine_PixelPosX(minXOffset + (HovertX - minX)) + TileBufferOffset + PixelOffsetX, Engine_PixelPosY(minYOffset + (HovertY - minY)) + TileBufferOffset + PixelOffsetY, _ Engine_PixelPosY(minYOffset + (HovertY - minY)) + TileBufferOffset + PixelOffsetY + GrhData(Val(frmSetTile.GrhTxt.Text)).pixelHeight, _ j, j, j, j, 0, 0, 0 End If End If End If '******************************************************** '************ Sort the RenderList() by the Z ************ '*********** value then draw then all in order ********** '******************************************************** If RenderListIndex > 0 Then 'Size the array down ReDim Preserve RenderList(1 To RenderListIndex) RenderListSize = RenderListIndex 'Sort the array ReDim ValueList(1 To RenderListIndex) ReDim pList(1 To RenderListIndex) For j = 1 To RenderListIndex ValueList(j) = RenderList(j).Z pList(j) = j Next j Engine_SortIntArray ValueList(), pList(), 1, RenderListIndex Erase ValueList() 'Erase the ValueList() - we don't need it anymore 'Create a temporary Grh (one without any animations since we don't need to animate) TempGrh.FrameCounter = 1 TempGrh.LastCount = 0 TempGrh.Started = 1 'Loop through all the graphics in the RenderList() For j = 1 To RenderListIndex If RenderList(pList(j)).CharIndex > 0 Then 'Draw a character With RenderList(pList(j)) Engine_Render_Char .CharIndex, .X, .Y End With ElseIf RenderList(pList(j)).ParticleEffectIndex > 0 Then 'Draw a particle effect Effect_Update RenderList(pList(j)).ParticleEffectIndex Else 'Draw a grh With RenderList(pList(j)) TempGrh.GrhIndex = .Grh If .Shadow Then Engine_Render_Grh TempGrh, .X, .Y, .Center, 0, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1, .Angle Engine_Render_Grh TempGrh, .X, .Y, .Center, 0, False, .Light(0), .Light(1), .Light(2), .Light(3), 0, .Angle End With End If Next j 'Done with the RenderList() Erase RenderList End If '******************************************************** '********** Perform the rest of the rendering *********** '******************************************************** '************** Layer 6 ************** Layer = 6 LightOffset = ((Layer - 1) * 4) + 1 For j = 1 To TileLayer(Layer).NumTiles With TileLayer(Layer).Tile(j) Engine_UpdateGrh MapData(.TileX, .TileY).Graphic(Layer) If MapData(.TileX, .TileY).Shadow(Layer) = 1 Then Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1 Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 0, True, MapData(.TileX, .TileY).Light(LightOffset), MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3) Else Engine_Render_Grh MapData(.TileX, .TileY).Graphic(Layer), .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 1, True, MapData(.TileX, .TileY).Light(LightOffset), MapData(.TileX, .TileY).Light(LightOffset + 1), MapData(.TileX, .TileY).Light(LightOffset + 2), MapData(.TileX, .TileY).Light(LightOffset + 3) End If End With Next j '************** Info ************** If InfoChkValue = 1 Then For X = 1 To InfoLayer.NumTiles For Y = 1 To InfoLayer.Tile(X).NumGrhs With InfoLayer.Tile(X).Grh(Y) Engine_Render_Grh .Grh, .PixelPosX + PixelOffsetX, .PixelPosY + PixelOffsetY, 0, 0, False End With Next Y Next X End If '************** Grid ************** If GridChkValue = 1 Then j = D3DColorARGB(25, 255, 255, 255) Grh.GrhIndex = 2 Grh.FrameCounter = 1 Grh.Started = 0 ScreenY = minYOffset For Y = minY To maxY ScreenX = minXOffset For X = minX To maxX Engine_Render_Grh Grh, Engine_PixelPosX(ScreenX) + PixelOffsetX + TileBufferOffset, Engine_PixelPosY(ScreenY) + PixelOffsetY + TileBufferOffset, 0, 0, , j, j, j, j ScreenX = ScreenX + 1 Next X ScreenY = ScreenY + 1 Next Y End If '************** Update weather ************** If WeatherChkValue = 1 Then 'Make sure the right weather is going on Engine_Weather_Update Else If WeatherEffectIndex > 0 Then If Effect(WeatherEffectIndex).Used Then Effect_Kill WeatherEffectIndex End If 'Change the light of all the tiles back If FlashTimer > 0 Then For X = 1 To MapInfo.Width For Y = 1 To MapInfo.Height For x2 = 1 To 4 MapData(X, Y).Light(x2) = SaveLightBuffer(X, Y).Light(x2) Next x2 Next Y Next X FlashTimer = 0 End If End If '************** Misc Rendering ************** 'Update and render particle effects Effect_UpdateAll 'Clear the shift-related variables LastOffsetX = ParticleOffsetX LastOffsetY = ParticleOffsetY '************** Mini-map ************** Const tS As Single = 2 'Size of the mini-map dots If ShowMiniMap Then 'Draw the map outline For X = 1 To NumMiniMapTiles Engine_Render_Rectangle MiniMapTile(X).X * tS, MiniMapTile(X).Y * tS, tS, tS, 1, 1, 1, 1, 1, 1, 0, 0, MiniMapTile(X).Color, MiniMapTile(X).Color, MiniMapTile(X).Color, MiniMapTile(X).Color Next X 'Draw the characters j = D3DColorARGB(200, 0, 255, 255) For X = 1 To LastChar Engine_Render_Rectangle CharList(X).Pos.X * tS, CharList(X).Pos.Y * tS, tS, tS, 1, 1, 1, 1, 1, 1, 0, 0, j, j, j, j Next X 'Draw the position indicator j = D3DColorARGB(200, 0, 255, 0) Engine_Render_Rectangle UserPos.X * tS, UserPos.Y * tS, tS, tS, 1, 1, 1, 1, 1, 1, 0, 0, j, j, j, j End If End Sub




