18-06-2007, 10:31 PM
Tutorial - Multi item shop trades - MSE Build 1 - Tested and working
Server side changes
-----------------------
First of all open up modConstants and add this code along with the other MAX values.
The server doesn't seem to like a MAX_SHOPS value above 70ish when it writes a new shops.ini file (with the above
MAX values), I would recommend you set it to this or below.
Next, open modTypes and modify the TradeItemRec to look like this.
We'll move onto modDatabase now to sort out the loading and saving of the new trade values.
You'll need to modify both the SaveShop and LoadShop subs to allow for all the extra item information.
Now we've defined the new shop trade combinations we have to deal with sending this information to the client
and receiving the modified data back from the client.
First of all, in modHandledata, modify the Save Shop Packet to include the extra item data.
A new variable 'f' needs to be declared so add the following at the top of Sub HandleData.
The Trade Request Packet is sent to the server every time a character tries to buy something from a shop.
Change the code, as shown below, to check if the player has all the items that might make up the trade,
and give them all the items they have bought.
Then, in the modServerTCP, adjust the makeup of the packets in the SendEditShopTo and SendTrade subs to allow
for multiple items.
Just one last sub to change now, open up modGameLogic and modify the ClearShop sub to zero all the item
values when the server starts up.
That's all for the server side......
First job client side is to add the new shop trade definitions, in modTypes change the
TradeItemRec to look like the code below.
As with the server, we need to add the maximum amount of items a player gives for a trade
and the maximum amount of items they receive, in modConstants add the following code in with
the other MAX Constants.
Now would be a good time for us to tackle the changes to frmShopEditor, bring up the form and move the controls
apart a little to create a gap between the 'fixes items' checkbox and the 'item give' combobox, then again between the 'value' textbox for 'item give' and the 'item get' combobox.
Right, follow this next part closely, there are new controls to add and the old give/get item controls will be re-named.
In the first gap;
* add a label with the caption 'Give Item',
* add a scrollbar next to that called 'scrlGiveItem' with the 'Min' value set to 1,
* add a label to the end of the scrollbar named 'lblGiveItem' with 'Autosize' set to TRUE and the 'Caption' as '1'.
* now change the 'cmbItemGive' comboboxes name to 'cmbShopItemGive'
* and change the 'txtItemGiveValue' textboxes name to 'txtShopGiveValue'.
In the second gap;
* add a label with the caption 'Get Item',
* add a scrollbar next to that called 'scrlGetItem' with the 'Min' value set to 1,
* add a label to the end of the scrollbar named 'lblGetItem' with 'Autosize' set to TRUE and the 'Caption' as '1'.
* now change the 'cmbItemGet' comboboxes name to 'cmbShopItemGet'
* and change the 'txtItemGetValue' textboxes name to 'txtShopGetValue'.
With that done we can change the associated code, bring up the forms code window, locate Sub cmdShopUpdate_Click()
and comment out all the code except for the call to 'UpdateShopTrade'.
Now add the following code to the end to deal with the controls we've added and the ones we modfied.
There aren't any real visual changes to frmTrade to be made, although you may want to widen 'lstTrade' to cope with the longer trade descriptions.
No changes to the code for this form either, so we'll move onto the changes in packet data.
First up is the Edit Shop Packet in modHandledata, more changes in view of the extra items per trade.
I've used another variable for each item in the GIVE and GET ITEM arrays and a new string variable for each trade description, so add this code to the top of Sub HandleData with the other Dim statements,
Modify the Edit shop Packet to look like the code below.
Over to frmClientTCP now, find the sub SendSaveShop and change it to the following code.
Lastly we come to modGameLogic, the changes here set how the shop editor displays the new trade item information.
Once again, modify the code to look like the code that follows.
And There you have it, you should now be able to set up multiple item trades in your shops.
It's best to delete the shops.ini file in the Data folder server side before running the server again.
It is possible to change the MAX_GIVE_ITEMS and MAX_GET_ITEMS and _VALUE constants to give different combinations.
NB: with MAX_GIVE_ITEMS set to 5 and MAX_GET_ITEMS set to 2, an .ini file will hold just over 70 shops.
** Know Issue - There is one last sub or code modification that this tutorial needs to complete it, I haven't gotten around to adding it to my source yet so you'll have to make it up yourself.
Basically it concerns the servers check for open inventory slots, at the moment if a player has just one open inventory slot the FindOpenInvSlot sub will find that open slot for each Get Item the character will receive, meaning the player will run out of inventory before they get all the items their due.
Best of Luck.
Server side changes
-----------------------
First of all open up modConstants and add this code along with the other MAX values.
Code:
Public Const MAX_GIVE_ITEMS = 5
Public Const MAX_GIVE_VALUE = 5
Public Const MAX_GET_ITEMS = 2
Public Const MAX_GET_VALUE = 2
The server doesn't seem to like a MAX_SHOPS value above 70ish when it writes a new shops.ini file (with the above
MAX values), I would recommend you set it to this or below.
Next, open modTypes and modify the TradeItemRec to look like this.
Code:
Type TradeItemRec
GiveItem(1 To MAX_GIVE_ITEMS) As Long
GiveValue(1 To MAX_GIVE_VALUE) As Long
GetItem(1 To MAX_GET_ITEMS) As Long
GetValue(1 To MAX_GET_VALUE) As Long
End Type
We'll move onto modDatabase now to sort out the loading and saving of the new trade values.
You'll need to modify both the SaveShop and LoadShop subs to allow for all the extra item information.
Code:
Sub SaveShop(ByVal ShopNum As Long)
Dim FileName As String
Dim i As Long
Dim n As Long
FileName = App.Path & "\data\shops.ini"
Call PutVar(FileName, "SHOP" & ShopNum, "Name", Trim(Shop(ShopNum).Name))
Call PutVar(FileName, "SHOP" & ShopNum, "JoinSay", Trim(Shop(ShopNum).JoinSay))
Call PutVar(FileName, "SHOP" & ShopNum, "LeaveSay", Trim(Shop(ShopNum).LeaveSay))
Call PutVar(FileName, "SHOP" & ShopNum, "FixesItems", Trim(Shop(ShopNum).FixesItems))
For i = 1 To MAX_TRADES
For n = 1 To MAX_GIVE_ITEMS
Call PutVar(FileName, "SHOP" & ShopNum, "Trade" & i & "GiveItem" & n, Trim(Shop(ShopNum).TradeItem(i).GiveItem(n)))
Call PutVar(FileName, "SHOP" & ShopNum, "Trade" & i & "GiveValue" & n, Trim(Shop(ShopNum).TradeItem(i).GiveValue(n)))
Next n
For n = 1 To MAX_GET_ITEMS
Call PutVar(FileName, "SHOP" & ShopNum, "Trade" & i & "GetItem" & n, Trim(Shop(ShopNum).TradeItem(i).GetItem(n)))
Call PutVar(FileName, "SHOP" & ShopNum, "Trade" & i & "GetValue" & n, Trim(Shop(ShopNum).TradeItem(i).GetValue(n)))
Next n
Next i
End Sub
Code:
Sub LoadShops()
On Error Resume Next
Dim FileName As String
Dim x As Long, y As Long, n As Long
Call CheckShops
FileName = App.Path & "\data\shops.ini"
For y = 1 To MAX_SHOPS
Shop(y).Name = GetVar(FileName, "SHOP" & y, "Name")
Shop(y).JoinSay = GetVar(FileName, "SHOP" & y, "JoinSay")
Shop(y).LeaveSay = GetVar(FileName, "SHOP" & y, "LeaveSay")
Shop(y).FixesItems = GetVar(FileName, "SHOP" & y, "FixesItems")
For x = 1 To MAX_TRADES
For n = 1 To MAX_GIVE_ITEMS
Shop(y).TradeItem(x).GiveItem(n) = GetVar(FileName, "SHOP" & y, "Trade" & x & "GiveItem" & n)
Shop(y).TradeItem(x).GiveValue(n) = GetVar(FileName, "SHOP" & y, "Trade" & x & "GiveValue" & n)
Next n
For n = 1 To MAX_GET_ITEMS
Shop(y).TradeItem(x).GetItem(n) = GetVar(FileName, "SHOP" & y, "Trade" & x & "GetItem" & n)
Shop(y).TradeItem(x).GetValue(n) = GetVar(FileName, "SHOP" & y, "Trade" & x & "GetValue" & n)
Next n
Next x
DoEvents
Next y
End Sub
Now we've defined the new shop trade combinations we have to deal with sending this information to the client
and receiving the modified data back from the client.
First of all, in modHandledata, modify the Save Shop Packet to include the extra item data.
A new variable 'f' needs to be declared so add the following at the top of Sub HandleData.
Code:
Dim f As Long
Code:
' ::::::::::::::::::::::
' :: Save shop packet ::
' ::::::::::::::::::::::
If (LCase(Parse(0)) = "saveshop") Then
' Prevent hacking
If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
Call HackingAttempt(Index, "Admin Cloning")
Exit Sub
End If
ShopNum = Val(Parse(1))
' Prevent hacking
If ShopNum < 0 Or ShopNum > MAX_SHOPS Then
Call HackingAttempt(Index, "Invalid Shop Index")
Exit Sub
End If
' Update the shop
Shop(ShopNum).Name = Trim(Parse(2))
Shop(ShopNum).JoinSay = Trim(Parse(3))
Shop(ShopNum).LeaveSay = Trim(Parse(4))
Shop(ShopNum).FixesItems = Val(Parse(5))
n = 6
For i = 1 To MAX_TRADES
For f = 1 To MAX_GIVE_ITEMS
Shop(ShopNum).TradeItem(I).GiveItem(f) = Val(Parse((n - 1) + f))
Next f
n = n + MAX_GIVE_ITEMS
For f = 1 To MAX_GIVE_VALUE
Shop(ShopNum).TradeItem(I).GiveValue(f) = Val(Parse((n - 1) + f))
Next f
n = n + MAX_GIVE_VALUE
For f = 1 To MAX_GET_ITEMS
Shop(ShopNum).TradeItem(I).GetItem(f) = Val(Parse((n - 1) + f))
Next f
n = n + MAX_GET_ITEMS
For f = 1 To MAX_GET_VALUE
Shop(ShopNum).TradeItem(I).GetValue(f) = Val(Parse((n - 1) + f))
Next f
n = n + MAX_GET_VALUE
Next i
' Save it
Call SendUpdateShopToAll(ShopNum)
Call SaveShop(ShopNum)
Call AddLog(GetPlayerName(Index) & " saving shop #" & ShopNum & ".", ADMIN_LOG)
Exit Sub
End If
The Trade Request Packet is sent to the server every time a character tries to buy something from a shop.
Change the code, as shown below, to check if the player has all the items that might make up the trade,
and give them all the items they have bought.
Code:
' ::::::::::::::::::::::::::
' :: Trade request packet ::
' ::::::::::::::::::::::::::
If LCase(Parse(0)) = "traderequest" Then
' Trade num
n = Val(Parse(1))
' Prevent hacking
If (n MAX_TRADES) Then
Call HackingAttempt(Index, "Trade Request Modification")
Exit Sub
End If
' Index for shop
i = Map(GetPlayerMap(Index).Shop
' Check if inv full
For f = 1 To MAX_GET_ITEMS
If Shop(i).TradeItem(n).GetItem(f) > 0 Then
x = FindOpenInvSlot(Index, Shop(i).TradeItem(n).GetItem(f))
If x = 0 Then
Call PlayerMsg(Index, "Inventory Full.", BrightRed)
Exit Sub
End If
End If
Next f
' Check if they have the items
For f = 1 To MAX_GIVE_ITEMS
If Shop(i).TradeItem(n).GiveItem(f) > 0 Then
If HasItem(Index, Shop(i).TradeItem(n).GiveItem(f)) >= Shop(i).TradeItem(n).GiveValue(f) Then
Else
Call PlayerMsg(Index, "Trade Unsuccessful.", BrightRed)
Exit Sub
End If
End If
Next f
' If they have all the items, make the trade
For f = 1 To MAX_GIVE_ITEMS
Call TakeItem(Index, Shop(i).TradeItem(n).GiveItem(f), Shop(i).TradeItem(n).GiveValue(f))
Next f
For f = 1 To MAX_GET_ITEMS
Call GiveItem(Index, Shop(i).TradeItem(n).GetItem(f), Shop(i).TradeItem(n).GetValue(f))
Next f
Call PlayerMsg(Index, "Trade Successful.", BrightRed)
Exit Sub
End If
Then, in the modServerTCP, adjust the makeup of the packets in the SendEditShopTo and SendTrade subs to allow
for multiple items.
Code:
Sub SendEditShopTo(ByVal Index As Long, ByVal ShopNum As Long)
Dim Packet As String
Dim i As Long, n As Long
Packet = "EDITSHOP" & SEP_CHAR & ShopNum & SEP_CHAR & Trim(Shop(ShopNum).Name) & SEP_CHAR & Trim(Shop(ShopNum).JoinSay) & SEP_CHAR & Trim(Shop(ShopNum).LeaveSay) & SEP_CHAR & Shop(ShopNum).FixesItems
For i = 1 To MAX_TRADES
For n = 1 To MAX_GIVE_ITEMS
Packet = Packet & SEP_CHAR & Shop(ShopNum).TradeItem(i).GiveItem(n)
Next n
For n = 1 To MAX_GIVE_VALUE
Packet = Packet & SEP_CHAR & Shop(ShopNum).TradeItem(i).GiveValue(n)
Next n
For n = 1 To MAX_GET_ITEMS
Packet = Packet & SEP_CHAR & Shop(ShopNum).TradeItem(i).GetItem(n)
Next n
For n = 1 To MAX_GET_VALUE
Packet = Packet & SEP_CHAR & Shop(ShopNum).TradeItem(i).GetValue(n)
Next n
Next i
Packet = Packet & SEP_CHAR & END_CHAR
Call SendDataTo(Index, Packet)
End Sub
Code:
Sub SendTrade(ByVal Index As Long, ByVal ShopNum As Long)
Dim Packet As String
Dim I As Long, x As Long, y As Long, n As Long
Packet = "TRADE" & SEP_CHAR & ShopNum & SEP_CHAR & Shop(ShopNum).FixesItems
For i = 1 To MAX_TRADES
For n = 1 To MAX_GIVE_ITEMS
Packet = Packet & SEP_CHAR & Shop(ShopNum).TradeItem(i).GiveItem(n)
Next n
For n = 1 To MAX_GIVE_VALUE
Packet = Packet & SEP_CHAR & Shop(ShopNum).TradeItem(i).GiveValue(n)
Next n
For n = 1 To MAX_GET_ITEMS
Packet = Packet & SEP_CHAR & Shop(ShopNum).TradeItem(i).GetItem(n)
Next n
For n = 1 To MAX_GET_VALUE
Packet = Packet & SEP_CHAR & Shop(ShopNum).TradeItem(i).GetValue(n)
Next n
For n = 1 To MAX_GET_ITEMS
' Item #
x = Shop(ShopNum).TradeItem(i).GetItem(n)
If Item(x).Type = ITEM_TYPE_SPELL Then
' Spell class requirement
y = Spell(Item(x).Data1).ClassReq
If y = 0 Then
Call PlayerMsg(Index, Trim(Item(x).Name) & " can be used by all classes.", Yellow)
Else
Call PlayerMsg(Index, Trim(Item(x).Name) & " can only be used by a " & GetClassName(y - 1) & ".", Yellow)
End If
End If
Next n
Next i
Packet = Packet & SEP_CHAR & END_CHAR
Call SendDataTo(Index, Packet)
End Sub
Just one last sub to change now, open up modGameLogic and modify the ClearShop sub to zero all the item
values when the server starts up.
Code:
Sub ClearShop(ByVal Index As Long)
Dim i As Long
Dim n As Long
Shop(Index).Name = ""
Shop(Index).JoinSay = ""
Shop(Index).LeaveSay = ""
Shop(Index).FixesItems = 0
For i = 1 To MAX_TRADES
For n = 1 To MAX_GIVE_ITEMS
Shop(Index).TradeItem(i).GiveItem(n) = 0
Next n
For n = 1 To MAX_GIVE_VALUE
Shop(Index).TradeItem(i).GiveValue(n) = 0
Next n
For n = 1 To MAX_GET_ITEMS
Shop(Index).TradeItem(i).GetItem(n) = 0
Next n
For n = 1 To MAX_GET_VALUE
Shop(Index).TradeItem(i).GetValue(n) = 0
Next n
Next i
End Sub
That's all for the server side......
First job client side is to add the new shop trade definitions, in modTypes change the
TradeItemRec to look like the code below.
Code:
Type TradeItemRec
GiveItem(1 To MAX_GIVE_ITEMS) As Long
GiveValue(1 To MAX_GIVE_VALUE) As Long
GetItem(1 To MAX_GET_ITEMS) As Long
GetValue(1 To MAX_GET_VALUE) As Long
End Type
As with the server, we need to add the maximum amount of items a player gives for a trade
and the maximum amount of items they receive, in modConstants add the following code in with
the other MAX Constants.
Code:
Public Const MAX_GIVE_ITEMS = 5
Public Const MAX_GIVE_VALUE = 5
Public Const MAX_GET_ITEMS = 2
Public Const MAX_GET_VALUE = 2
Now would be a good time for us to tackle the changes to frmShopEditor, bring up the form and move the controls
apart a little to create a gap between the 'fixes items' checkbox and the 'item give' combobox, then again between the 'value' textbox for 'item give' and the 'item get' combobox.
Right, follow this next part closely, there are new controls to add and the old give/get item controls will be re-named.
In the first gap;
* add a label with the caption 'Give Item',
* add a scrollbar next to that called 'scrlGiveItem' with the 'Min' value set to 1,
* add a label to the end of the scrollbar named 'lblGiveItem' with 'Autosize' set to TRUE and the 'Caption' as '1'.
* now change the 'cmbItemGive' comboboxes name to 'cmbShopItemGive'
* and change the 'txtItemGiveValue' textboxes name to 'txtShopGiveValue'.
In the second gap;
* add a label with the caption 'Get Item',
* add a scrollbar next to that called 'scrlGetItem' with the 'Min' value set to 1,
* add a label to the end of the scrollbar named 'lblGetItem' with 'Autosize' set to TRUE and the 'Caption' as '1'.
* now change the 'cmbItemGet' comboboxes name to 'cmbShopItemGet'
* and change the 'txtItemGetValue' textboxes name to 'txtShopGetValue'.
With that done we can change the associated code, bring up the forms code window, locate Sub cmdShopUpdate_Click()
and comment out all the code except for the call to 'UpdateShopTrade'.
Now add the following code to the end to deal with the controls we've added and the ones we modfied.
Code:
Private Sub lstTradeItem_Click()
cmbShopItemGive.ListIndex = Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GiveItem(scrlGiveItem.Value)
txtShopGiveValue.Text = Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GiveValue(scrlGiveItem.Value)
lblGiveItem.Caption = scrlGiveItem.Value
cmbShopItemGet.ListIndex = Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GetItem(scrlGetItem.Value)
txtShopGetValue.Text = Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GetValue(scrlGetItem.Value)
lblGetItem.Caption = scrlGetItem.Value
End Sub
Code:
Private Sub scrlGiveItem_Change()
cmbShopItemGive.ListIndex = Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GiveItem(scrlGiveItem.Value)
txtShopGiveValue.Text = Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GiveValue(scrlGiveItem.Value)
lblGiveItem.Caption = scrlGiveItem.Value
End Sub
Code:
Private Sub cmbShopItemGive_Click()
If lstTradeItem.ListIndex >= 0 Then
Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GiveItem(scrlGiveItem.Value) = cmbShopItemGive.ListIndex
End If
End Sub
Code:
Private Sub txtShopGiveValue_Change()
Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GiveValue(scrlGiveItem.Value) = Val(txtShopGiveValue.Text)
End Sub
Code:
Private Sub scrlGetItem_Change()
cmbShopItemGet.ListIndex = Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GetItem(scrlGetItem.Value)
txtShopGetValue.Text = Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GetValue(scrlGetItem.Value)
lblGetItem.Caption = scrlGetItem.Value
End Sub
Code:
Private Sub cmbShopItemGet_Click()
If lstTradeItem.ListIndex >= 0 Then
Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GetItem(scrlGetItem.Value) = cmbShopItemGet.ListIndex
End If
End Sub
Code:
Private Sub txtShopGetValue_Change()
Shop(EditorIndex).TradeItem(lstTradeItem.ListIndex + 1).GetValue(scrlGetItem.Value) = Val(txtShopGetValue.Text)
End Sub
There aren't any real visual changes to frmTrade to be made, although you may want to widen 'lstTrade' to cope with the longer trade descriptions.
No changes to the code for this form either, so we'll move onto the changes in packet data.
First up is the Edit Shop Packet in modHandledata, more changes in view of the extra items per trade.
I've used another variable for each item in the GIVE and GET ITEM arrays and a new string variable for each trade description, so add this code to the top of Sub HandleData with the other Dim statements,
Code:
Dim f As Long
Dim TradeDescription As String
Modify the Edit shop Packet to look like the code below.
Code:
' ::::::::::::::::::::::
' :: Edit shop packet :: 0) And (Shop(ShopNum).TradeItem(i).GetValue(f) > 0) Then
TradeDescription = TradeDescription & Shop(ShopNum).TradeItem(i).GetValue(f) & " x " & Trim(Item(Shop(ShopNum).TradeItem(i).GetItem(f)).Name) & " + "
End If
Next f
If TradeDescription = "" Then
frmTrade.lstTrade.AddItem "Empty Trade Slot"
frmTrade.lstTrade.ListIndex = 0
If frmTrade.lstTrade.ListCount > 0 Then
frmTrade.lstTrade.ListIndex = 0
End If
Exit For
End If
TradeDescription = Left(TradeDescription, (Len(TradeDescription) - 2))
TradeDescription = TradeDescription & "for "
For f = 1 To MAX_GIVE_ITEMS
If (Shop(ShopNum).TradeItem(i).GiveItem(f) > 0) And (Shop(ShopNum).TradeItem(i).GiveValue(f) > 0) Then
TradeDescription = TradeDescription & Shop(ShopNum).TradeItem(i).GiveValue(f) & " x " & Trim(Item(Shop(ShopNum).TradeItem(i).GiveItem(f)).Name) & " + "
End If
Next f
If TradeDescription = "" Then
frmTrade.lstTrade.AddItem i & "Empty Trade Slot"
frmTrade.lstTrade.ListIndex = 0
If frmTrade.lstTrade.ListCount > 0 Then
frmTrade.lstTrade.ListIndex = 0
End If
Exit For
End If
TradeDescription = Left(TradeDescription, (Len(TradeDescription) - 2))
frmTrade.lstTrade.AddItem i & ": " & TradeDescription
Next i
If frmTrade.lstTrade.ListCount > 0 Then
frmTrade.lstTrade.ListIndex = 0
End If
frmTrade.Show vbModal
Exit Sub
End If
Over to frmClientTCP now, find the sub SendSaveShop and change it to the following code.
Code:
Public Sub SendSaveShop(ByVal ShopNum As Long)
Dim Packet As String
Dim i As Long, f As Long
With Shop(ShopNum)
Packet = "SAVESHOP" & SEP_CHAR & ShopNum & SEP_CHAR & Trim(.Name) & SEP_CHAR & Trim(.JoinSay) & SEP_CHAR & Trim(.LeaveSay) & SEP_CHAR & .FixesItems & SEP_CHAR
End With
For i = 1 To MAX_TRADES
With Shop(ShopNum).TradeItem(i)
For f = 1 To MAX_GIVE_ITEMS
Packet = Packet & .GiveItem(f) & SEP_CHAR
Next f
For f = 1 To MAX_GIVE_VALUE
Packet = Packet & .GiveValue(f) & SEP_CHAR
Next f
For f = 1 To MAX_GET_ITEMS
Packet = Packet & .GetItem(f) & SEP_CHAR
Next f
For f = 1 To MAX_GET_VALUE
Packet = Packet & .GetValue(f) & SEP_CHAR
Next f
End With
Next i
Packet = Packet & END_CHAR
Call SendData(Packet)
End Sub
Lastly we come to modGameLogic, the changes here set how the shop editor displays the new trade item information.
Once again, modify the code to look like the code that follows.
Code:
Public Sub ShopEditorInit()
On Error Resume Next
Dim i As Long
frmShopEditor.txtName.Text = Trim(Shop(EditorIndex).Name)
frmShopEditor.txtJoinSay.Text = Trim(Shop(EditorIndex).JoinSay)
frmShopEditor.txtLeaveSay.Text = Trim(Shop(EditorIndex).LeaveSay)
frmShopEditor.chkFixesItems.Value = Shop(EditorIndex).FixesItems
frmShopEditor.scrlGiveItem.Max = MAX_GIVE_ITEMS
frmShopEditor.scrlGetItem.Max = MAX_GET_ITEMS
frmShopEditor.cmbShopItemGive.Clear
frmShopEditor.cmbShopItemGive.AddItem "None"
frmShopEditor.cmbShopItemGet.Clear
frmShopEditor.cmbShopItemGet.AddItem "None"
For i = 1 To MAX_ITEMS
frmShopEditor.cmbShopItemGive.AddItem i & ": " & Trim(Item(i).Name)
frmShopEditor.cmbShopItemGet.AddItem i & ": " & Trim(Item(i).Name)
Next i
frmShopEditor.cmbShopItemGive.ListIndex = 0
frmShopEditor.cmbShopItemGet.ListIndex = 0
frmShopEditor.lstTradeItem.ListIndex = 0
Call UpdateShopTrade
frmShopEditor.Show vbModal
End Sub
Code:
Public Sub UpdateShopTrade()
Dim i As Long, f As Long
Dim TradeDescription As String
Dim GiveItem(1 To MAX_GIVE_ITEMS) As Byte
Dim GiveValue(1 To MAX_GIVE_ITEMS) As Byte
Dim GetItem(1 To MAX_GET_ITEMS) As Byte
Dim GetValue(1 To MAX_GET_VALUE) As Byte
frmShopEditor.lstTradeItem.Clear
For i = 1 To MAX_TRADES
For f = 1 To MAX_GIVE_ITEMS
GiveItem(f) = Shop(EditorIndex).TradeItem(i).GiveItem(f)
GiveValue(f) = Shop(EditorIndex).TradeItem(i).GiveValue(f)
Next f
For f = 1 To MAX_GET_ITEMS
GetItem(f) = Shop(EditorIndex).TradeItem(i).GetItem(f)
GetValue(f) = Shop(EditorIndex).TradeItem(i).GetValue(f)
Next f
TradeDescription = ""
For f = 1 To MAX_GET_ITEMS
If (GetItem(f) > 0) And (GetValue(f) > 0) Then
TradeDescription = TradeDescription & GetValue(f) & " x " & Trim(Item(GetItem(f)).Name) & " + "
End If
Next f
If TradeDescription = "" Then
frmShopEditor.lstTradeItem.AddItem "Empty Trade Slot"
frmShopEditor.lstTradeItem.ListIndex = 0
Exit For
End If
TradeDescription = Left(TradeDescription, (Len(TradeDescription) - 2))
TradeDescription = TradeDescription & "for "
For f = 1 To MAX_GIVE_ITEMS
If (GiveItem(f) > 0) And (GiveValue(f) > 0) Then
TradeDescription = TradeDescription & GiveValue(f) & " x " & Trim(Item(GiveItem(f)).Name) & " + "
End If
Next f
If TradeDescription = "" Then
frmShopEditor.lstTradeItem.AddItem i & "Empty Trade Slot"
frmShopEditor.lstTradeItem.ListIndex = 0
Exit For
End If
TradeDescription = Left(TradeDescription, (Len(TradeDescription) - 2))
frmShopEditor.lstTradeItem.AddItem i & ": " & TradeDescription
Next i
frmShopEditor.lstTradeItem.ListIndex = 0
End Sub
Code:
Public Sub ShopEditorOk()
Shop(EditorIndex).Name = frmShopEditor.txtName.Text
Shop(EditorIndex).JoinSay = frmShopEditor.txtJoinSay.Text
Shop(EditorIndex).LeaveSay = frmShopEditor.txtLeaveSay.Text
Shop(EditorIndex).FixesItems = frmShopEditor.chkFixesItems.Value
Call SendSaveShop(EditorIndex)
InShopEditor = False
Unload frmShopEditor
End Sub
And There you have it, you should now be able to set up multiple item trades in your shops.
It's best to delete the shops.ini file in the Data folder server side before running the server again.
It is possible to change the MAX_GIVE_ITEMS and MAX_GET_ITEMS and _VALUE constants to give different combinations.
NB: with MAX_GIVE_ITEMS set to 5 and MAX_GET_ITEMS set to 2, an .ini file will hold just over 70 shops.
** Know Issue - There is one last sub or code modification that this tutorial needs to complete it, I haven't gotten around to adding it to my source yet so you'll have to make it up yourself.
Basically it concerns the servers check for open inventory slots, at the moment if a player has just one open inventory slot the FindOpenInvSlot sub will find that open slot for each Get Item the character will receive, meaning the player will run out of inventory before they get all the items their due.
Best of Luck.