Alternate Inventory

From VbGORE Visual Basic Online RPG Engine

Name: Benjamin Justice

Credit: not required, but would make me happy ^^

Feature: This is a "help" to exchange the Inventory with a more common system. NOT A COPY PASTE TUTORIAL! There will be lots of work to do after the tutorial (individually for your project)

Difficulty: very hard

Edits: Client, Server, Database

Details: It replaces the Inventory system with 1 very simialaer to lineage 2

Contents

Warning

This Guide is a very heavy modification, without optimizations here! Many things remain very buggy, you will have to rewrite Paperdolling partially if you wish for it to work.

Difficulty: Intermediate-Expert

*untested*

Hope it works now... It is not COMPLETE, you will have major problems with Paperdolling and shops aswell as warehouses. But the main stuff is done. My problem is I can only compare my code to vbGORE and try to extract my Inventory so it will work in vbGORE :/


About

This is the Inventory System that we use in Aleron It is similar to the Inventory System used in Lineage II. Each Item occupies 1 Slot. You drag and drop your Equipment into the Equip Slots. For those familiar with Diablo's Inventory, Equipping works the same way :)

This guide is written by Zanval Feel free to write questions and feedback to me!

Preparations

vbGOREs Inventory doesnt have room for the Equip Slots SO you should replace the Graphics with one that has these Slots

I will provide Alerons Basic Inventory Graphics which has already been replaced. Yes I made this myself xD Yes it sucks xD Inventory.jpg

The .ini entries for this Inventory:

ImageOffsetX=43
ImageOffsetY=287
ImageSpaceX=6
ImageSpaceY=6
Grh=***YOUR VALUE HERE***
Arm1X=135
Arm1Y=132
Arm2X=211
Arm2Y=132
BodyX=189
BodyY=132


Lets start, shall we?

Server Side Edits

Declares.bas

Find:

'************ Object types ************
Public Const MaxObjAmount As Integer = 100          'Maximum number you can hold of an item (if Stacking <= 0) - works as the "default value"
Public Const MAX_INVENTORY_SLOTS As Byte = 49       'Maximum number of inventory slots - value must be equal to that of the client

Replace with:

Public Const MaxObjAmount As Integer = 100          'Maximum number you can hold of an item (if Stacking <= 0) - works as the "default value"
Public Const MIN_INVENTORY_SLOTS As Byte = 32       'Inventory SIze WITHOUT Equip Slots
Public Const MAX_INVENTORY_SLOTS As Byte = 39       'Inventory Size INCLUDING Equip Slots'
Public Const EQUIP_ARM1 As Byte = 33                'Right Hand Equip Slot
Public Const EQUIP_ARM2 As Byte = 34                'Left Hand Equip Slot
Public Const EQUIP_HEAD As Byte = 37                'Head Equip Slot
Public Const EQUIP_BODY As Byte = 38                'Body Equip Slot
Public Const EQUIP_WINGS As Byte = 39               'Wings Equip Slot

Find:

Type UserOBJ    'Objects the user has
   ObjIndex As Long    'Index of the object
   Amount As Long      'Amount of the objects
   Equipped As Byte    'If the object is equipted

Replace with:

Type UserOBJ    'Objects the user has
   ObjIndex As Long    'Index of the object
   Amount As Long      'Amount of the objects
   Equip As Byte    'Which slot the Item can be equipped to

Find:

 Bank(1 To MAX_INVENTORY_SLOTS) As Obj       'The user's bank items

Replace with:

 Bank(1 To MIN_INVENTORY_SLOTS) As Obj       'The user's bank items

FileIO.bas

In:

   'Fill in the data for the objects
   Do While Not DB_RS.EOF   'Loop until we reach the end of the recordset
       With TempObjData

Add:

            .Equip = Val(DB_RS!Equip)

In:

Public Sub Load_User

