Upgrade 1.0.1 to 1.0.2
From VbGORE Visual Basic Online RPG Engine
This guide will lead you through how to upgrade Version 1.0.1 to Version 1.0.2. For help, please refer to the How to upgrade article. It is highly recommended you read it before ever upgrading.
Fix - Edge of map crashes
Open GameServer.vbp.
Find:
<vb>
If MapInfo(nPos.Map).Data(nPos.X, nPos.Y).UserIndex > 0 Then
X = MapInfo(nPos.Map).Data(nPos.X, nPos.Y).UserIndex
'Get the damage
Damage = NPC_AttackUser(NPCIndex, X)
'Send the attack packet
ConBuf.PreAllocate 12
ConBuf.Put_Byte DataCode.Combo_SlashSoundRotateDamage
ConBuf.Put_Integer NPCList(NPCIndex).Char.CharIndex
ConBuf.Put_Integer UserList(X).Char.CharIndex
ConBuf.Put_Long NPCList(NPCIndex).AttackGrh
ConBuf.Put_Byte NPCList(NPCIndex).AttackSfx
If Damage > 32000 Then ConBuf.Put_Integer 32000 Else ConBuf.Put_Integer Damage
Data_Send ToNPCArea, NPCIndex, ConBuf.Get_Buffer, NPCList(NPCIndex).Pos.Map
'Apply damage
NPC_AttackUser_ApplyDamage NPCIndex, X, Damage
NPC_AI_Attack = 1
Exit Function
End If
</vb>
Before, add:
<vb>
If nPos.X > 0 Then
If nPos.Y > 0 Then
If nPos.X <= MapInfo(nPos.Map).Width Then
If nPos.Y <= MapInfo(nPos.Map).Height Then
</vb>
After, add:
<vb>
End If
End If
End If
End If
</vb>
Find:
<vb>
'Check for a thralled NPC
If MapInfo(UserList(UserIndex).Pos.Map).Data(X, Y).NPCIndex Then
NPCIndex = MapInfo(UserList(UserIndex).Pos.Map).Data(X, Y).NPCIndex
If NPCList(NPCIndex).Flags.Thralled Then
If NPCList(NPCIndex).OwnerIndex = 0 Then
NPC_Kill NPCIndex
End If
End If
End If
</vb>
Before, add:
<vb>
If X > 0 Then
If Y > 0 Then
If X <= MapInfo(UserList(UserIndex).Pos.Map).Width Then
If Y <= MapInfo(UserList(UserIndex).Pos.Map).Height Then
</vb>
After, add:
<vb>
End If
End If
End If
End If
</vb>
Find:
<vb>
'If a legal pos and a NPC is found attack
If MapInfo(nPos.Map).Data(nPos.X, nPos.Y).NPCIndex > 0 Then
X = MapInfo(nPos.Map).Data(nPos.X, nPos.Y).NPCIndex
If NPCList(X).Attackable Then
If NPCList(X).Hostile Then
If NPCList(X).OwnerIndex <> NotSlaveOfUserIndex Then
'Get the damage
Damage = NPC_AttackNPC(NPCIndex, X)
'Send the attack packet
ConBuf.PreAllocate 12
ConBuf.Put_Byte DataCode.Combo_SlashSoundRotateDamage
ConBuf.Put_Integer NPCList(NPCIndex).Char.CharIndex
ConBuf.Put_Integer NPCList(X).Char.CharIndex
ConBuf.Put_Long NPCList(NPCIndex).AttackGrh
ConBuf.Put_Byte NPCList(NPCIndex).AttackSfx
If Damage > 32000 Then ConBuf.Put_Integer 32000 Else ConBuf.Put_Integer Damage
Data_Send ToNPCArea, X, ConBuf.Get_Buffer, NPCList(NPCIndex).Pos.Map
'Apply damage
NPC_Damage X, 0, Damage, NPCList(NPCIndex).Char.CharIndex
NPC_AI_AttackNPC = 1
Exit Function
End If
End If
End If
End If
</vb>
Before, add:
<vb>
If nPos.X > 0 Then
If nPos.Y > 0 Then
If nPos.X <= MapInfo(nPos.Map).Width Then
If nPos.Y <= MapInfo(nPos.Map).Height Then
</vb>
After, add:
<vb>
End If
End If
End If
End If
</vb>
Find:
<vb>
If AttackPos.X < 1 Or AttackPos.X > MapInfo(UserList(UserIndex).Pos.Map).Width Or AttackPos.Y <= 1 Or AttackPos.Y > MapInfo(UserList(UserIndex).Pos.Map).Height Then
</vb>
Replace with:
<vb>
If AttackPos.X < 1 Or AttackPos.X > MapInfo(UserList(UserIndex).Pos.Map).Width Or AttackPos.Y < 1 Or AttackPos.Y > MapInfo(UserList(UserIndex).Pos.Map).Height Then
</vb>
Fix - Thralling
Open GameServer.vbp.
In Data_GM_Thrall, find and delete:
<vb>
'Set up the NPC on the map / char array
MapInfo(NPCList(tIndex).Pos.Map).Data(NPCList(tIndex).Pos.X, NPCList(tIndex).Pos.Y).NPCIndex = tIndex
CharIndex = Server_NextOpenCharIndex
NPCList(NPCIndex).Char.CharIndex = CharIndex
CharList(CharIndex).Index = NPCIndex
CharList(CharIndex).CharType = CharType_NPC
</vb>
Fix - Spike field crashing
Open GameServer.vbp.
Find:
<vb>
If UserList(CasterIndex).Char.HeadHeading = NORTH Or UserList(CasterIndex).Char.HeadHeading = NORTHEAST Then
</vb>
Before, add:
<vb>
On Error Resume Next
</vb>
At the end of the same sub, find:
<vb>
'Display the user casting it on other people's screens ConBuf.PreAllocate 4 ConBuf.Put_Byte DataCode.User_CastSkill ConBuf.Put_Byte SkID.SpikeField ConBuf.Put_Integer UserList(CasterIndex).Char.CharIndex Data_Send ToMap, CasterIndex, ConBuf.Get_Buffer, UserList(CasterIndex).Pos.Map, PP_DisplaySpell
</vb>
After, add:
<vb>
On Error GoTo 0
</vb>
Fix - Attacking summoned NPCs
Open GameServer.vbp.
Find:
<vb>
Log "User_Attack: Found a NPC to attack", CodeTracker '//\\LOGLINE//\\
TargetIndex = MapInfo(AttackPos.Map).Data(AttackPos.X, AttackPos.Y).NPCIndex
If NPCList(TargetIndex).Attackable Then
</vb>
After, add:
<vb>
If NPCList(TargetIndex).OwnerIndex <> UserIndex Then
</vb>
Close the IF block. In the same sub, find:
<vb>
NPC_Damage TargetIndex, UserIndex, Damage
</vb>
After, add:
<vb>
End If
</vb>
Change - Updated translations
Go to the Message translations page, and copy the new translation files to the files found in \Data\Messages\.
Add - Packet caching
Open GameServer.vbp.
Find:
<vb> Type User 'Holds data for a user </vb>
Before, add:
<vb> Type Cache_Server_MakeChar
Body As Integer Head As Integer Heading As Byte X As Byte Y As Byte Speed As Byte Name As String Weapon As Integer Hair As Integer Wings As Integer HP As Byte MP As Byte ChatID As Byte CharType As Byte
End Type Type PacketCache
Server_MakeChar As Cache_Server_MakeChar
End Type </vb>
Find:
<vb>
Stats As UserStats 'Declares the user stats Flags As UserFlags 'Declares the user Flags Skills As Skills 'Declares the skills casted on the user
</vb>
After, add:
<vb>
PacketCache As PacketCache 'Typical users do NOT need to worry about the packet cache at all and just let it do its job
</vb>
Find:
<vb> Public Sub NPC_MakeChar( </vb>
Replace the whole sub with:
<vb> Public Sub NPC_MakeChar(ByVal sndRoute As Byte, ByVal sndIndex As Integer, ByVal NPCIndex As Integer, ByVal Map As Integer, ByVal X As Integer, ByVal Y As Integer, Optional ByVal SendPacket As Boolean = True)
'***************************************************************** 'Makes and places a NPC character '***************************************************************** Dim SndHP As Byte Dim SndMP As Byte Dim Flags As Integer Dim PacketSize As Long
Log "Call NPC_MakeChar(" & sndRoute & "," & sndIndex & "," & NPCIndex & "," & Map & "," & X & "," & Y & ")", CodeTracker '//\\LOGLINE//\\
'Place character on map MapInfo(Map).Data(X, Y).NPCIndex = NPCIndex
'Set alive flag NPCList(NPCIndex).Flags.NPCAlive = 1
'Set the hp/mp to send If NPCList(NPCIndex).ModStat(SID.MaxHP) > 0 Then SndHP = CByte((NPCList(NPCIndex).BaseStat(SID.MinHP) / NPCList(NPCIndex).ModStat(SID.MaxHP)) * 100) If NPCList(NPCIndex).ModStat(SID.MaxMAN) > 0 Then SndMP = CByte((NPCList(NPCIndex).BaseStat(SID.MinMAN) / NPCList(NPCIndex).ModStat(SID.MaxMAN)) * 100)
'NPCs wont be created with active spells
ZeroMemory NPCList(NPCIndex).Skills, Len(NPCList(NPCIndex).Skills)
'Find out what information needs to be sent
'Typical users do NOT need to worry about the packet cache system!
'Caching will only work when sending to a single client
If sndRoute = ToIndex Then
If sndIndex > LastUser Or sndIndex < 1 Then Exit Sub
PacketSize = 2
With UserList(sndIndex).PacketCache.Server_MakeChar
If NPCList(NPCIndex).Char.Body <> .Body Then
Flags = Flags Or 1
.Body = NPCList(NPCIndex).Char.Body
PacketSize = PacketSize + 2
End If
If NPCList(NPCIndex).Char.Head <> .Head Then
Flags = Flags Or 2
.Head = NPCList(NPCIndex).Char.Head
PacketSize = PacketSize + 2
End If
If NPCList(NPCIndex).Char.Heading <> .Heading Then
Flags = Flags Or 4
.Heading = NPCList(NPCIndex).Char.Heading
PacketSize = PacketSize + 1
End If
If X <> .X Then
Flags = Flags Or 8
.X = X
PacketSize = PacketSize + 1
End If
If Y <> .Y Then
Flags = Flags Or 16
.Y = Y
PacketSize = PacketSize + 1
End If
If NPCList(NPCIndex).BaseStat(SID.Speed) <> .Speed Then
Flags = Flags Or 32
.Speed = NPCList(NPCIndex).BaseStat(SID.Speed)
PacketSize = PacketSize + 1
End If
If NPCList(NPCIndex).Name <> .Name Then
Flags = Flags Or 64
.Name = NPCList(NPCIndex).Name
PacketSize = PacketSize + 1 + Len(.Name)
End If
If NPCList(NPCIndex).Char.Weapon <> .Weapon Then
Flags = Flags Or 128
.Weapon = NPCList(NPCIndex).Char.Weapon
PacketSize = PacketSize + 2
End If
If NPCList(NPCIndex).Char.Hair <> .Hair Then
Flags = Flags Or 256
.Hair = NPCList(NPCIndex).Char.Hair
PacketSize = PacketSize + 2
End If
If NPCList(NPCIndex).Char.Wings <> .Wings Then
Flags = Flags Or 512
.Wings = NPCList(NPCIndex).Char.Wings
PacketSize = PacketSize + 2
End If
If SndHP <> .HP Then
Flags = Flags Or 1024
.HP = SndHP
PacketSize = PacketSize + 1
End If
If SndMP <> .MP Then
Flags = Flags Or 2048
.MP = SndMP
PacketSize = PacketSize + 1
End If
If NPCList(NPCIndex).ChatID <> .ChatID Then
Flags = Flags Or 4096
.ChatID = NPCList(NPCIndex).ChatID
PacketSize = PacketSize + 1
End If
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
End With
Static asdf As Long
asdf = asdf + (22 + Len(NPCList(NPCIndex).Name)) - PacketSize
Debug.Print asdf
Else
PacketSize = 22 + Len(NPCList(NPCIndex).Name)
End If
'Send make character command to clients
If SendPacket Then
ConBuf.PreAllocate PacketSize
Else
ConBuf.Allocate PacketSize
End If
'Check whether to send cached or not
'CACHED
If sndRoute = ToIndex Then
ConBuf.Put_Byte DataCode.Server_MakeCharCached
ConBuf.Put_Integer Flags
If Flags And 1 Then ConBuf.Put_Integer NPCList(NPCIndex).Char.Body
If Flags And 2 Then ConBuf.Put_Integer NPCList(NPCIndex).Char.Head
If Flags And 4 Then ConBuf.Put_Byte NPCList(NPCIndex).Char.Heading
ConBuf.Put_Integer NPCList(NPCIndex).Char.CharIndex
If Flags And 8 Then ConBuf.Put_Byte X
If Flags And 16 Then ConBuf.Put_Byte Y
If Flags And 32 Then ConBuf.Put_Byte NPCList(NPCIndex).BaseStat(SID.Speed) 'We dont use modstat on speed since for one it may not have been updated
If Flags And 64 Then ConBuf.Put_String NPCList(NPCIndex).Name ' yet, along with theres nothing to mod the stat
If Flags And 128 Then ConBuf.Put_Integer NPCList(NPCIndex).Char.Weapon
If Flags And 256 Then ConBuf.Put_Integer NPCList(NPCIndex).Char.Hair
If Flags And 512 Then ConBuf.Put_Integer NPCList(NPCIndex).Char.Wings
If Flags And 1024 Then ConBuf.Put_Byte SndHP
If Flags And 2048 Then ConBuf.Put_Byte SndMP
If Flags And 4096 Then ConBuf.Put_Byte NPCList(NPCIndex).ChatID
If NPCList(NPCIndex).OwnerIndex > 0 Then
If Flags And 8192 Then ConBuf.Put_Byte ClientCharType_Slave
ConBuf.Put_Integer UserList(NPCList(NPCIndex).OwnerIndex).Char.CharIndex
Else
If Flags And 8192 Then ConBuf.Put_Byte ClientCharType_NPC
End If
'NOT CACHED
Else
ConBuf.Put_Byte DataCode.Server_MakeChar
ConBuf.Put_Integer NPCList(NPCIndex).Char.Body
ConBuf.Put_Integer NPCList(NPCIndex).Char.Head
ConBuf.Put_Byte NPCList(NPCIndex).Char.Heading
ConBuf.Put_Integer NPCList(NPCIndex).Char.CharIndex
ConBuf.Put_Byte X
ConBuf.Put_Byte Y
ConBuf.Put_Byte NPCList(NPCIndex).BaseStat(SID.Speed) 'We dont use modstat on speed since for one it may not have been updated
ConBuf.Put_String NPCList(NPCIndex).Name ' yet, along with theres nothing to mod the stat
ConBuf.Put_Integer NPCList(NPCIndex).Char.Weapon
ConBuf.Put_Integer NPCList(NPCIndex).Char.Hair
ConBuf.Put_Integer NPCList(NPCIndex).Char.Wings
ConBuf.Put_Byte SndHP
ConBuf.Put_Byte SndMP
ConBuf.Put_Byte NPCList(NPCIndex).ChatID
If NPCList(NPCIndex).OwnerIndex > 0 Then
ConBuf.Put_Byte ClientCharType_Slave
ConBuf.Put_Integer UserList(NPCList(NPCIndex).OwnerIndex).Char.CharIndex
Else
ConBuf.Put_Byte ClientCharType_NPC
End If
End If
'Send the NPC
If SendPacket Then Data_Send sndRoute, sndIndex, ConBuf.Get_Buffer, Map
End Sub </vb>
Find:
<vb>
Server_MakeChar As Byte
</vb>
After, add:
<vb>
Server_MakeCharCached As Byte
</vb>
Find:
<vb>
.Combo_SlashSoundRotateDamage = 109
</vb>
After, add:
<vb>
.Server_MakeCharCached = 110
</vb>
Open GameClient.vbp.
Find:
<vb>
Case .Server_MakeChar: Data_Server_MakeChar rBuf
</vb>
After, add:
<vb>
Case .Server_MakeCharCached: Data_Server_MakeCharCached rBuf
</vb>
In the TCP module, add:
<vb> Sub Data_Server_MakeCharCached(ByRef rBuf As DataBuffer)
'********************************************* '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)> (<OwnerCharIndex(I)>) '********************************************* Dim flags As Integer Dim Body As Integer Dim Head As Integer Dim Heading As Byte Dim CharIndex As Integer Dim X As Byte Dim Y As Byte Dim Speed As Byte Dim Name As String Dim Weapon As Integer Dim Hair As Integer Dim Wings As Integer Dim HP As Byte Dim MP As Byte Dim ChatID As Byte Dim CharType As Byte Dim OwnerChar As Integer
'Retrieve all the information
flags = rBuf.Get_Integer
If flags And 1 Then Body = rBuf.Get_Integer Else Body = PacketCache.Server_MakeChar.Body
If flags And 2 Then Head = rBuf.Get_Integer Else Head = PacketCache.Server_MakeChar.Head
If flags And 4 Then Heading = rBuf.Get_Byte Else Heading = PacketCache.Server_MakeChar.Heading
CharIndex = rBuf.Get_Integer
If flags And 8 Then X = rBuf.Get_Byte Else X = PacketCache.Server_MakeChar.X
If flags And 16 Then Y = rBuf.Get_Byte Else Y = PacketCache.Server_MakeChar.Y
If flags And 32 Then Speed = rBuf.Get_Byte Else Speed = PacketCache.Server_MakeChar.Speed
If flags And 64 Then Name = rBuf.Get_String Else Name = PacketCache.Server_MakeChar.Name
If flags And 128 Then Weapon = rBuf.Get_Integer Else Weapon = PacketCache.Server_MakeChar.Weapon
If flags And 256 Then Hair = rBuf.Get_Integer Else Hair = PacketCache.Server_MakeChar.Hair
If flags And 512 Then Wings = rBuf.Get_Integer Else Wings = PacketCache.Server_MakeChar.Wings
If flags And 1024 Then HP = rBuf.Get_Byte Else HP = PacketCache.Server_MakeChar.HP
If flags And 2048 Then MP = rBuf.Get_Byte Else MP = PacketCache.Server_MakeChar.MP
If flags And 4096 Then ChatID = rBuf.Get_Byte Else ChatID = PacketCache.Server_MakeChar.ChatID
If flags And 8192 Then CharType = rBuf.Get_Byte Else CharType = PacketCache.Server_MakeChar.CharType
'Check for the owner char index if the char is a slave NPC
If CharType = ClientCharType_Slave Then OwnerChar = rBuf.Get_Integer
'Store the new values for the cache
With PacketCache.Server_MakeChar
.Body = Body
.Head = Head
.Heading = Heading
.X = X
.Y = Y
.Speed = Speed
.Name = Name
.Weapon = Weapon
.Hair = Hair
.Wings = Wings
.HP = HP
.MP = MP
.ChatID = ChatID
.CharType = CharType
End With
'Create the character
Engine_Char_Make CharIndex, Body, Head, Heading, X, Y, Speed, Name, Weapon, Hair, Wings, ChatID, CharType, HP, MP
'Apply the owner index value CharList(CharIndex).OwnerChar = OwnerChar
End Sub </vb>
Find:
<vb> Public LastLootTime As Long </vb>
After, add:
<vb> 'Cached packets Type Cache_Server_MakeChar
Body As Integer Head As Integer Heading As Byte X As Byte Y As Byte Speed As Byte Name As String Weapon As Integer Hair As Integer Wings As Integer HP As Byte MP As Byte ChatID As Byte CharType As Byte
End Type Type PacketCache
Server_MakeChar As Cache_Server_MakeChar
End Type Public PacketCache As PacketCache </vb>
Fix - Char changing
Open GameServer.vbp.
Find:
<vb>
If ChangeFlags And 1 Then ConBuf.Put_Integer Body If ChangeFlags And 2 Then ConBuf.Put_Integer Head If ChangeFlags And 8 Then ConBuf.Put_Integer Weapon If ChangeFlags And 16 Then ConBuf.Put_Integer Hair If ChangeFlags And 32 Then ConBuf.Put_Integer Wings
</vb>
Replace with:
<vb>
If ChangeFlags And 1 Then ConBuf.Put_Integer Body If ChangeFlags And 2 Then ConBuf.Put_Integer Head If ChangeFlags And 4 Then ConBuf.Put_Integer Weapon If ChangeFlags And 8 Then ConBuf.Put_Integer Hair If ChangeFlags And 16 Then ConBuf.Put_Integer Wings
</vb>
Fix - Faster map loading
Open GameServer.vbp.
Find:
<vb> Public Sub User_UpdateMap(ByVal UserIndex As Integer) </vb>
Replace the whole sub with:
<vb> Public Sub User_UpdateMap(ByVal UserIndex As Integer)
'***************************************************************** 'Updates a user with the place of all chars in the Map '*****************************************************************
Dim Map As Integer Dim X As Byte Dim Y As Byte Dim i As Long
Log "Call User_UpdateMap(" & UserIndex & ")", CodeTracker '//\\LOGLINE//\\
Map = UserList(UserIndex).Pos.Map 'Make sure the map is in memory If MapInfo(Map).DataLoaded = 0 Then Exit Sub
'Send user char's pos
Log "User_UpdateMap: For X = 1 to " & UBound(MapUsers(Map).Index()), CodeTracker '//\\LOGLINE//\\
For X = 1 To UBound(MapUsers(Map).Index())
User_MakeChar ToIndex, UserIndex, MapUsers(Map).Index(X), Map, UserList(MapUsers(Map).Index(X)).Pos.X, UserList(MapUsers(Map).Index(X)).Pos.Y
Next X
'Clear the buffer ConBuf.Clear
'Place chars and objects
For Y = 1 To MapInfo(Map).Height
For X = 1 To MapInfo(Map).Width
'NPC update
If MapInfo(Map).Data(X, Y).NPCIndex Then
NPC_MakeChar ToIndex, UserIndex, MapInfo(Map).Data(X, Y).NPCIndex, Map, X, Y, False
End If
'Object update
If MapInfo(Map).ObjTile(X, Y).NumObjs > 0 Then
For i = 1 To MapInfo(Map).ObjTile(X, Y).NumObjs
If MapInfo(Map).ObjTile(X, Y).ObjInfo(i).ObjIndex Then
ConBuf.Allocate 7
ConBuf.Put_Byte DataCode.Server_MakeObject
ConBuf.Put_Long ObjData.GrhIndex(MapInfo(Map).ObjTile(X, Y).ObjInfo(i).ObjIndex)
ConBuf.Put_Byte X
ConBuf.Put_Byte Y
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer, Map, PP_GroundObjects
End If
Next i
End If
Next X Next Y
'Send the buffer if it exists If ConBuf.HasBuffer Then Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer, Map
End Sub </vb>
Find:
<vb> Public Sub NPC_MakeChar(ByVal sndRoute As Byte, ByVal sndIndex As Integer, ByVal NPCIndex As Integer, ByVal Map As Integer, ByVal X As Integer, ByVal Y As Integer) </vb>
Replace with:
<vb> Public Sub NPC_MakeChar(ByVal sndRoute As Byte, ByVal sndIndex As Integer, ByVal NPCIndex As Integer, ByVal Map As Integer, ByVal X As Integer, ByVal Y As Integer, Optional ByVal SendPacket As Boolean = True) </vb>
In that same sub, find:
<vb>
ConBuf.PreAllocate 22 + Len(NPCList(NPCIndex).Name)
</vb>
Replace with:
<vb>
If SendPacket Then
ConBuf.PreAllocate 22 + Len(NPCList(NPCIndex).Name)
Else
ConBuf.Allocate 22 + Len(NPCList(NPCIndex).Name)
End If
</vb>
Again in that sub, find:
<vb>
'Send the NPC Data_Send sndRoute, sndIndex, ConBuf.Get_Buffer, Map
</vb>
Replace with:
<vb>
'Send the NPC If SendPacket Then Data_Send sndRoute, sndIndex, ConBuf.Get_Buffer, Map
</vb>
Open GameServer.vbp.
Find:
<vb>
Shell App.Path & "\ToolServerFPSViewer.exe", vbMaximizedFocus
</vb>
Replace with:
<vb>
Shell App.Path & "\ToolServerFPSViewer.exe " & Chr$(34) & LogPath & ServerID & "\serverfps.txt" & Chr$(34), vbMaximizedFocus
</vb>
Fix - NPC chat BEGINFILE
Open GameClient.vbp.
Find:
<vb>
Loop While UCase$(ln) <> "BEGINFILE"
</vb>
Replace with:
<vb>
Loop While UCase$(Left$(ln, 9)) <> "BEGINFILE"
</vb>
Fix - Stat updating on spells running out
Open GameServer.vbp.
Find:
<vb>
'*** Update the counters ***
If UpdateUserCounters Then 'Bless
If UserList(UserIndex).Counters.BlessCounter > 0 Then
If UserList(UserIndex).Counters.BlessCounter < timeGetTime Then
UserList(UserIndex).Skills.Bless = 0
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconBlessed
ConBuf.Put_Byte 0
ConBuf.Put_Integer UserList(UserIndex).Char.CharIndex
Data_Send ToMap, UserIndex, ConBuf.Get_Buffer, UserList(UserIndex).Pos.Map, PP_StatusIcons
End If
End If 'Protection
If UserList(UserIndex).Counters.ProtectCounter > 0 Then
If UserList(UserIndex).Counters.ProtectCounter < timeGetTime Then
UserList(UserIndex).Skills.Protect = 0
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconProtected
ConBuf.Put_Byte 0
ConBuf.Put_Integer UserList(UserIndex).Char.CharIndex
Data_Send ToMap, UserIndex, ConBuf.Get_Buffer, UserList(UserIndex).Pos.Map, PP_StatusIcons
End If
End If 'Strengthen
If UserList(UserIndex).Counters.StrengthenCounter > 0 Then
If UserList(UserIndex).Counters.StrengthenCounter < timeGetTime Then
UserList(UserIndex).Skills.Strengthen = 0
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconStrengthened
ConBuf.Put_Byte 0
ConBuf.Put_Integer UserList(UserIndex).Char.CharIndex
Data_Send ToMap, UserIndex, ConBuf.Get_Buffer, UserList(UserIndex).Pos.Map, PP_StatusIcons
End If
End If 'Spell exhaustion
</vb>
Replace with:
<vb>
'*** Update the counters ***
If UpdateUserCounters Then 'Bless
If UserList(UserIndex).Counters.BlessCounter > 0 Then
If UserList(UserIndex).Counters.BlessCounter < timeGetTime Then
UserList(UserIndex).Skills.Bless = 0
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconBlessed
ConBuf.Put_Byte 0
ConBuf.Put_Integer UserList(UserIndex).Char.CharIndex
Data_Send ToMap, UserIndex, ConBuf.Get_Buffer, UserList(UserIndex).Pos.Map, PP_StatusIcons
User_UpdateModStats UserIndex
End If
End If 'Protection
If UserList(UserIndex).Counters.ProtectCounter > 0 Then
If UserList(UserIndex).Counters.ProtectCounter < timeGetTime Then
UserList(UserIndex).Skills.Protect = 0
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconProtected
ConBuf.Put_Byte 0
ConBuf.Put_Integer UserList(UserIndex).Char.CharIndex
Data_Send ToMap, UserIndex, ConBuf.Get_Buffer, UserList(UserIndex).Pos.Map, PP_StatusIcons
User_UpdateModStats UserIndex
End If
End If 'Strengthen
If UserList(UserIndex).Counters.StrengthenCounter > 0 Then
If UserList(UserIndex).Counters.StrengthenCounter < timeGetTime Then
UserList(UserIndex).Skills.Strengthen = 0
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconStrengthened
ConBuf.Put_Byte 0
ConBuf.Put_Integer UserList(UserIndex).Char.CharIndex
Data_Send ToMap, UserIndex, ConBuf.Get_Buffer, UserList(UserIndex).Pos.Map, PP_StatusIcons
User_UpdateModStats UserIndex
End If
End If 'Spell exhaustion
</vb>
Add - Walking through slave NPCs
Open GameServer.vbp.
Find:
<vb>
MapInfo(UserList(UserIndex).Pos.Map).Data(UserList(UserIndex).Pos.X, UserList(UserIndex).Pos.Y).UserIndex = UserIndex
</vb>
After, add:
<vb>
'If there is a slave that belongs to the user on the tile, switch places with it
If MapInfo(UserList(UserIndex).Pos.Map).Data(nPos.X, nPos.Y).NPCIndex > 0 Then
i = MapInfo(UserList(UserIndex).Pos.Map).Data(nPos.X, nPos.Y).NPCIndex
If NPCList(i).OwnerIndex = UserIndex Then
Select Case nHeading
Case NORTH: NewHeading = SOUTH
Case EAST: NewHeading = WEST
Case SOUTH: NewHeading = NORTH
Case WEST: NewHeading = EAST
Case NORTHEAST: NewHeading = SOUTHWEST
Case SOUTHEAST: NewHeading = NORTHWEST
Case NORTHWEST: NewHeading = SOUTHEAST
Case SOUTHWEST: NewHeading = NORTHEAST
End Select
NPC_MoveChar i, NewHeading
End If
End If
</vb>
In the same sub, at the top, add:
<vb> Dim i As Integer Dim NewHeading As Byte </vb>
Find:
<vb>
If Server_LegalPos(UserList(UserIndex).Pos.Map, nPos.X, nPos.Y, nHeading) Then
</vb>
Replace with:
<vb>
If Server_LegalPos(UserList(UserIndex).Pos.Map, nPos.X, nPos.Y, nHeading, , True) Then
</vb>
Find:
<vb> Public Function Server_LegalPos(ByVal Map As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal Heading As Byte, Optional ByVal CheckWarps As Boolean = False) As Boolean </vb>
Replace with:
<vb> Public Function Server_LegalPos(ByVal Map As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal Heading As Byte, Optional ByVal CheckWarps As Boolean = False, Optional ByVal IgnoreSlaves As Boolean = False) As Boolean </vb>
Find:
<vb>
If .NPCIndex > 0 Then
Log "Rtrn Server_LegalPos = " & Server_LegalPos, CodeTracker '//\\LOGLINE//\\
Exit Function
End If
</vb>
Replace with:
<vb>
If .NPCIndex > 0 Then
'Check if we count whether our slave NPCs count as blocked or not
If IgnoreSlaves Then
If NPCList(.NPCIndex).OwnerIndex = 0 Then
Log "Rtrn Server_LegalPos = " & Server_LegalPos, CodeTracker '//\\LOGLINE//\\
Exit Function
End If
Else
Log "Rtrn Server_LegalPos = " & Server_LegalPos, CodeTracker '//\\LOGLINE//\\
Exit Function
End If
End If
</vb>
Open GameClient.vbp.
Find:
<vb>
'Check for character
For i = 1 To LastChar
If CharList(i).Active Then
If CharList(i).Pos.X = X Then
If CharList(i).Pos.Y = Y Then Exit Function
End If
End If
Next i
</vb>
Replace with:
<vb>
'Check for character
For i = 1 To LastChar
If CharList(i).Active Then
If CharList(i).Pos.X = X Then
If CharList(i).Pos.Y = Y Then
If CharList(i).OwnerChar <> UserCharIndex Then
Exit Function
End If
End If
End If
End If
Next i
</vb>
Fix - Accidental inventory dropping
Open GameClient.vbp.
Find:
<vb>
'Inventory -> Inventory (change slot)
If DragSourceWindow = InventoryWindow Then
If ShowGameWindow(InventoryWindow) Then
With GameWindow.Inventory
If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X, .Screen.Y, .Screen.Width, .Screen.Height) Then
For i = 1 To 49
If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Image(i).X + .Screen.X, .Image(i).Y + .Screen.Y, .Image(i).Width, .Image(i).Height) Then
If DragItemSlot <> i Then
'Switch slots
sndBuf.Allocate 3
sndBuf.Put_Byte DataCode.User_ChangeInvSlot
sndBuf.Put_Byte DragItemSlot
sndBuf.Put_Byte i
'Clear and leave
DragSourceWindow = 0
DragItemSlot = 0
Exit Sub
End If
End If
Next i
End If
End With
End If
End If
</vb>
Replace with:
<vb>
'Inventory -> Inventory (change slot)
If DragSourceWindow = InventoryWindow Then
If ShowGameWindow(InventoryWindow) Then
With GameWindow.Inventory
If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Screen.X, .Screen.Y, .Screen.Width, .Screen.Height) Then
For i = 1 To 49
If Engine_Collision_Rect(MousePos.X, MousePos.Y, 1, 1, .Image(i).X + .Screen.X, .Image(i).Y + .Screen.Y, .Image(i).Width, .Image(i).Height) Then
If DragItemSlot <> i Then
'Switch slots
sndBuf.Allocate 3
sndBuf.Put_Byte DataCode.User_ChangeInvSlot
sndBuf.Put_Byte DragItemSlot
sndBuf.Put_Byte i
'Clear and leave
DragSourceWindow = 0
DragItemSlot = 0
Exit Sub
End If
End If
Next i
'Clear and leave
DragSourceWindow = 0
DragItemSlot = 0
Exit Sub
End If
End With
End If
End If
</vb>
Change - Encryptions modules
Replace \Code\Common Code\Encryptions.bas with that found in v1.0.2.
Replace \Code\Common Code\EncryptionsEX.bas with that found in v1.0.2.
Links for the new versions will be up after v1.0.2's release.
Add - OBJTYPE_USEINIFINITE
Open GameServer.vbp.
Find:
<vb> Public Const OBJTYPE_WINGS As Byte = 4 'Wings </vb>
After, add:
<vb> Public Const OBJTYPE_USEINFINITE As Byte = 5 'USEONCE object, minus the removal after usage </vb>
Find:
<vb>
Case OBJTYPE_USEONCE
</vb>
Replace with:
<vb>
Case OBJTYPE_USEONCE, OBJTYPE_USEINFINITE
</vb>
Go to line right below:
<vb>
'Remove from inventory
UserList(UserIndex).Object(Slot).Amount = UserList(UserIndex).Object(Slot).Amount - 1
If UserList(UserIndex).Object(Slot).Amount <= 0 Then UserList(UserIndex).Object(Slot).ObjIndex = 0
<vb>
Replace with:
<vb>
'Remove from inventory
If ObjData.ObjType(ObjIndex) = OBJTYPE_USEONCE Then
UserList(UserIndex).Object(Slot).Amount = UserList(UserIndex).Object(Slot).Amount - 1
If UserList(UserIndex).Object(Slot).Amount <= 0 Then UserList(UserIndex).Object(Slot).ObjIndex = 0
End If
</vb>
Add - User_GiveSkill routine
Open \Data\Messages\_nummessages.ini.
Find:
<ini> NumMessages=136 </ini>
Replace with:
<ini> NumMessages=137 </ini>
Open \Data\Messages\english.ini.
Add to the end:
<ini> --User can't learn a skill that was attempted to be given to them 137=You are unable to learn <skill>. </ini>
Open GameClient.vbp.
Find:
<vb>
Case 134
Str1 = rBuf.Get_String
Engine_AddToChatTextBuffer Replace$(Message(134), "<name>", Str1), FontColor_Quest
</vb>
After, add:
<vb>
Case 137
Engine_AddToChatTextBuffer Message(137), FontColor_Info
</vb>
Open GameServer.vbp.
In Users module, add:
<vb> Public Sub User_GiveSkill(ByVal UserIndex As Integer, ByVal SkillID As Byte)
'***************************************************************** 'Gives a user a skill they don't know, or tells them they already know it '***************************************************************** Dim s As String
'Check for a valid skill ID If SkillID <= 0 Then Exit Sub If SkillID > NumSkills Then Exit Sub
'Store the skill name s = Server_SkillIDtoSkillName(SkillID)
'Make sure the user can learn the skill
If Skill_ValidSkillForClass(UserList(UserIndex).Class, SkillID) Then
'Check whether the user knows the skill or not
If UserList(UserIndex).KnownSkills(SkillID) = 1 Then
'User already knew the skill
ConBuf.PreAllocate 3 + Len(s)
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 5
ConBuf.Put_String s
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer
Else
'User learns the new skill
ConBuf.PreAllocate 3 + Len(s)
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 6
ConBuf.Put_String s
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer
'Give the user the skill
UserList(UserIndex).KnownSkills(SkillID) = 1
User_SendKnownSkills UserIndex
End If
Else
'User can't learn the skill
ConBuf.PreAllocate 3 + Len(s)
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 137
ConBuf.Put_String s
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer
End If
End Sub </vb>
Find:
<vb>
If QuestData(UserList(UserIndex).Quest(UserQuestSlot)).FinishLearnSkill > 0 Then
If Skill_ValidSkillForClass(UserList(UserIndex).Class, QuestData(UserList(UserIndex).Quest(UserQuestSlot)).FinishLearnSkill) Then
If UserList(UserIndex).KnownSkills(QuestData(UserList(UserIndex).Quest(UserQuestSlot)).FinishLearnSkill) = 1 Then
'User already knew the skill
s = Server_SkillIDtoSkillName(QuestData(UserList(UserIndex).Quest(UserQuestSlot)).FinishLearnSkill)
ConBuf.PreAllocate 3 + Len(s)
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 5
ConBuf.Put_String s
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer
Else
'User learns the new skill
s = Server_SkillIDtoSkillName(QuestData(UserList(UserIndex).Quest(UserQuestSlot)).FinishLearnSkill)
ConBuf.PreAllocate 3 + Len(s)
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 6
ConBuf.Put_String s
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer
'Give the user the skill
UserList(UserIndex).KnownSkills(QuestData(UserList(UserIndex).Quest(UserQuestSlot)).FinishLearnSkill) = 1
User_SendKnownSkills UserIndex
End If
End If
End If
</vb>
Replace with:
<vb>
If QuestData(UserList(UserIndex).Quest(UserQuestSlot)).FinishLearnSkill > 0 Then
User_GiveSkill UserIndex, QuestData(UserList(UserIndex).Quest(UserQuestSlot)).FinishLearnSkill
End If
</vb>
Fix - Tile buffer calculation
Open GameClient.vbp.
Find:
<vb>
If ByFlags And 1 Then MapData(X, Y).Blocked = MapBuf.Get_Byte Else MapData(X, Y).Blocked = 0</vb>
Replace all code between the previously mentioned line of code and this line:
<vb>
'Set light to default (-1) - it will be set again if it is not -1 from the code below
</vb>
With the following:
<vb>
'Graphic layers
If ByFlags And 2 Then
MapData(X, Y).Graphic(1).GrhIndex = MapBuf.Get_Long
Engine_Init_Grh MapData(X, Y).Graphic(1), MapData(X, Y).Graphic(1).GrhIndex
'Find the size of the largest tile used
If LargestTileSize < GrhData(MapData(X, Y).Graphic(1).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(1).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(1).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(1).GrhIndex).pixelHeight
End If
End If
If ByFlags And 4 Then
MapData(X, Y).Graphic(2).GrhIndex = MapBuf.Get_Long
Engine_Init_Grh MapData(X, Y).Graphic(2), MapData(X, Y).Graphic(2).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(2).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(2).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(2).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(2).GrhIndex).pixelHeight
End If
End If
If ByFlags And 8 Then
MapData(X, Y).Graphic(3).GrhIndex = MapBuf.Get_Long
Engine_Init_Grh MapData(X, Y).Graphic(3), MapData(X, Y).Graphic(3).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(3).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(3).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(3).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(3).GrhIndex).pixelHeight
End If
End If
If ByFlags And 16 Then
MapData(X, Y).Graphic(4).GrhIndex = MapBuf.Get_Long
Engine_Init_Grh MapData(X, Y).Graphic(4), MapData(X, Y).Graphic(4).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(4).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(4).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(4).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(4).GrhIndex).pixelHeight
End If
End If
If ByFlags And 32 Then
MapData(X, Y).Graphic(5).GrhIndex = MapBuf.Get_Long
Engine_Init_Grh MapData(X, Y).Graphic(5), MapData(X, Y).Graphic(5).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(5).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(5).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(5).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(5).GrhIndex).pixelHeight
End If
End If
If ByFlags And 64 Then
MapData(X, Y).Graphic(6).GrhIndex = MapBuf.Get_Long
Engine_Init_Grh MapData(X, Y).Graphic(6), MapData(X, Y).Graphic(6).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(6).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(6).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(6).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(6).GrhIndex).pixelHeight
End If
End If
</vb>
Open MapEditor.vbp.
Find:
<vb>
'Graphic layers
</vb>
Replace all code between the previously mentioned line of code and this line:
<vb>
'Set light to default (-1) - it will be set again if it is not -1 from the code below
</vb>
With the following:
<vb>
If ByFlags And 2 Then
Get #MapNum, , MapData(X, Y).Graphic(1).GrhIndex
Engine_Init_Grh MapData(X, Y).Graphic(1), MapData(X, Y).Graphic(1).GrhIndex
'Find the size of the largest tile used
If LargestTileSize < GrhData(MapData(X, Y).Graphic(1).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(1).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(1).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(1).GrhIndex).pixelHeight
End If
End If
If ByFlags And 4 Then
Get #MapNum, , MapData(X, Y).Graphic(2).GrhIndex
Engine_Init_Grh MapData(X, Y).Graphic(2), MapData(X, Y).Graphic(2).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(2).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(2).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(2).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(2).GrhIndex).pixelHeight
End If
End If
If ByFlags And 8 Then
Get #MapNum, , MapData(X, Y).Graphic(3).GrhIndex
Engine_Init_Grh MapData(X, Y).Graphic(3), MapData(X, Y).Graphic(3).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(3).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(3).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(3).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(3).GrhIndex).pixelHeight
End If
End If
If ByFlags And 16 Then
Get #MapNum, , MapData(X, Y).Graphic(4).GrhIndex
Engine_Init_Grh MapData(X, Y).Graphic(4), MapData(X, Y).Graphic(4).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(4).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(4).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(4).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(4).GrhIndex).pixelHeight
End If
End If
If ByFlags And 32 Then
Get #MapNum, , MapData(X, Y).Graphic(5).GrhIndex
Engine_Init_Grh MapData(X, Y).Graphic(5), MapData(X, Y).Graphic(5).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(5).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(5).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(5).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(5).GrhIndex).pixelHeight
End If
End If
If ByFlags And 64 Then
Get #MapNum, , MapData(X, Y).Graphic(6).GrhIndex
Engine_Init_Grh MapData(X, Y).Graphic(6), MapData(X, Y).Graphic(6).GrhIndex
If LargestTileSize < GrhData(MapData(X, Y).Graphic(6).GrhIndex).pixelWidth Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(6).GrhIndex).pixelWidth
End If
If LargestTileSize < GrhData(MapData(X, Y).Graphic(6).GrhIndex).pixelHeight Then
LargestTileSize = GrhData(MapData(X, Y).Graphic(6).GrhIndex).pixelHeight
End If
End If
</vb>
Fix - Sign image
Replace file \Grh\27.png with the file of the same name found in v1.0.2:
Fix - Save password saving
Open GameClient.vbp.
Find:
<vb>
Var_Write DataPath & "Game.ini", "INIT", "SavePass", Val(SavePass) * -1
</vb>
Replace with:
<vb>
Var_Write DataPath & "Game.ini", "INIT", "SavePass", -CInt(SavePass)
</vb>