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
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