Find:

    'Inventory string
   If LenB(InvStr) Then
       Log "Load_User: Splitting inventory string (" & InvStr & ")", CodeTracker '//\\LOGLINE//\\
       TempStr = Split(InvStr, vbNewLine)  'Split up the inventory slots
       For i = 0 To UBound(TempStr)        'Loop through the slots
           Log "Load_User: Splitting item data (" & TempStr(i) & ")", CodeTracker '//\\LOGLINE//\\
           TempStr2 = Split(TempStr(i), " ")   'Split up the slot, objindex, amount and equipted (in that order)
           If Val(TempStr2(0)) <= MAX_INVENTORY_SLOTS Then
               With UserList(UserIndex).Object(Val(TempStr2(0)))
                   .ObjIndex = Val(TempStr2(1))
                   .Amount = Val(TempStr2(2))
                   .Equipped = Val(TempStr2(3))
               End With
           Else '//\\LOGLINE//\\
               Log "Load_User: User has too many inventory slots - tried applying slot " & Val(TempStr2(0)), CriticalError '//\\LOGLINE//\\
           End If
       Next i
   End If

Replace With:

    'Inventory string
   If LenB(InvStr) Then
       Log "Load_User: Splitting inventory string (" & InvStr & ")", CodeTracker '//\\LOGLINE//\\
       TempStr = Split(InvStr, vbNewLine)  'Split up the inventory slots
       For i = 0 To UBound(TempStr)        'Loop through the slots
           Log "Load_User: Splitting item data (" & TempStr(i) & ")", CodeTracker '//\\LOGLINE//\\
           TempStr2 = Split(TempStr(i), " ")   'Split up the slot, objindex, amount and equipted (in that order)
           If Val(TempStr2(0)) <= MAX_INVENTORY_SLOTS Then
               With UserList(UserIndex).Object(Val(TempStr2(0)))
                   .ObjIndex = Val(TempStr2(1))
                   .Amount = Val(TempStr2(2))
                   .Equip = Val(TempStr2(3))
               End With
           Else '//\\LOGLINE//\\
               Log "Load_User: User has too many inventory slots - tried applying slot " & Val(TempStr2(0)), CriticalError '//\\LOGLINE//\\
           End If
       Next i
   End If

Find:

   'Bank string
   If LenB(BankStr) Then
       Log "Load_User: Splitting bank string (" & InvStr & ")", CodeTracker '//\\LOGLINE//\\
       TempStr = Split(BankStr, vbNewLine) 'Split the bank slots
       For i = 0 To UBound(TempStr)        'Loop through the slots
           TempStr2 = Split(TempStr(i), " ")   'Split up the slot, objindex and amount (in that order)
           If Val(TempStr2(0)) <= MAX_INVENTORY_SLOTS Then
               With UserList(UserIndex).Bank(Val(TempStr2(0)))
                   .ObjIndex = Val(TempStr2(1))
                   .Amount = Val(TempStr2(2))
               End With
           Else '//\\LOGLINE//\\
               Log "Load_User: User has too many bank slots - tried applying slot " & Val(TempStr2(0)), CriticalError '//\\LOGLINE//\\
           End If
       Next i
   End If

Replace With:

   'Bank string
   If LenB(BankStr) Then
       Log "Load_User: Splitting bank string (" & InvStr & ")", CodeTracker '//\\LOGLINE//\\
       TempStr = Split(BankStr, vbNewLine) 'Split the bank slots
       For i = 0 To UBound(TempStr)        'Loop through the slots
           TempStr2 = Split(TempStr(i), " ")   'Split up the slot, objindex and amount (in that order)
           If Val(TempStr2(0)) <= MAX_BANK_SLOTS Then
               With UserList(UserIndex).Bank(Val(TempStr2(0)))
                   .ObjIndex = Val(TempStr2(1))
                   .Amount = Val(TempStr2(2))
               End With
           Else '//\\LOGLINE//\\
               Log "Load_User: User has too many bank slots - tried applying slot " & Val(TempStr2(0)), CriticalError '//\\LOGLINE//\\
           End If
       Next i
   End If

