Mounts and Shields
From VbGORE Visual Basic Online RPG Engine
Here's my next great tutorial of doom! Here's my tutorial about how to add mounts and shields:
Before you do this, back up your code. You add this at your own risk (mwahahaha... *cough cough*)
Resources: Download these http://www.vbgore.com/forums/download/file.php?id=241, and unzip it. Put the grh files into the GRH directory and the dat files into the data directory.
Contents |
Database
First thing to do is go to your users table. add a "char_mount" and "char_shield" field. Make their settings identical to "char_weapon". Next add "eq_mount" and "eq_shield" and make their settings identical to "eq_weapon".
Now open up the objects table. add a "sprite_mount" and "sprite_shield" field. Make their settings identical to "sprite_weapon".
Now open the objects table to add two new records: 1) Make a new record with: (Edit the values how u see fit, except the objtype unless you know what u are doing) id: 10 (or whatever the next free id is) name: Horse price: 1000 objtpe: 7 grhIndex: 174 sprite_mount: 1 stat_speed: 10
2) Make another record with: id: 11 (or whatever the next free id) name: Newbie Shield price: 35 objtype: 6 grhindex: 195 sprite_shield: 1 stat_def: 2
Data Files
Just a note, I am working with the default body files (including the armor). So the changes below, just mimic it for all other bodies you have. Also, the grh for the bodies I included have a new row of graphics at the bottom. These are used when riding a mount. make something similar for all body graphics u have.
Open Body.dat and locate body 1. after the a1-a8 lines, add:
<ini>r1=181 r2=183 r3=182 r4=184 r5=181 r6=183 r7=182 r8=184</ini>
and for body 2, after a1-18 lines. add:
<ini>r1=191 r2=193 r3=192 r4=194 r5=191 r6=193 r7=192 r8=194</ini>
Now open the GrhRaw.txt file and locate the "armored body". in the lines of GRH that follow that section, add:
<ini>Grh118=1-100-0-192-32-48-(128) Grh119=1-100-32-192-32-48-(128) Grh120=1-100-64-192-32-48-(128) Grh121=1-100-96-192-32-48-(128) Grh185=1-100-128-192-32-48-(128) Grh186=1-100-160-192-32-48-(128) Grh187=1-100-192-192-32-48-(128) Grh188=1-100-224-192-32-48-(128) Grh189=1-100-192-191-32-48-(128) Grh190=1-100-224-191-32-48-(128)
Grh191=4-187-189-187-189-8-(128)
Grh192=4-188-190-188-190-8-(128)
Grh193=4-118-119-118-120-8-(128)
Grh194=4-121-185-121-186-8-(128)</ini>
This basically adds the animation for riding a mount.
Now locate "Body Naked" and add this to that section of grhs:
<ini>Grh60=1-109-0-192-32-48-(128) Grh61=1-109-32-192-32-48-(128) Grh74=1-109-64-192-32-48-(128) Grh75=1-109-96-192-32-48-(128) Grh175=1-109-128-192-32-48-(128) Grh176=1-109-160-192-32-48-(128) Grh177=1-109-192-192-32-48-(128) Grh178=1-109-224-192-32-48-(128) Grh179=1-109-192-191-32-48-(128) Grh180=1-109-224-191-32-48-(128)
Grh181=4-177-179-177-179-8-(128)
Grh182=4-178-180-178-180-8-(128)
Grh183=4-60-61-60-74-8-(128)
Grh184=4-75-175-75-176-8-(128)</ini>
This will also create the "riding" animation for mounts.
Now add the following to the bottom of your GrhRaw.txt file:
<ini>'**** Shield **** Grh134=1-149-0-0-32-48-(128) Grh135=1-149-32-0-32-48-(128) Grh136=1-149-64-0-32-48-(128) Grh137=1-149-96-0-32-48-(128) Grh138=1-149-0-48-32-48-(128) Grh139=1-149-32-48-32-48-(128) Grh140=1-149-64-48-32-48-(128) Grh141=1-149-96-48-32-48-(128) Grh142=1-149-0-96-32-48-(128) Grh143=1-149-32-96-32-48-(128) Grh144=1-149-64-96-32-48-(128) Grh145=1-149-96-96-32-48-(128) Grh146=1-149-0-144-32-48-(128) Grh147=1-149-32-144-32-48-(128) Grh148=1-149-64-144-32-48-(128) Grh149=1-149-96-144-32-48-(128) Grh150=1-149-128-0-32-48-(128) Grh151=1-149-160-0-32-48-(128) Grh152=1-149-192-0-32-48-(128) Grh153=1-149-224-0-32-48-(128) Grh154=1-149-128-48-32-48-(128) Grh155=1-149-160-48-32-48-(128) Grh156=1-149-192-48-32-48-(128) Grh157=1-149-224-48-32-48-(128) Grh158=1-149-128-96-32-48-(128) Grh159=1-149-160-96-32-48-(128) Grh160=1-149-192-96-32-48-(128) Grh161=1-149-224-96-32-48-(128) Grh162=1-149-128-144-32-48-(128) Grh163=1-149-160-144-32-48-(128) Grh164=1-149-192-144-32-48-(128) Grh165=1-149-224-144-32-48-(128)
Grh166=4-134-135-136-137-8-(128) Grh167=4-138-139-140-141-8-(128) Grh168=4-142-143-144-145-8-(128) Grh169=4-146-147-148-149-8-(128)
Grh195=1-149-26-9-30-30-(128)
'**** Horse **** Grh122=1-148-16-197-71-54-(128) Grh123=1-148-90-196-71-54-(128) Grh124=1-148-166-197-71-54-(128) Grh125=1-148-13-6-71-54-(128) Grh126=1-148-87-5-71-54-(128) Grh127=1-148-163-6-71-54-(128) Grh128=1-148-16-70-71-54-(128) Grh129=1-148-90-69-71-54-(128) Grh130=1-148-166-70-71-54-(128) Grh131=1-148-13-132-71-54-(128) Grh132=1-148-87-131-71-54-(128) Grh133=1-148-163-132-71-54-(128)
Grh170=4-131-132-133-132-8-(128) Grh171=4-128-129-130-129-8-(128) Grh172=4-125-126-127-126-8-(128) Grh173=4-122-123-124-123-8-(128)
Grh174=1-148-180-131-37-54-(128)</ini>
This creates the new shield and mount! If the grh numbers interfer with anything you already have, just make the appropriate adjustments (which I'm sorry to say may be a bit of grind).
Now run the ToolGrhDatMaker.exe to update these changes.
Client
Declares.Bat
Locate "Type Cache_Server_MakeChar" and add the following:
<vb> Mount As Integer
Shield As Integer</vb>
General.bas
Locate "'Load graphic data into memory" and add:
<vb> Engine_Init_ShieldData
Engine_Init_MountData</vb>
TCP.bas
locate "Data_Server_ChangeChar". in there find "Dim flags As Byte" and add below it:
<vb>Dim CharShield As Integer Dim CharMount As Integer</vb>
now at the end of the function add:
<vb> If flags And 32 Then
CharMount = rBuf.Get_Integer
If Not DontSetData Then CharList(CharIndex).Mount = MountData(CharMount)
End If
If flags And 64 Then
CharShield = rBuf.Get_Integer
If Not DontSetData Then CharList(CharIndex).Shield = ShieldData(CharShield)
End If</vb>
Now find Data_Server_MakeCharCached. just for your reference if you are editing this later, update the comments to:
<vb>'************************************************************ 'Create a character and set their information '<Flags(I)><Body(I)><Head(I)><Heading(B)><CharIndex(I)><X(B)><Y(B)><Speed(B)><Name(S)><Weapon(I)><Hair(I)><Wings(I)> ' <HP%(B)><MP%(B)><ChatID(B)><CharType(B)><Mount(I)><Shield(I)> (<OwnerCharIndex(I)>) 'More info: http://www.vbgore.com/GameClient.TCP.Data_Server_MakeCharCached '************************************************************</vb>
and among the variables declared at the beginning, add:
<vb>Dim Mount As Integer Dim Shield As Integer</vb>
and at the end of the block of code under "'Retrieve all the information" add this:
<vb> If flags And 16384 Then Mount = rBuf.Get_Integer Else Mount = PacketCache.Server_MakeChar.Mount
If flags And 32768 Then Shield = rBuf.Get_Integer Else Shield = PacketCache.Server_MakeChar.Shield</vb>
and in the block of code under "'Store the new values for the cache" add:
<vb> .Mount = Mount
.Shield = Shield</vb>
and replace the line of code under "'Create the character" with this:
<vb>Engine_Char_Make CharIndex, Body, Head, Heading, X, Y, Speed, Name, Weapon, Shield, Mount, Hair, Wings, ChatID, CharType, HP, MP</vb>
locate the function "Data_Server_MakeChar". Change the comments (for future editing) to this:
<vb>'************************************************************ 'Create a character and set their information '<Body(I)><Head(I)><Heading(B)><CharIndex(I)><X(B)><Y(B)><Speed(B)><Name(S)><Weapon(I)><Hair(I)><Wings(I)> ' <HP%(B)><MP%(B)><ChatID(B)><CharType(B)><Mount(I)><Shield(I)> (<OwnerCharIndex(I)>) 'More info: http://www.vbgore.com/GameClient.TCP.Data_Server_MakeChar '************************************************************</vb>
and add to the variable declarations at the beginning this:
<vb>Dim Mount As Integer Dim Shield As Integer</vb>
and add to the end of the block of code under "Retrieve all the information" this
<vb> Mount = rBuf.Get_Integer
Shield = rBuf.Get_Integer</vb>
and replace the line of code under "'Create the character" with this:
<vb>Engine_Char_Make CharIndex, Body, Head, Heading, X, Y, Speed, Name, Weapon, Shield, Mount, Hair, Wings, ChatID, CharType, HP, MP</vb>
Getting tired yet? get some coffee, there's ton more changes! Ok, find "Data_Server_ChangeChar" and change the comments under it to this:
<vb>'************************************************************ 'Change a character by the character index '<CharIndex(I)><Flags(B)>(<Body(I)><Head(I)><Weapon(I)><Hair(I)><Wings(I)>) 'More info: http://www.vbgore.com/GameClient.TCP.Data_Server_ChangeChar '************************************************************</vb>
And to add to the variables declarations at the beginning this:
<vb>Dim CharShield As Integer Dim CharMount As Integer</vb>
and at the very end of the function, add this:
<vb> If flags And 32 Then
CharMount = rBuf.Get_Integer
If Not DontSetData Then CharList(CharIndex).Mount = MountData(CharMount)
End If
If flags And 64 Then
CharShield = rBuf.Get_Integer
If Not DontSetData Then CharList(CharIndex).Shield = ShieldData(CharShield)
End If</vb>
TileEngine.bas
locate this:
<vb>'Weapons list Public Type WeaponData
Walk(1 To 8) As Grh Attack(1 To 8) As Grh
End Type</vb>
and under it add this:
<vb>'Shields list Public Type ShieldData
Walk(1 To 8) As Grh Attack(1 To 8) As Grh
End Type
'Mount list Public Type MountData
Walk(1 To 8) As Grh Offset As Position
End Type</vb>
Locate this:
<vb>'Bodies list Public Type BodyData</vb>
and add to it this:
<vb>Ride(1 To 8) As Grh</vb>
locate "Public Type Char" and add this:
<vb> Shield As ShieldData
Mount As MountData</vb>
locate this:
<vb>'Totals Private NumBodies As Integer 'Number of bodies Private NumHeads As Integer 'Number of heads</vb>
and add this:
<vb>Private NumMounts As Integer 'Number of Mounts Private NumShields As Integer 'Number of Shields</vb>
Now locate this:
<vb>'********** Public ARRAYS *********** Public GrhData() As GrhData 'Holds data for the graphic structure Public SurfaceSize() As TexInfo 'Holds the size of the surfaces for SurfaceDB() Public BodyData() As BodyData 'Holds data about body structure Public HeadData() As HeadData 'Holds data about head structure Public HairData() As HairData 'Holds data about hair structure</vb>
and add this:
<vb>Public MountData() As MountData 'Holds data about Mount structure Public ShieldData() As ShieldData 'Holds data about Shield structure</vb>
Now locate "Engine_Char_Make" and change the sub declaration to this:
<vb>Sub Engine_Char_Make(ByVal CharIndex As Integer, ByVal Body As Integer, ByVal Head As Integer, ByVal Heading As Byte, ByVal X As Integer, ByVal Y As Integer, ByVal Speed As Byte, ByVal Name As String, ByVal Weapon As Integer, ByVal Shield As Integer, ByVal Mount As Integer, ByVal Hair As Integer, ByVal Wings As Integer, ByVal ChatID As Byte, ByVal CharType As Byte, Optional ByVal HP As Byte = 100, Optional ByVal MP As Byte = 100)</vb>
and then locate "'Set the apperances" and add this:
<vb> CharList(CharIndex).Mount = MountData(Mount)
CharList(CharIndex).Shield = ShieldData(Shield)</vb>
now locate "Engine_Init_BodyData". Inside the loop "For j = 1 To 8" add this:
<vb>Engine_Init_Grh BodyData(LoopC).Ride(j), CLng(Var_Get(DataPath & "Body.dat", LoopC, "r" & j)), 0</vb>
Now add these sub routines (before or after the Engine_Init_BodyData sub):
<vb>Sub Engine_Init_MountData() '***************************************************************** 'Loads Mount.dat '***************************************************************** Dim LoopC As Long Dim j As Long
'Get number of Mounts
NumMounts = CLng(Var_Get(DataPath & "Mount.dat", "INIT", "NumMounts"))
'Resize array
ReDim MountData(0 To NumMounts) As MountData
'Fill list
For LoopC = 1 To NumMounts
For j = 1 To 8
Engine_Init_Grh MountData(LoopC).Walk(j), CLng(Var_Get(DataPath & "Mount.dat", LoopC, j)), 0
Next j
MountData(LoopC).Offset.X = CLng(Var_Get(DataPath & "Mount.dat", LoopC, "OffsetX"))
MountData(LoopC).Offset.Y = CLng(Var_Get(DataPath & "Mount.dat", LoopC, "OffsetY"))
Next LoopC
End Sub
Sub Engine_Init_ShieldData() '***************************************************************** 'Loads Shield.dat '***************************************************************** Dim LoopC As Long Dim j As Long
'Get number of Shields
NumShields = CLng(Var_Get(DataPath & "Shield.dat", "INIT", "NumShields"))
'Resize array
ReDim ShieldData(0 To NumShields) As ShieldData
'Fill list
For LoopC = 1 To NumShields
For j = 1 To 8
Engine_Init_Grh ShieldData(LoopC).Walk(j), CLng(Var_Get(DataPath & "Shield.dat", LoopC, j)), 0
Engine_Init_Grh ShieldData(LoopC).Attack(j), CLng(Var_Get(DataPath & "Shield.dat", LoopC, "a" & j)), 1
Next j
Next LoopC
End Sub </vb>
Locate "Engine_Init_UnloadTileEngine" and find "'Clear arrays". Add this under it:
<vb> Erase MountData
Erase ShieldData</vb>
Locate "Engine_Render_Char" and in the variable declarations at the beginning add this:
<vb>Dim MountGrh As Grh Dim ShieldGrh As Grh Dim Offset As Position Dim IsOnMount As Boolean</vb>
Under "'***** Set the variables *****" add this:
<vb> 'Is char on mount?
If Not CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).GrhIndex = 0 Then
IsOnMount = True
Offset = CharList(CharIndex).Mount.Offset
End If</vb>
now under "'***** Render Shadows *****" find "'Draw Body", change that section of code to this:
<vb> If CharList(CharIndex).ActionIndex <= 1 Then
'Shadow
If IsOnMount Then
Engine_Render_Grh CharList(CharIndex).Body.Ride(CharList(CharIndex).Heading), PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Engine_Render_Grh CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Else
Engine_Render_Grh CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Engine_Render_Grh CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Engine_Render_Grh CharList(CharIndex).Shield.Walk(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
End If
Else
'Shadow
Engine_Render_Grh CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Engine_Render_Grh CharList(CharIndex).Weapon.Attack(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Engine_Render_Grh CharList(CharIndex).Shield.Attack(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
'Check if animation has stopped
If CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading).Started = 0 Then CharList(CharIndex).ActionIndex = 0
End If
'Hair Engine_Render_Grh CharList(CharIndex).Hair.Hair(CharList(CharIndex).HeadHeading), PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, True, False, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1</vb>
and find '***** Render Character *****" and change the code under it to this:
<vb>'***** (When updating this, make sure you copy it to the NPCEditor and MapEditor, too!) *****
If IsOnMount Then
CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).FrameCounter
Else
CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).FrameCounter
End If
'The body, weapon, wings, shield, and mount
If CharList(CharIndex).ActionIndex <= 1 Then
'Walking
If IsOnMount Then
BodyGrh = CharList(CharIndex).Body.Ride(CharList(CharIndex).Heading)
MountGrh = CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading)
' animate weapon/shield
CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).FrameCounter
CharList(CharIndex).Shield.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).FrameCounter
Else
BodyGrh = CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading)
' animate weapon/shield
CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).FrameCounter
CharList(CharIndex).Shield.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).FrameCounter
WeaponGrh = CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading)
ShieldGrh = CharList(CharIndex).Shield.Walk(CharList(CharIndex).Heading)
End If
WingsGrh = CharList(CharIndex).Wings.Walk(CharList(CharIndex).Heading)
Else
'Attacking
BodyGrh = CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading)
WeaponGrh = CharList(CharIndex).Weapon.Attack(CharList(CharIndex).Heading)
WingsGrh = CharList(CharIndex).Wings.Attack(CharList(CharIndex).Heading)
ShieldGrh = CharList(CharIndex).Shield.Attack(CharList(CharIndex).Heading)
' animate weapon/shield
CharList(CharIndex).Weapon.Attack(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading).FrameCounter
CharList(CharIndex).Shield.Attack(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading).FrameCounter
End If
'The head
If CharList(CharIndex).Aggressive > 0 Then 'Aggressive
If CharList(CharIndex).BlinkTimer > 0 Then HeadGrh = CharList(CharIndex).Head.AgrBlink(CharList(CharIndex).HeadHeading) Else HeadGrh = CharList(CharIndex).Head.AgrHead(CharList(CharIndex).HeadHeading)
Else 'Non-aggressive
If CharList(CharIndex).BlinkTimer > 0 Then HeadGrh = CharList(CharIndex).Head.Blink(CharList(CharIndex).HeadHeading) Else HeadGrh = CharList(CharIndex).Head.Head(CharList(CharIndex).HeadHeading)
End If
'The hair
HairGrh = CharList(CharIndex).Hair.Hair(CharList(CharIndex).HeadHeading)
'Make the paperdoll layering based off the direction they are heading
'*** NORTH / NORTHEAST *** (1.Weapon 2.Body 3.Head 4.Hair 5.Wings)
If CharList(CharIndex).Heading = NORTH Or CharList(CharIndex).Heading = NORTHEAST Then
Engine_Render_Grh MountGrh, PixelOffsetX, PixelOffsetY, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WeaponGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh ShieldGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh BodyGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HeadGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HairGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WingsGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
'*** EAST / SOUTHEAST *** (1.Body 2.Head 3.Hair 4.Wings 5.Weapon)
ElseIf CharList(CharIndex).Heading = EAST Or CharList(CharIndex).Heading = SOUTHEAST Then
Engine_Render_Grh MountGrh, PixelOffsetX, PixelOffsetY, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh ShieldGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh BodyGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HeadGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HairGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WingsGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WeaponGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
'*** SOUTH / SOUTHWEST *** (1.Wings 2.Body 3.Head 4.Hair 5.Weapon)
ElseIf CharList(CharIndex).Heading = SOUTH Or CharList(CharIndex).Heading = SOUTHWEST Then
Engine_Render_Grh WingsGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh BodyGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HeadGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HairGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WeaponGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh ShieldGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh MountGrh, PixelOffsetX, PixelOffsetY, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
'*** WEST / NORTHWEST *** (1.Weapon 1.Body 2.Head 3.Hair 4.Wings)
ElseIf CharList(CharIndex).Heading = WEST Or CharList(CharIndex).Heading = NORTHWEST Then
Engine_Render_Grh WeaponGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh MountGrh, PixelOffsetX, PixelOffsetY, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh BodyGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HeadGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HairGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh ShieldGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WingsGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
End If</vb>
... come to think of it, I should have just copied my whole function over... xD
Now, for the code that draws the name:
<vb>'***** Render Extras *****
'Add Border around name
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 41 + Offset.Y, -16777216
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 39 + Offset.Y, -16777216
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 15 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -16777216
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 17 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -16777216
'Draw name over head
If CharList(CharIndex).HealthPercent = 100 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -14104576
ElseIf CharList(CharIndex).HealthPercent > 90 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -11483136
ElseIf CharList(CharIndex).HealthPercent > 80 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -8861696
ElseIf CharList(CharIndex).HealthPercent > 70 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -6240256
ElseIf CharList(CharIndex).HealthPercent > 50 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -3618816
ElseIf CharList(CharIndex).HealthPercent > 40 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -3629056
ElseIf CharList(CharIndex).HealthPercent > 30 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -3639296
ElseIf CharList(CharIndex).HealthPercent > 20 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -3649536
ElseIf CharList(CharIndex).HealthPercent > 10 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -3659776
ElseIf CharList(CharIndex).HealthPercent > 0 Then
Engine_Render_Text Font_Default, CharList(CharIndex).DisplayName, PixelOffsetX + 16 - CharList(CharIndex).NameOffset + Offset.X, PixelOffsetY - 40 + Offset.Y, -3670016
End If</vb>
now, yours may be different because I added to my code the "Name Border" code and the code from the tutorial that changes the color of the name to reflect your health status. The important thing to do in your code for the part that renders the name is add "Offset.X" and "Offset.Y" to the x and y coordinates. That's also what I am doing in the following code...
Now for the code that renders the emoticons, the icons, and health/mana bars, change yours or replace it with this:
<vb> 'Health/Mana bars
Engine_Render_Rectangle PixelOffsetX - 4 + Offset.X, PixelOffsetY + 34 + Offset.Y, (CharList(CharIndex).HealthPercent / 100) * 40, 4, 1, 1, 1, 1, 1, 1, 0, 0, HealthColor, HealthColor, HealthColor, HealthColor, 0, False Engine_Render_Rectangle PixelOffsetX - 4 + Offset.X, PixelOffsetY + 38 + Offset.Y, (CharList(CharIndex).ManaPercent / 100) * 40, 4, 1, 1, 1, 1, 1, 1, 0, 0, ManaColor, ManaColor, ManaColor, ManaColor, 0, False
'Draw the icons If IconCount > 0 Then
'Calculate the icon offset
IconOffset = PixelOffsetX + 16 - (IconCount * 8) + Offset.X
If CharList(CharIndex).CharStatus.Blessed Then
Engine_Init_Grh TempGrh, 15
Engine_Render_Grh TempGrh, IconOffset, PixelOffsetY - 50 + Offset.Y, 0, 0, False
IconOffset = IconOffset + 16
End If
If CharList(CharIndex).CharStatus.Protected Then
Engine_Init_Grh TempGrh, 20
Engine_Render_Grh TempGrh, IconOffset, PixelOffsetY - 50 + Offset.Y, 0, 0, False
IconOffset = IconOffset + 16
End If
If CharList(CharIndex).CharStatus.Strengthened Then
Engine_Init_Grh TempGrh, 17
Engine_Render_Grh TempGrh, IconOffset, PixelOffsetY - 50 + Offset.Y, 0, 0, False
IconOffset = IconOffset + 16
End If
If CharList(CharIndex).CharStatus.Cursed Then
Engine_Init_Grh TempGrh, 18
Engine_Render_Grh TempGrh, IconOffset, PixelOffsetY - 50 + Offset.Y, 0, 0, False
IconOffset = IconOffset + 16
End If
If CharList(CharIndex).CharStatus.WarCursed Then
Engine_Init_Grh TempGrh, 19
Engine_Render_Grh TempGrh, IconOffset, PixelOffsetY - 50 + Offset.Y, 0, 0, False
IconOffset = IconOffset + 16
End If
If CharList(CharIndex).CharStatus.IronSkinned Then
Engine_Init_Grh TempGrh, 16
Engine_Render_Grh TempGrh, IconOffset, PixelOffsetY - 50 + Offset.Y, 0, 0, False
IconOffset = IconOffset + 16
End If
If CharList(CharIndex).CharStatus.Exhausted Then
Engine_Init_Grh TempGrh, 22
Engine_Render_Grh TempGrh, IconOffset, PixelOffsetY - 50 + Offset.Y, 0, 0, False
IconOffset = IconOffset + 16
End If
End If
'Emoticons If CharList(CharIndex).EmoDir > 0 Then
'Fade in
If CharList(CharIndex).EmoDir = 1 Then
CharList(CharIndex).EmoFade = CharList(CharIndex).EmoFade + (ElapsedTime * 1.5)
If CharList(CharIndex).EmoFade >= 255 Then
CharList(CharIndex).EmoFade = 255
CharList(CharIndex).EmoDir = 2
End If
End If
'Fade out
If CharList(CharIndex).Emoticon.Started = 0 Then 'Animation has stopped
If CharList(CharIndex).EmoDir = 2 Then
CharList(CharIndex).EmoFade = CharList(CharIndex).EmoFade - (ElapsedTime * 1.5)
If CharList(CharIndex).EmoFade <= 0 Then
CharList(CharIndex).EmoFade = 0
CharList(CharIndex).EmoDir = 0
End If
'Stop at the last frame, don't roll over to the first
CharList(CharIndex).Emoticon.FrameCounter = GrhData(CharList(CharIndex).Emoticon.GrhIndex).NumFrames
End If
End If
'Render
Engine_Render_Grh CharList(CharIndex).Emoticon, PixelOffsetX + 8 + Offset.X, PixelOffsetY - 40 + Offset.Y, 0, 1, False, D3DColorARGB(CharList(CharIndex).EmoFade, 255, 255, 255), D3DColorARGB(CharList(CharIndex).EmoFade, 255, 255, 255), D3DColorARGB(CharList(CharIndex).EmoFade, 255, 255, 255), D3DColorARGB(CharList(CharIndex).EmoFade, 255, 255, 255)
End If</vb>
Server
Declares.bas
find "Public Type udtObjData" and add to it this:
<vb> SpriteMount As Integer 'Index of the Mount sprite to change to
SpriteShield As Integer 'Index of the Shield sprite to change to</vb>
Find "Type Char 'Holds data for a user or NPC character" and add this:
<vb> Mount As Integer 'Mount index
Shield As Integer 'Shield index</vb>
Find "Type Cache_Server_MakeChar" and add this:
<vb> Shield As Integer
Mount As Integer</vb>
Find "Type User 'Holds data for a user" and add this:
<vb> ShieldEqpObjIndex As Integer 'The index of the equipted Shield
ShieldEqpSlot As Byte 'Slot of the equipted Shield MountEqpObjIndex As Integer 'The index of the equipted Mount MountEqpSlot As Byte 'Slot of the equipted Mount</vb>
Find this:
<vb>'Object types Public Const OBJTYPE_USEONCE As Byte = 1 'Objects that can be used only once Public Const OBJTYPE_WEAPON As Byte = 2 'Weapons of all types Public Const OBJTYPE_ARMOR As Byte = 3 'Body armors Public Const OBJTYPE_WINGS As Byte = 4 'Wings Public Const OBJTYPE_USEINFINITE As Byte = 5 'USEONCE object, minus the removal after usage</vb>
and add to the bottom of it this:
<vb>Public Const OBJTYPE_SHIELD As Byte = 6 'Shields Public Const OBJTYPE_MOUNT As Byte = 7 'Mount</vb>
FileIO.bas
Now find "Save_NPCs_Temp" and in it find "With NPCList (1)" and add this:
<vb> .Char.Mount = Val(DB_RS!char_mount)
.Char.Shield = Val(DB_RS!char_shield)</vb>
Find Load_Objs and in it find "With TempObjData". add to it this:
<vb> .SpriteMount = Val(DB_RS!sprite_mount)
.SpriteShield = Val(DB_RS!sprite_shield)</vb>
Find "Load_User" and find "UserList(UserIndex).Char.Weapon = Val(!char_weapon)" and add below it this:
<vb> UserList(UserIndex).Char.Mount = Val(!char_mount)
UserList(UserIndex).Char.Shield = Val(!char_shield)
UserList(UserIndex).MountEqpSlot = Val(!eq_mount)
UserList(UserIndex).ShieldEqpSlot = Val(!eq_shield)</vb>
Find in the same function this "'Equipt items" and add below it this:
<vb> If UserList(UserIndex).MountEqpSlot > 0 Then UserList(UserIndex).MountEqpObjIndex = UserList(UserIndex).Object(UserList(UserIndex).MountEqpSlot).ObjIndex
If UserList(UserIndex).ShieldEqpSlot > 0 Then UserList(UserIndex).ShieldEqpObjIndex = UserList(UserIndex).Object(UserList(UserIndex).WeaponEqpSlot).ObjIndex</vb>
Find "Save_User" and find "DB_RS!char_weapon = .Char.Weapon" and below it add this:
<vb> DB_RS!char_mount = .Char.Mount
DB_RS!char_shield = .Char.Shield
DB_RS!eq_mount = .MountEqpSlot
DB_RS!eq_shield = .ShieldEqpSlot</vb>
Find "Save_NPCs_Temp" and in it find ".Char.Weapon = Val(DB_RS!char_weapon)' and below that add this:
<vb> .Char.Mount = Val(DB_RS!char_mount)
.Char.Shield = Val(DB_RS!char_shield)</vb>
NPCs.bas
Find NPC_ChangeChar and change the sub declaration to this:
<vb>Private Sub NPC_ChangeChar(ByVal sndRoute As Byte, ByVal sndIndex As Integer, ByVal NPCIndex As Integer, Optional ByVal Body As Integer = -1, Optional ByVal Head As Integer = -1, Optional ByVal Weapon As Integer = -1, Optional ByVal Mount As Integer = -1, Optional ByVal Shield As Integer = -1, Optional ByVal Hair As Integer = -1, Optional ByVal Wings As Integer = -1)</vb>
then find this:
<vb>If Weapon > -1 Then
If .Weapon <> Weapon Then
.Weapon = Weapon
ChangeFlags = ChangeFlags Or 4
FlagSizes = FlagSizes + 2
End If
End If</vb>
and below it add this:
<vb> If Mount > -1 Then
NPCList(NPCIndex).Attackable = 0
If .Mount <> Mount Then
.Mount = Mount
ChangeFlags = ChangeFlags Or 4
FlagSizes = FlagSizes + 2
End If
End If
If Shield > -1 Then
If .Shield <> Shield Then
.Shield = Shield
ChangeFlags = ChangeFlags Or 4
FlagSizes = FlagSizes + 2
End </vb>
then find "If ChangeFlags And 16 Then ConBuf.Put_Integer Wings" and below it add this:
<vb> If ChangeFlags And 32 Then ConBuf.Put_Integer Mount
If ChangeFlags And 64 Then ConBuf.Put_Integer Shield</vb>
Find NPC_MakeChar and find this:
<vb>If NPCList(NPCIndex).OwnerIndex > 0 Then
If ClientCharType_Slave <> .CharType Then
Flags = Flags Or 8192
.CharType = ClientCharType_Slave
PacketSize = PacketSize + 1
End If
Else
If ClientCharType_NPC <> .CharType Then
Flags = Flags Or 8192
.CharType = ClientCharType_NPC
PacketSize = PacketSize + 1
End If
End If</vb>
and below it add this:
<vb>If NPCList(NPCIndex).Char.Mount <> .Mount Then
Flags = Flags Or 16384
.Mount = NPCList(NPCIndex).Char.Mount
If (.Mount > 0) Then
NPCList(NPCIndex).Attackable = 0
End If
PacketSize = PacketSize + 2
End If
If NPCList(NPCIndex).Char.Shield <> .Shield Then
Flags = Flags Or 32768
.Shield = NPCList(NPCIndex).Char.Shield
PacketSize = PacketSize + 2
End If</vb>
Now in the if statement "If sndRoute = ToIndex Then" find "If NPCList(NPCIndex).OwnerIndex > 0 Then ... End If" and replace that section of code with this:
<vb> If NPCList(NPCIndex).OwnerIndex > 0 Then
If Flags And 8192 Then ConBuf.Put_Byte ClientCharType_Slave
If Flags And 16384 Then ConBuf.Put_Byte NPCList(NPCIndex).Char.Mount
If Flags And 32768 Then ConBuf.Put_Byte NPCList(NPCIndex).Char.Shield
ConBuf.Put_Integer UserList(NPCList(NPCIndex).OwnerIndex).Char.CharIndex
Else
If Flags And 8192 Then ConBuf.Put_Byte ClientCharType_NPC
If Flags And 16384 Then ConBuf.Put_Byte NPCList(NPCIndex).Char.Mount
If Flags And 32768 Then ConBuf.Put_Byte NPCList(NPCIndex).Char.Shield
End If</vb>
Now for the same if statement "If NPCList(NPCIndex).OwnerIndex > 0 Then ... End If", go to the ELSE statement and find "If NPCList(NPCIndex).OwnerIndex > 0 Then" and replace that block of code with this:
<vb> If NPCList(NPCIndex).OwnerIndex > 0 Then
ConBuf.Put_Byte ClientCharType_Slave
ConBuf.Put_Integer NPCList(NPCIndex).Char.Mount
ConBuf.Put_Integer NPCList(NPCIndex).Char.Shield
ConBuf.Put_Integer UserList(NPCList(NPCIndex).OwnerIndex).Char.CharIndex
Else
ConBuf.Put_Byte ClientCharType_NPC
ConBuf.Put_Integer NPCList(NPCIndex).Char.Mount
ConBuf.Put_Integer NPCList(NPCIndex).Char.Shield
End If</vb>
TCP.bas
find Data_User_ChangeInvSlot and in that find:
<vb>If UserList(UserIndex).WeaponEqpSlot = SrcSlot Then
UserList(UserIndex).WeaponEqpSlot = DestSlot
ElseIf UserList(UserIndex).WeaponEqpSlot = DestSlot Then
UserList(UserIndex).WeaponEqpSlot = SrcSlot
End If</vb>
and below that add this:
<vb>If UserList(UserIndex).MountEqpSlot = SrcSlot Then
UserList(UserIndex).MountEqpSlot = DestSlot
ElseIf UserList(UserIndex).MountEqpSlot = DestSlot Then
UserList(UserIndex).MountEqpSlot = SrcSlot
End If
If UserList(UserIndex).ShieldEqpSlot = SrcSlot Then
UserList(UserIndex).ShieldEqpSlot = DestSlot
ElseIf UserList(UserIndex).ShieldEqpSlot = DestSlot Then
UserList(UserIndex).ShieldEqpSlot = SrcSlot
End If</vb>
Now find Data_User_Attack. At the end of this function, add: <vb>
'Dismount when attacking
For i = 1 To MAX_INVENTORY_SLOTS
If ObjData.ObjType(UserList(UserIndex).Object(i).ObjIndex) = 7 Then
Call User_RemoveInvItem(UserIndex, i, True)
Exit For
End If
Next i
</vb>
Users.bas
Find User_ChangeChar and change the sub declaration to this:
<vb>Public Sub User_ChangeChar(ByVal sndRoute As Byte, ByVal sndIndex As Integer, ByVal UserIndex As Integer, Optional ByVal Body As Integer = -1, Optional ByVal Head As Integer = -1, Optional ByVal Weapon As Integer = -1, Optional ByVal Hair As Integer = -1, Optional ByVal Wings As Integer = -1, Optional ByVal Mount As Integer = -1, Optional ByVal Shield As Integer = -1)</vb>
now change the comment section to this:
<vb>'***************************************************************** 'Changes a user char's head,body, shield, mount, and heading 'More info: http://www.vbgore.com/GameServer.Users.User_ChangeChar '*****************************************************************</vb>
and now change the "Log" calls at the beginning to this:
<vb>Log "Call User_ChangeChar(" & sndRoute & "," & sndIndex & "," & UserIndex & "," & Body & "," & Head & "," & Weapon & "," & Hair & "," & Wings & "," & Mount & "," & Shield & ")", CodeTracker '//\\LOGLINE//\\
'Check for invalid values
If UserIndex > MaxUsers Then
Log "User_ChangeChar: UserIndex > MaxUsers - aborting", CodeTracker '//\\LOGLINE//\\
Exit Sub
End If
If UserIndex <= 0 Then
Log "User_ChangeChar: UserIndex <= 0 - aborting", CodeTracker '//\\LOGLINE//\\
Exit Sub
End If</vb>
now find this:
<vb> If Wings > -1 Then
If .Wings <> Wings Then
.Wings = Wings
ChangeFlags = ChangeFlags Or 16
FlagSizes = FlagSizes + 2
End If
End If</vb>
and below it add this:
<vb> If Mount > -1 Then
If .Mount <> Mount Then
.Mount = Mount
ChangeFlags = ChangeFlags Or 32
FlagSizes = FlagSizes + 2
End If
End If
If Shield > -1 Then
If .Shield <> Shield Then
.Shield = Shield
ChangeFlags = ChangeFlags Or 64
FlagSizes = FlagSizes + 2
End If
End If</vb>
Now find "If ChangeFlags And 16 Then ConBuf.Put_Integer Wings" and below it add this:
<vb> If ChangeFlags And 32 Then ConBuf.Put_Integer Mount
If ChangeFlags And 64 Then ConBuf.Put_Integer Shield</vb>
Find User_MakeChar and find this:
<vb> If UserList(UserIndex).GroupIndex > 0 And UserList(sndIndex).GroupIndex = UserList(UserIndex).GroupIndex Then
ConBuf.Put_Byte ClientCharType_Grouped
Else
ConBuf.Put_Byte ClientCharType_PC
End If</vb>
and below it add this:
<vb> ConBuf.Put_Integer UserList(UserIndex).Char.Mount
ConBuf.Put_Integer UserList(UserIndex).Char.Shield</vb>
Find User_RemoveInvItem and find this:
<vb>'Check for weapon
Case OBJTYPE_WEAPON
Log "User_RemoveInvItem: Object type OBJTYPE_WEAPON", CodeTracker '//\\LOGLINE//\\
If Slot = UserList(UserIndex).WeaponEqpSlot Then
'Update the weapon distance on the client
ConBuf.PreAllocate 2
ConBuf.Put_Byte DataCode.User_SetWeaponRange
ConBuf.Put_Byte 0
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer
'Unequip
UserList(UserIndex).Object(Slot).Equipped = 0
UserList(UserIndex).WeaponEqpObjIndex = 0
UserList(UserIndex).WeaponEqpSlot = 0
UserList(UserIndex).WeaponType = Hand
'Set the paper-dolling
User_ChangeChar ToMap, UserIndex, UserIndex, , , 0
'Update user's stats and inventory
If UpdateInv Then User_UpdateInv False, UserIndex, Slot
End If</vb>
Below that add this:
<vb> 'Check for mount
Case OBJTYPE_MOUNT
Log "User_RemoveInvItem: Object type OBJTYPE_MOUNT", CodeTracker '//\\LOGLINE//\\
If Slot = UserList(UserIndex).MountEqpSlot Then
'Unequip
UserList(UserIndex).Object(Slot).Equipped = 0
UserList(UserIndex).MountEqpObjIndex = 0
UserList(UserIndex).MountEqpSlot = 0
'Set the paper-dolling
User_ChangeChar ToMap, UserIndex, UserIndex, , , , , , 0
'Update user's stats and inventory
If UpdateInv Then User_UpdateInv False, UserIndex, Slot
End If
'Check for shield
Case OBJTYPE_SHIELD
Log "User_RemoveInvItem: Object type OBJTYPE_SHIELD", CodeTracker '//\\LOGLINE//\\
If Slot = UserList(UserIndex).ShieldEqpSlot Then
'Unequip
UserList(UserIndex).Object(Slot).Equipped = 0
UserList(UserIndex).ShieldEqpObjIndex = 0
UserList(UserIndex).ShieldEqpSlot = 0
'Set the paper-dolling
User_ChangeChar ToMap, UserIndex, UserIndex, , , , , , , 0
'Update user's stats and inventory
If UpdateInv Then User_UpdateInv False, UserIndex, Slot
End If</vb>
Find User_UpdateModStats and add to the variable declarations at the beginning this:
<vb>Dim MountObj As Integer Dim ShieldObj As Integer</vb>
Then find "If UserList(UserIndex).WeaponEqpObjIndex > 0 Then WeaponObj = UserList(UserIndex).WeaponEqpObjIndex" and after it add this:
<vb> If UserList(UserIndex).MountEqpObjIndex > 0 Then MountObj = UserList(UserIndex).MountEqpObjIndex
If UserList(UserIndex).ShieldEqpObjIndex > 0 Then ShieldObj = UserList(UserIndex).ShieldEqpObjIndex</vb>
Now find "'Equipted items" and replace the block of code under it with this:
<vb> For i = FirstModStat To NumStats
Log "User_UpdateModStats: Updating ModStat ID " & i, CodeTracker '//\\LOGLINE//\\
.ModStat(i) = .BaseStat(i) + ObjData.AddStat(WeaponObj, i) + ObjData.AddStat(MountObj, i) + ObjData.AddStat(ShieldObj, i) + ObjData.AddStat(ArmorObj, i) + ObjData.AddStat(WingsObj, i)
Next i</vb>
Find EACH "'Set the paper-doll" section in this function and replace the code under them with this:
<vb>User_ChangeChar ToMap, UserIndex, UserIndex, ObjData.SpriteBody(ObjIndex), ObjData.SpriteHead(ObjIndex), ObjData.SpriteWeapon(ObjIndex), ObjData.SpriteHair(ObjIndex), ObjData.SpriteWings(ObjIndex), ObjData.SpriteMount(ObjIndex), ObjData.SpriteShield(ObjIndex)</vb>
(basically it adds the mount and shield sprite parameters to the User_ChangeChar calls)
Now add this code below to the Select Case structure in this function:
<vb> Case OBJTYPE_MOUNT
Log "User_UseInvItem: ObjType = OBJTYPE_MOUNT", CodeTracker '//\\LOGLINE//\\
'If currently equipped remove instead
If UserList(UserIndex).Object(Slot).Equipped Then
User_RemoveInvItem UserIndex, Slot
Exit Sub
End If
'Remove old item if exists
If UserList(UserIndex).MountEqpObjIndex > 0 Then User_RemoveInvItem UserIndex, UserList(UserIndex).MountEqpSlot
'Equip
UserList(UserIndex).Object(Slot).Equipped = 1
UserList(UserIndex).MountEqpObjIndex = UserList(UserIndex).Object(Slot).ObjIndex
UserList(UserIndex).MountEqpSlot = Slot
'Set the paper-doll
User_ChangeChar ToMap, UserIndex, UserIndex, ObjData.SpriteBody(ObjIndex), ObjData.SpriteHead(ObjIndex), ObjData.SpriteWeapon(ObjIndex), ObjData.SpriteHair(ObjIndex), ObjData.SpriteWings(ObjIndex), ObjData.SpriteMount(ObjIndex), ObjData.SpriteShield(ObjIndex)
Case OBJTYPE_SHIELD
Log "User_UseInvItem: ObjType = OBJTYPE_SHIELD", CodeTracker '//\\LOGLINE//\\
'If currently equipped remove instead
If UserList(UserIndex).Object(Slot).Equipped Then
User_RemoveInvItem UserIndex, Slot
Exit Sub
End If
'Remove old item if exists
If UserList(UserIndex).ShieldEqpObjIndex > 0 Then User_RemoveInvItem UserIndex, UserList(UserIndex).ShieldEqpSlot
'Equip
UserList(UserIndex).Object(Slot).Equipped = 1
UserList(UserIndex).ShieldEqpObjIndex = UserList(UserIndex).Object(Slot).ObjIndex
UserList(UserIndex).ShieldEqpSlot = Slot
'Set the paper-doll
User_ChangeChar ToMap, UserIndex, UserIndex, ObjData.SpriteBody(ObjIndex), ObjData.SpriteHead(ObjIndex), ObjData.SpriteWeapon(ObjIndex), ObjData.SpriteHair(ObjIndex), ObjData.SpriteWings(ObjIndex), ObjData.SpriteMount(ObjIndex), ObjData.SpriteShield(ObjIndex)</vb>
ObjData.cls
Add this code:
<vb>Public Property Get SpriteMount(ByVal Index As Integer) As Integer
If Index > 0 Then
If Index <= MaxDatas Then
ReadyObj Index
SpriteMount = cData(ObjIndexToDataIndex(Index)).SpriteMount
End If
End If
End Property
Public Property Get SpriteShield(ByVal Index As Integer) As Integer
If Index > 0 Then
If Index <= MaxDatas Then
ReadyObj Index
SpriteShield = cData(ObjIndexToDataIndex(Index)).SpriteShield
End If
End If
End Property</vb>
Go to TCP.bas Go to Data_User_Attack and add this to the end of the function: <vb>
'Dismount when attacking
For i = 1 To MAX_INVENTORY_SLOTS
If ObjData.ObjType(UserList(UserIndex).Object(i).ObjIndex) = 7 Then
Call User_RemoveInvItem(UserIndex, i, True)
Exit For
End If
Next i
</vb>
Map Editor
General.bas
Find SetTile and find "'Check to place/erase a NPC" and replace the section of code under it with this:
<vb> If frmNPCs.Visible Then
If Button = vbLeftButton Then
If tY > 1 Then 'Dont place NPCs on tiles y = 1, since their head goes onto tile 0, then uhoh! :o
If Not Shift Then
If frmNPCs.SetOpt.Value Then
If MapData(tX, tY).NPCIndex = 0 Then
DB_RS.Open "SELECT * FROM npcs WHERE id=" & frmNPCs.NPCList.ListIndex + 1, DB_Conn, adOpenStatic, adLockOptimistic
Engine_Char_Make NextOpenCharIndex, DB_RS!char_body, DB_RS!char_head, DB_RS!char_heading, tX, tY, Trim$(DB_RS!Name), DB_RS!char_weapon, DB_RS!char_mount, DB_RS!chr_shield, DB_RS!char_hair, DB_RS!char_wings, DB_RS!id
DB_RS.Close
AB = 1
End If
End If
If frmNPCs.EraseOpt.Value Then
If MapData(tX, tY).NPCIndex <> 0 Then
Engine_Char_Erase MapData(tX, tY).NPCIndex
AB = 1
End If
End If
End If
End If
End If
End If</vb>
Find Game_Map_Switch and find " 'Load NPC". Replace the section of code under it with this:
<vb> If BxFlags And 2 Then
Get #InfNum, , TempInt
'Set up pos and startup pos
DB_RS.Open "SELECT * FROM npcs WHERE id=" & TempInt, DB_Conn, adOpenStatic, adLockOptimistic
Engine_Char_Make NextOpenCharIndex, DB_RS!char_body, DB_RS!char_head, DB_RS!char_heading, X, Y, Trim$(DB_RS!Name), DB_RS!char_weapon, DB_RS!char_mount, DB_RS!char_shield, DB_RS!char_hair, DB_RS!char_wings, DB_RS!id
DB_RS.Close
End If</vb>
TileEngine.bas
Find this:
<vb>'Weapons list Public Type WeaponData
Walk(1 To 8) As Grh Attack(1 To 8) As Grh
End Type</vb>
and below it add this:
<vb>'Shields list Public Type ShieldData
Walk(1 To 8) As Grh Attack(1 To 8) As Grh
End Type
'Mount list Public Type MountData
Walk(1 To 8) As Grh Offset As Position
End Type</vb>
Find "Public Type Char" and add to it this:
<vb> Shield As ShieldData
Mount As MountData</vb>
Find "Type CharShort" and add to it this:
<vb> Mount As Integer 'Mount index
Shield As Integer 'Shield index</vb>
Find this:
<vb>'Totals Private NumBodies As Integer 'Number of bodies Private NumWings As Integer 'Number of wings Private NumHeads As Integer 'Number of heads Private NumHairs As Integer 'Number of hairs Private NumWeapons As Integer 'Number of weapons</vb>
and add to it this:
<vb>Private NumMounts As Integer 'Number of Mounts Private NumShields As Integer 'Number of Shields</vb>
Find "'********** Public ARRAYS ***********" and add to it this:
<vb>Public MountData() As MountData 'Holds data about Mount structure Public ShieldData() As ShieldData 'Holds data about Shield structure</vb>
Find Engine_Char_Make and replace the sub declaration with this:
<vb>Sub Engine_Char_Make(ByVal CharIndex As Integer, ByVal Body As Integer, ByVal Head As Integer, ByVal Heading As Byte, ByVal X As Integer, ByVal Y As Integer, ByVal Name As String, ByVal Weapon As Integer, ByVal Mount As Integer, ByVal Shield As Integer, ByVal Hair As Integer, ByVal Wings As Integer, ByVal NPCNumber As Integer)</vb>
Find "'Set the apperances" and add to it this:
<vb> CharList(CharIndex).Mount = MountData(Mount)
CharList(CharIndex).Shield = ShieldData(Shield)</vb>
Find Engine_Init_TileEngine and find in it "'Load graphic data into memory" and add to that this:
<vb> Engine_Init_MountData
Engine_Init_ShieldData</vb>
Find Engine_Init_BodyData and in the loop "For j = 1 To 8" add this:
<vb>Engine_Init_Grh BodyData(LoopC).Ride(j), CLng(Var_Get(DataPath & "Body.dat", LoopC, "r" & j)), 0</vb>
Outside that sub, either above or below it, add these subs:
<vb>Sub Engine_Init_MountData() '***************************************************************** 'Loads Mount.dat '***************************************************************** Dim LoopC As Long Dim j As Long
'Get number of Mounts
NumMounts = CLng(Var_Get(DataPath & "Mount.dat", "INIT", "NumMounts"))
'Resize array
ReDim MountData(0 To NumMounts) As MountData
'Fill list
For LoopC = 1 To NumMounts
For j = 1 To 8
Engine_Init_Grh MountData(LoopC).Walk(j), CLng(Var_Get(DataPath & "Mount.dat", LoopC, j)), 0
Next j
MountData(LoopC).Offset.X = CLng(Var_Get(DataPath & "Mount.dat", LoopC, "OffsetX"))
MountData(LoopC).Offset.Y = CLng(Var_Get(DataPath & "Mount.dat", LoopC, "OffsetY"))
Next LoopC
End Sub
Sub Engine_Init_ShieldData() '***************************************************************** 'Loads Shield.dat '***************************************************************** Dim LoopC As Long Dim j As Long
'Get number of Shields
NumShields = CLng(Var_Get(DataPath & "Shield.dat", "INIT", "NumShields"))
'Resize array
ReDim ShieldData(0 To NumShields) As ShieldData
'Fill list
For LoopC = 1 To NumShields
For j = 1 To 8
Engine_Init_Grh ShieldData(LoopC).Walk(j), CLng(Var_Get(DataPath & "Shield.dat", LoopC, j)), 0
Engine_Init_Grh ShieldData(LoopC).Attack(j), CLng(Var_Get(DataPath & "Shield.dat", LoopC, "a" & j)), 1
Next j
Next LoopC
End Sub</vb>
Find Engine_Render_Char and replace the whole sub with this (There's so many changes, this is the fast and easy way. You can pick out what's different from your code and make only the changes you want of course)
<vb>Private Sub Engine_Render_Char(ByVal CharIndex As Long, ByVal PixelOffsetX As Single, ByVal PixelOffsetY As Single)
'*************************************************** 'Draw a character to the screen by the CharIndex 'First variables are set, then all shadows drawn, then character drawn, then extras (emoticons, icons, etc) 'Any variables not handled in "Set the variables" are set in Shadow calls - do not call a second time in the 'normal character rendering calls '***************************************************
Dim TempGrh As Grh Dim Moved As Boolean Dim IconCount As Byte Dim IconOffset As Integer Dim LoopC As Byte Dim Green As Byte Dim RenderColor(1 To 4) As Long Dim TempBlock As MapBlock Dim TempBlock2 As MapBlock Dim HeadGrh As Grh Dim BodyGrh As Grh Dim WeaponGrh As Grh Dim MountGrh As Grh Dim ShieldGrh As Grh Dim HairGrh As Grh Dim WingsGrh As Grh Dim Offset As Position Dim IsOnMount As Boolean
'***** Set the variables *****
'Is char on mount?
If Not CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).GrhIndex = 0 Then
IsOnMount = True
Offset = CharList(CharIndex).Mount.Offset
End If
'Set the map block the char is on to the TempBlock, and the block above the user as TempBlock2
TempBlock = MapData(CharList(CharIndex).Pos.X, CharList(CharIndex).Pos.Y) If CharList(CharIndex).Pos.Y > 1 Then TempBlock2 = MapData(CharList(CharIndex).Pos.X, CharList(CharIndex).Pos.Y - 1)
RenderColor(1) = TempBlock2.Light(1) RenderColor(2) = TempBlock2.Light(2) RenderColor(3) = TempBlock.Light(3) RenderColor(4) = TempBlock.Light(4)
If CharList(CharIndex).Moving Then
'If needed, move left and right
If CharList(CharIndex).ScrollDirectionX <> 0 Then
CharList(CharIndex).MoveOffset.X = CharList(CharIndex).MoveOffset.X + ScrollPixelsPerFrameX * Sgn(CharList(CharIndex).ScrollDirectionX) * TickPerFrame
'Start animation
If IsOnMount Then
'Is Riding Mount
CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).Started = 1
CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).Started = 0
CharList(CharIndex).Body.Ride(CharList(CharIndex).Heading).Started = 1
Else
'Is using their own legs
CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).Started = 1
End If
'Char moved
Moved = True
'Check if we already got there
If (Sgn(CharList(CharIndex).ScrollDirectionX) = 1 And CharList(CharIndex).MoveOffset.X >= 0) Or (Sgn(CharList(CharIndex).ScrollDirectionX) = -1 And CharList(CharIndex).MoveOffset.X <= 0) Then
CharList(CharIndex).MoveOffset.X = 0
CharList(CharIndex).ScrollDirectionX = 0
End If
End If
'If needed, move up and down
If CharList(CharIndex).ScrollDirectionY <> 0 Then
CharList(CharIndex).MoveOffset.Y = CharList(CharIndex).MoveOffset.Y + ScrollPixelsPerFrameY * Sgn(CharList(CharIndex).ScrollDirectionY) * TickPerFrame
'Start animation
If IsOnMount Then
'Is Riding Mount
CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).Started = 1
CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).Started = 0
CharList(CharIndex).Body.Ride(CharList(CharIndex).Heading).Started = 1
Else
'Is using their own legs
CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).Started = 1
End If
'Char moved
Moved = True
'Check if we already got there
If (Sgn(CharList(CharIndex).ScrollDirectionY) = 1 And CharList(CharIndex).MoveOffset.Y >= 0) Or (Sgn(CharList(CharIndex).ScrollDirectionY) = -1 And CharList(CharIndex).MoveOffset.Y <= 0) Then
CharList(CharIndex).MoveOffset.Y = 0
CharList(CharIndex).ScrollDirectionY = 0
End If
End If End If
'Update movement reset timer If CharList(CharIndex).ScrollDirectionX = 0 Or CharList(CharIndex).ScrollDirectionY = 0 Then
'If done moving stop animation
If Not Moved Then
If CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).Started Then
'Stop animation
If IsOnMount Then
'Is Riding Mount
CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).Started = 0
CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).FrameCounter = 1
CharList(CharIndex).Body.Ride(CharList(CharIndex).Heading).Started = 0
CharList(CharIndex).Body.Ride(CharList(CharIndex).Heading).FrameCounter = 1
Else
'Is using own legs
CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).Started = 0
CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).FrameCounter = 1
End If
CharList(CharIndex).Moving = False
If CharList(CharIndex).ActionIndex = 1 Then CharList(CharIndex).ActionIndex = 0
End If
End If
End If
'Set the pixel offset PixelOffsetX = PixelOffsetX + CharList(CharIndex).MoveOffset.X PixelOffsetY = PixelOffsetY + CharList(CharIndex).MoveOffset.Y
'Save the values in the realpos variable CharList(CharIndex).RealPos.X = PixelOffsetX CharList(CharIndex).RealPos.Y = PixelOffsetY
'***** Render Shadows *****
'Draw Body If CharList(CharIndex).ActionIndex <= 1 Then
'Shadow
If IsOnMount Then
Engine_Render_Grh CharList(CharIndex).Body.Ride(CharList(CharIndex).Heading), PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Engine_Render_Grh CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Else
Engine_Render_Grh CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Engine_Render_Grh CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Engine_Render_Grh CharList(CharIndex).Shield.Walk(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
End If
Else
'Start attack animation
CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading).Started = 0
CharList(CharIndex).Weapon.Attack(CharList(CharIndex).Heading).FrameCounter = 1
'Shadow
Engine_Render_Grh CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, 1, 1, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, , 1
Engine_Render_Grh CharList(CharIndex).Weapon.Attack(CharList(CharIndex).Heading), PixelOffsetX, PixelOffsetY, True, True, False, ShadowColor, ShadowColor, ShadowColor, ShadowColor, , 1
'Check if animation has stopped
If CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading).Started = 0 Then CharList(CharIndex).ActionIndex = 0
End If
'Draw Head
If CharList(CharIndex).Aggressive > 0 Then
'Aggressive
If CharList(CharIndex).BlinkTimer > 0 Then
CharList(CharIndex).BlinkTimer = CharList(CharIndex).BlinkTimer - ElapsedTime
'Blinking
Engine_Render_Grh CharList(CharIndex).Head.AgrBlink(CharList(CharIndex).HeadHeading), PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y, True, False, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Else
'Normal
Engine_Render_Grh CharList(CharIndex).Head.AgrHead(CharList(CharIndex).HeadHeading), PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y, True, False, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
End If
Else
'Not Aggressive
If CharList(CharIndex).BlinkTimer > 0 Then
CharList(CharIndex).BlinkTimer = CharList(CharIndex).BlinkTimer - ElapsedTime
'Blinking
Engine_Render_Grh CharList(CharIndex).Head.Blink(CharList(CharIndex).HeadHeading), PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, True, False, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
Else
'Normal
Engine_Render_Grh CharList(CharIndex).Head.Head(CharList(CharIndex).HeadHeading), PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, True, False, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, 1
End If
End If
'Hair Engine_Render_Grh CharList(CharIndex).Hair.Hair(CharList(CharIndex).HeadHeading), PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y, True, False, True, ShadowColor, ShadowColor, ShadowColor, ShadowColor, , 1
'***** Render Character *****
'***** (When updating this, make sure you copy it to the NPCEditor and MapEditor, too!) *****
If IsOnMount Then
CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).FrameCounter
Else
CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).FrameCounter
End If
'The body, weapon and wings
If CharList(CharIndex).ActionIndex <= 1 Then
'Walking
If IsOnMount Then
BodyGrh = CharList(CharIndex).Body.Ride(CharList(CharIndex).Heading)
MountGrh = CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading)
' animate weapon/shield
CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).FrameCounter
CharList(CharIndex).Shield.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Mount.Walk(CharList(CharIndex).Heading).FrameCounter
Else
BodyGrh = CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading)
' animate weapon/shield
CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).FrameCounter
CharList(CharIndex).Shield.Walk(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Walk(CharList(CharIndex).Heading).FrameCounter
WeaponGrh = CharList(CharIndex).Weapon.Walk(CharList(CharIndex).Heading)
ShieldGrh = CharList(CharIndex).Shield.Walk(CharList(CharIndex).Heading)
End If
WingsGrh = CharList(CharIndex).Wings.Walk(CharList(CharIndex).Heading)
Else
'Attacking
BodyGrh = CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading)
WeaponGrh = CharList(CharIndex).Weapon.Attack(CharList(CharIndex).Heading)
WingsGrh = CharList(CharIndex).Wings.Attack(CharList(CharIndex).Heading)
CharList(CharIndex).Weapon.Attack(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading).FrameCounter
CharList(CharIndex).Shield.Attack(CharList(CharIndex).Heading).FrameCounter = CharList(CharIndex).Body.Attack(CharList(CharIndex).Heading).FrameCounter
End If
'The head
If CharList(CharIndex).Aggressive > 0 Then 'Aggressive
If CharList(CharIndex).BlinkTimer > 0 Then HeadGrh = CharList(CharIndex).Head.AgrBlink(CharList(CharIndex).HeadHeading) Else HeadGrh = CharList(CharIndex).Head.AgrHead(CharList(CharIndex).HeadHeading)
Else 'Non-aggressive
If CharList(CharIndex).BlinkTimer > 0 Then HeadGrh = CharList(CharIndex).Head.Blink(CharList(CharIndex).HeadHeading) Else HeadGrh = CharList(CharIndex).Head.Head(CharList(CharIndex).HeadHeading)
End If
'The hair
HairGrh = CharList(CharIndex).Hair.Hair(CharList(CharIndex).HeadHeading)
'*** NORTH / NORTHEAST *** (1.Weapon 2.Body 3.Head 4.Hair 5.Wings)
If CharList(CharIndex).Heading = NORTH Or CharList(CharIndex).Heading = NORTHEAST Then
Engine_Render_Grh MountGrh, PixelOffsetX, PixelOffsetY, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WeaponGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh ShieldGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh BodyGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HeadGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HairGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WingsGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
'*** EAST / SOUTHEAST *** (1.Body 2.Head 3.Hair 4.Wings 5.Weapon)
ElseIf CharList(CharIndex).Heading = EAST Or CharList(CharIndex).Heading = SOUTHEAST Then
Engine_Render_Grh MountGrh, PixelOffsetX, PixelOffsetY, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh ShieldGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh BodyGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HeadGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HairGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WingsGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WeaponGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
'*** SOUTH / SOUTHWEST *** (1.Wings 2.Body 3.Head 4.Hair 5.Weapon)
ElseIf CharList(CharIndex).Heading = SOUTH Or CharList(CharIndex).Heading = SOUTHWEST Then
Engine_Render_Grh WingsGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh BodyGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HeadGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HairGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WeaponGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh ShieldGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh MountGrh, PixelOffsetX, PixelOffsetY, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
'*** WEST / NORTHWEST *** (1.Weapon 1.Body 2.Head 3.Hair 4.Wings)
ElseIf CharList(CharIndex).Heading = WEST Or CharList(CharIndex).Heading = NORTHWEST Then
Engine_Render_Grh WeaponGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh MountGrh, PixelOffsetX, PixelOffsetY, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh BodyGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HeadGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh HairGrh, PixelOffsetX + CharList(CharIndex).Body.HeadOffset.X + Offset.X, PixelOffsetY + CharList(CharIndex).Body.HeadOffset.Y + Offset.Y, 1, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh ShieldGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
Engine_Render_Grh WingsGrh, PixelOffsetX + Offset.X, PixelOffsetY + Offset.Y, True, 0, True, RenderColor(1), RenderColor(2), RenderColor(3), RenderColor(4)
End If
'***** Render Extras *****
'Check to draw the health or not
If CharList(CharIndex).HealthPercent > 0 Then
'Draw name/health over head
Engine_Render_Text CharList(CharIndex).Name & " " & CharList(CharIndex).HealthPercent & "%", PixelOffsetX - 32 + Offset.X, PixelOffsetY - 36 + Offset.Y, 96, RenderColor(1), DT_TOP Or DT_CENTER
Else
'Draw name over head
Engine_Render_Text CharList(CharIndex).Name, PixelOffsetX - 32 + Offset.X, PixelOffsetY - 36 + Offset.Y, 96, RenderColor(1), DT_TOP Or DT_CENTER
End If
End Sub</vb>
Optional: Sound
Optional stuff here. If you want a sound to play when you mount or ride your mount, add this to the code above:
in the client, open TileEngine.bas
find this:
<vb>'Mount list Public Type MountData</vb>
add this:
<vb> MoveSndNum As Integer
EquipSndNum As Integer MoveSnd As DirectSoundSecondaryBuffer8 EquipSnd As DirectSoundSecondaryBuffer8</vb>
find Engine_Init_MountData and add this to the 'Fill List loop
<vb> MountData(LoopC).MoveSndNum = CLng(Var_Get(DataPath & "Mount.dat", LoopC, "MoveSnd"))
MountData(LoopC).EquipSndNum = CLng(Var_Get(DataPath & "Mount.dat", LoopC, "EquipSnd"</vb>
Find Engine_Init_TileEngine and add this above "'Start the engine"
<vb> 'Set Mount Sounds
Dim i As Integer
For i = 0 To UBound(MountData)
Sound_Set MountData(i).MoveSnd, MountData(i).MoveSndNum
Sound_Set MountData(i).EquipSnd, MountData(i).EquipSndNum
Next i</vb>
find Engine_Render_Char and locate this:
<vb>If CharList(CharIndex).Moving Then</vb>
further down find:
<vb> 'Start animation
If IsOnMount Then</vb>
right above the ELSE that follows it, add this:
<vb> 'Play Mount Movement Sound
If (Not CharList(CharIndex).Mount.MoveSnd.GetStatus = DSBSTATUS_PLAYING) Then
Sound_Play CharList(CharIndex).Mount.MoveSnd, DSBPLAY_DEFAULT
End If</vb>
further down find "'If needed, move up and down" and below that find "If IsOnMount Then" and right above the ELSE that follows it add this:
<vb> 'Play Mount Movement Sound
If (Not CharList(CharIndex).Mount.MoveSnd.GetStatus = DSBSTATUS_PLAYING) Then
Sound_Play CharList(CharIndex).Mount.MoveSnd, DSBPLAY_DEFAULT
End If</vb>
Now go to Data_Server_ChangeChar and find
<vb>If Not DontSetData Then CharList(CharIndex).Mount = MountData(CharMount)</vb>
and below that add this:
<vb> If (Not CharMount = 0) Then
Sound_Play MountData(CharMount).EquipSnd, DSBPLAY_DEFAULT
End If</vb>
Now open the Mount.dat file and add this to the bottom:
<vb>MoveSnd=10 EquipSnd=9 </vb>
Now download the sounds below and put them in the Sfx directory. Update the Sfx.ini file to "NumSfx=10"
Sounds: http://www.vbgore.com/forums/download/file.php?id=243
If the you have sound files by the name of 9 and 10, then change the above code to the next two free numbers and adjust Sfx.ini accordingly.
Now your horse will make an impressive sound when you mount and while you ride!
End
Ok, unless I missed something, that should be it. You now have shields and mounts. Ok, what I didn't mention before is that your character sprite (while riding the mount) is animated. He will "bounce" and such. Also, you do gain a speed boost with the mount. (in the database part of the tutorial, it is set with "stat_speed"). I designed it so that you can't attack while on the mount, and your weapon/shield are removed while on the mount (until you get back off). You will dismount automatically when attacking. Hope you like!
This tutorial is made by: GoreMania Corrected by: -