In:

Public Sub Save_User

Find:

        'Build the inventory string
       For i = 1 To MAX_INVENTORY_SLOTS
           If .Object(i).ObjIndex > 0 Then
               If LenB(InvStr) Then InvStr = InvStr & vbNewLine   'Add the line break, but dont add it to first entry
               InvStr = InvStr & i & " " & .Object(i).ObjIndex & " " & .Object(i).Amount & " " & .Object(i).Equipped
           End If
       Next i
       Log "Save_User: Built inventory string (" & InvStr & ")", CodeTracker '//\\LOGLINE//\\

Replace With:

        'Build the inventory string
       For i = 1 To MAX_INVENTORY_SLOTS
           If .Object(i).ObjIndex > 0 Then
               If LenB(InvStr) Then InvStr = InvStr & vbNewLine   'Add the line break, but dont add it to first entry
               InvStr = InvStr & i & " " & .Object(i).ObjIndex & " " & .Object(i).Amount & " " & .Object(i).Equip
           End If
       Next i
       Log "Save_User: Built inventory string (" & InvStr & ")", CodeTracker '//\\LOGLINE//\\

Find:

       'Build the bank string
       For i = 1 To MAX_INVENTORY_SLOTS
           If .Bank(i).ObjIndex > 0 Then
               If LenB(BankStr) Then
                   BankStr = BankStr & vbNewLine & i & " " & .Bank(i).ObjIndex & " " & .Bank(i).Amount
               Else
                   BankStr = BankStr & i & " " & .Bank(i).ObjIndex & " " & .Bank(i).Amount
               End If
           End If
       Next i
       Log "Save_User: Built bank string (" & BankStr & ")", CodeTracker '//\\LOGLINE//\\

Replace With:

       'Build the bank string
       For i = 1 To MAX_BANK_SLOTS
           If .Bank(i).ObjIndex > 0 Then
               If LenB(BankStr) Then
                   BankStr = BankStr & vbNewLine & i & " " & .Bank(i).ObjIndex & " " & .Bank(i).Amount
               Else
                   BankStr = BankStr & i & " " & .Bank(i).ObjIndex & " " & .Bank(i).Amount
               End If
           End If
       Next i
       Log "Save_User: Built bank string (" & BankStr & ")", CodeTracker '//\\LOGLINE//\\

Objects.bas

Add Following Functions:

Public Function Obj_EmptySlot(ByVal UserIndex As Integer, ByVal Slot As Long)

If UserList(UserIndex).Object(Slot).ObjIndex Then
   Obj_EmptySlot = False
Else
   Obj_EmptySlot = True
End If
   
End Function

And:

Public Function Obj_ValidObjForSlot(ByVal ObjIndex As Integer, ByVal Slot As Byte) As Boolean
'*****************************************************************
'Checks if an object, by the object index, is useable by the passed class
'More info: http://www.vbgore.com/GameServer.Objects.Obj_ValidObjForClass
'*****************************************************************
   'findme
   'Check if the Slot is Equip or Inventory
   If Slot > MIN_INVENTORY_SLOTS Then
       Select Case Slot
           Case EQUIP_ARM1, EQUIP_ARM2, EQUIP_ARM3, EQUIP_ARM4
               If ObjData.Equip(ObjIndex) = EQUIP_ARM1 Then
                   Obj_ValidObjForSlot = True
                   GoTo QuitThis
               End If
           Case EQUIP_HEAD
               If ObjData.Equip(ObjIndex) = EQUIP_HEAD Then
                   Obj_ValidObjForSlot = True
                   GoTo QuitThis
               End If
           Case EQUIP_BODY
               If ObjData.Equip(ObjIndex) = EQUIP_BODY Then
                   Obj_ValidObjForSlot = True
                   GoTo QuitThis
               End If
           Case EQUIP_ARMS
               If ObjData.Equip(ObjIndex) = EQUIP_ARMS Then
                   Obj_ValidObjForSlot = True
                   GoTo QuitThis
               End If
           Case EQUIP_LEGS
               If ObjData.Equip(ObjIndex) = EQUIP_LEGS Then
                   Obj_ValidObjForSlot = True
                   GoTo QuitThis
               End If
           Case EQUIP_FEET
               If ObjData.Equip(ObjIndex) = EQUIP_FEET Then
                   Obj_ValidObjForSlot = True
                   GoTo QuitThis
               End If
           Case EQUIP_RING1, EQUIP_RING2
               If ObjData.Equip(ObjIndex) = EQUIP_RING1 Then
                   Obj_ValidObjForSlot = True
                   GoTo QuitThis
               End If
           Case EQUIP_NECK
               If ObjData.Equip(ObjIndex) = EQUIP_NECK Then
                   Obj_ValidObjForSlot = True
                   GoTo QuitThis
               End If
       End Select
   Else
       Obj_ValidObjForSlot = True
   End If
   
QuitThis:

End Function

TCP.bas

Find:

   'Check for item of the same type already in there
   PutSlot = 1
   If ObjData.Stacking(UserList(UserIndex).Bank(PutSlot).ObjIndex) > 1 Then
       PutSlot = 0
       Do
           PutSlot = PutSlot + 1
           If PutSlot > MAX_INVENTORY_SLOTS Then
               PutSlot = 0
               Exit Do
           End If
       Loop While UserList(UserIndex).Bank(PutSlot).ObjIndex <> UserList(UserIndex).Object(Slot).ObjIndex
   Else
       PutSlot = 0  'Force to check the next free slot
   End If

Replace With:

   'Check for item of the same type already in there
   PutSlot = 1
   If ObjData.Stacking(UserList(UserIndex).Bank(PutSlot).ObjIndex) > 1 Then
       PutSlot = 0
       Do
           PutSlot = PutSlot + 1
           If PutSlot > MAX_BANK_SLOTS Then
               PutSlot = 0
               Exit Do
           End If
       Loop While UserList(UserIndex).Bank(PutSlot).ObjIndex <> UserList(UserIndex).Object(Slot).ObjIndex
   Else
       PutSlot = 0  'Force to check the next free slot
   End If

Find:

   'If PutSlot = 0, no duplicate item was found, so use the next free slot
   If PutSlot = 0 Then
       Do
           PutSlot = PutSlot + 1
           If PutSlot > MAX_INVENTORY_SLOTS Then
               
               'Bank is full
               Data_Send ToIndex, UserIndex, cMessage(97).Data
               Exit Sub
               
           End If
       Loop While UserList(UserIndex).Bank(PutSlot).ObjIndex > 0
       
       'Just as a pre-caution, we empty the amount value since we are going to be adding on to it and it should be empty
       UserList(UserIndex).Bank(PutSlot).Amount = 0
       
   End If

Replace With:

   'If PutSlot = 0, no duplicate item was found, so use the next free slot
   If PutSlot = 0 Then
       Do
           PutSlot = PutSlot + 1
           If PutSlot > MAX_BANK_SLOTS Then
               
               'Bank is full
               Data_Send ToIndex, UserIndex, cMessage(97).Data
               Exit Sub
               
           End If
       Loop While UserList(UserIndex).Bank(PutSlot).ObjIndex > 0
       
       'Just as a pre-caution, we empty the amount value since we are going to be adding on to it and it should be empty
       UserList(UserIndex).Bank(PutSlot).Amount = 0
       
   End If

Find and remove:

       'User depotted all the items, so remove it from the inventory
       If UserList(UserIndex).Object(Slot).Equipped Then User_RemoveInvItem UserIndex, Slot

Find:

   'Check for invalid values
   If Slot <= 0 Then Exit Sub
   If Slot > MAX_INVENTORY_SLOTS Then Exit Sub

Replace With:

   'Check for invalid values
   If Slot <= 0 Then Exit Sub
   If Slot > MAX_BANK_SLOTS Then Exit Sub

TradeTables.bas

Find Me:

                   'Delete the item from the user's inventory
                   .Amount = 0
                   .ObjIndex = 0
                   .Equipped = 0

Replace With:

                   'Delete the item from the user's inventory
                   .Amount = 0
                   .ObjIndex = 0

Find:

   'Do the same process, but the other way around, for user 2 to get their stuff
   For i = 1 To 9
       If TradeTable(TradeTableIndex).Objs1(i).UserInvSlot > 0 Then
           User_GiveObj TradeTable(TradeTableIndex).User2, UserList(TradeTable(TradeTableIndex).User1).Object(TradeTable(TradeTableIndex).Objs1(i).UserInvSlot).ObjIndex, TradeTable(TradeTableIndex).Objs1(i).Amount, False
           With UserList(TradeTable(TradeTableIndex).User1).Object(TradeTable(TradeTableIndex).Objs1(i).UserInvSlot)
               If .Amount <= TradeTable(TradeTableIndex).Objs1(i).Amount Then
                   User_RemoveInvItem TradeTable(TradeTableIndex).User1, TradeTable(TradeTableIndex).Objs1(i).UserInvSlot, False
                   .ObjIndex = 0
                   .Amount = 0
                   .Equipped = 0
               Else
                   .Amount = .Amount - TradeTable(TradeTableIndex).Objs1(i).Amount
               End If
           End With
       End If
   Next i

Replace With:

   'Do the same process, but the other way around, for user 2 to get their stuff
   For i = 1 To 9
       If TradeTable(TradeTableIndex).Objs1(i).UserInvSlot > 0 Then
           User_GiveObj TradeTable(TradeTableIndex).User2, UserList(TradeTable(TradeTableIndex).User1).Object(TradeTable(TradeTableIndex).Objs1(i).UserInvSlot).ObjIndex, TradeTable(TradeTableIndex).Objs1(i).Amount, False
           With UserList(TradeTable(TradeTableIndex).User1).Object(TradeTable(TradeTableIndex).Objs1(i).UserInvSlot)
               If .Amount <= TradeTable(TradeTableIndex).Objs1(i).Amount Then
                   User_RemoveInvItem TradeTable(TradeTableIndex).User1, TradeTable(TradeTableIndex).Objs1(i).UserInvSlot, False
                   .ObjIndex = 0
                   .Amount = 0

               Else
                   .Amount = .Amount - TradeTable(TradeTableIndex).Objs1(i).Amount
               End If
           End With
       End If
   Next i

ObjData.cls

Add Property:

Public Property Get Equip(ByVal Index As Integer) As Byte
   If Index > 0 Then
       If Index <= MaxDatas Then
           ReadyObj Index
           Equip = cData(ObjIndexToDataIndex(Index)).Equip
       End If
   End If
End Property


Clientside Edits

Declares.bas

Find:

'Object constants
Public Const MAX_INVENTORY_SLOTS As Byte = 49

Replace With:

Public Const MIN_INVENTORY_SLOTS As Byte = 32       'Maximum number of inventory slots - value must be equal to that of the client
Public Const MAX_INVENTORY_SLOTS As Byte = 39
Public Const MAX_BANK_SLOTS As Byte = 16
Public Const EQUIP_ARM1 As Byte = 33
Public Const EQUIP_ARM2 As Byte = 34
Public Const EQUIP_HEAD As Byte = 37
Public Const EQUIP_BODY As Byte = 38
Public Const EQUIP_WINGS As Byte = 39               'Wings Equip Slot

Find:

'User's inventory
Type Inventory
   ObjIndex As Long
   Name As String
   GrhIndex As Long
   Amount As Integer
   Equipped As Boolean

Replace with:

'User's inventory
Type Inventory
   ObjIndex As Long
   Name As String
   GrhIndex As Long
   Amount As Integer
   Equip As Integer

Find:

'User status vars
Public UserInventory(1 To MAX_INVENTORY_SLOTS) As Inventory
Public UserBank(1 To MAX_INVENTORY_SLOTS) As Inventory

Replace with:

'User status vars
Public UserInventory(1 To MAX_INVENTORY_SLOTS) As Inventory
Public UserBank(1 To MAX_BANK_SLOTS) As Inventory

TCP.bas

Find:

'If the object index = 0, then we are deleting a slot, so the rest is null
   If UserInventory(Slot).ObjIndex = 0 Then
       UserInventory(Slot).Name = "(None)"
       UserInventory(Slot).Amount = 0
       UserInventory(Slot).Equipped = 0

Replace with:

'If the object index = 0, then we are deleting a slot, so the rest is null
   If UserInventory(Slot).ObjIndex = 0 Then
       UserInventory(Slot).Name = "(None)"
       UserInventory(Slot).Amount = 0
       UserInventory(Slot).Equip = 0

Find:

'Index <> 0, so we have to get the information
       UserInventory(Slot).Name = rBuf.Get_String
       UserInventory(Slot).Amount = rBuf.Get_Long
       UserInventory(Slot).Equipped = rBuf.Get_Byte

Replace with:

'Index <> 0, so we have to get the information
       UserInventory(Slot).Name = rBuf.Get_String
       UserInventory(Slot).Amount = rBuf.Get_Long
       UserInventory(Slot).Equip = rBuf.Get_Integer

TileEngine.bas

Find:

       Engine_Init_Grh .SkinGrh, Val(Var_Get(s, "INVENTORY", "Grh"))

Replace With:

       Engine_Init_Grh .SkinGrh, Val(Var_Get(s, "INVENTORY", "Grh"))
       .Image(EQUIP_ARM1).X = Val(Var_Get(s, "INVENTORY", "Arm1X"))
       .Image(EQUIP_ARM1).Y = Val(Var_Get(s, "INVENTORY", "Arm1Y"))
       .Image(EQUIP_ARM2).X = Val(Var_Get(s, "INVENTORY", "Arm2X"))
       .Image(EQUIP_ARM2).Y = Val(Var_Get(s, "INVENTORY", "Arm2Y"))
       .Image(EQUIP_BODY).X = Val(Var_Get(s, "INVENTORY", "BodyX"))
       .Image(EQUIP_BODY).Y = Val(Var_Get(s, "INVENTORY", "BodyY"))

Find:

   For LoopC = 1 To MAX_INVENTORY_SLOTS
       With GameWindow.Inventory.Image(LoopC)
           .X = ImageOffsetX + ((ImageSpaceX + 32) * (((LoopC - 1) Mod 7)))
           .Y = ImageOffsetY + ((ImageSpaceY + 32) * ((LoopC - 1) \ 7))
           .Width = 32
           .Height = 32
       End With
   Next LoopC

Replace With:

   For LoopC = 1 To MIN_INVENTORY_SLOTS
       With GameWindow.Inventory.Image(LoopC)
           .X = ImageOffsetX + ((ImageSpaceX + 32) * (((LoopC - 1) Mod 8)))
           .Y = ImageOffsetY + ((ImageSpaceY + 32) * ((LoopC - 1) \ 8))
       End With
   Next LoopC
   For LoopC = 1 To MAX_INVENTORY_SLOTS
       With GameWindow.Inventory.Image(LoopC)


           .Width = 32
           .Height = 32
       End With
   Next LoopC

Database

Go to the object table. Here we add the field "equip" Make it a tinyint, Length 3, NOTNULL, Unsigned. Default 0

Personal tools