Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[EO 2.0] Item Loot Sidebar


Joyce
 Share

Recommended Posts

* * *

**Item Loot Sidebar**

* * *

**Created By:** Yami (Joyce)
**Inspired By:** Random Doodles, and boredom.
**Date Finished:** 10/1/2012
**Difficulty:** 2/5 - Rated R for Retard Friendly!
**Summary:** A nice and simple method of adding a sidebar where you can display item pickups should you want to have them displayed when you pick items up, instead of the standard dull text. The sidebar items dissapear after a timer runs out, which can be adjusted in the constants provided, as well as the amount of them displayed.
**Credits:**

* Yami
* Whack for pointing out a flaw in my system on scrolling maps.

**Lisence:** This snippet is offered under the Eclipse Public Lisence V1.1

**Screenshot:**
![](http://www.freemmorpgmaker.com/files/imagehost/pics/52603ce3b8215f9cf22a51a4ad68c071.png)

* * *

**Client-Side**

In **modConstants** add these two lines at the bottom:
```
Public Const MAX_SIDEBAR_ITEMS As Byte = 5
Public Const SIDEBAR_TIMER As Long = 15
```
In **modEnumerations** look for Public Enum ServerPackets, and add the following line near the bottom. Right before the commented line.
```
SSendSideBarItem
```
In **modTypes** add the following type near the bottom:
```
' Sidebar Addition
Private Type ItemSideBarRec
    itemnum As Long
    value As Long
    timer As Long
    visible As Boolean
End Type
```
and the following near the other public declarations at the top:
```
' Sidebar Addition
Public ItemSideBar(MAX_SIDEBAR_ITEMS) As ItemSideBarRec
```
In **modDirectDraw7** add the following sub at the bottom:
```
Public Sub BltItemSideBar()
Dim rec As DxVBLib.RECT
Dim i As Long

    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    For i = 1 To MAX_SIDEBAR_ITEMS
        If ItemSideBar(i).itemnum < 1 Or ItemSideBar(i).itemnum > NumItems Then Exit Sub
        If ItemSideBar(i).visible = True Then
            If DDS_Item(Item(ItemSideBar(i).itemnum).Pic) Is Nothing Then
                Call InitDDSurf("items\" & Item(ItemSideBar(i).itemnum).Pic, DDSD_Item(Item(ItemSideBar(i).itemnum).Pic), DDS_Item(Item(ItemSideBar(i).itemnum).Pic))
            End If

            With rec
                .top = 0
                .Bottom = PIC_Y
                .Left = 0
                .Right = PIC_X
            End With

            Call Engine_BltFast(Camera.Left + 3, Camera.top + ScreenY - (PIC_Y * i + 3), DDS_Item(Item(ItemSideBar(i).itemnum).Pic), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
        End If
    Next i

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "BltItemSideBar", "modDirectDraw7", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
then head for Sub Render_Graphics, and the following piece of code right above this commented line : ' Lock the backbuffer so we can draw text and names
```
' blt the item sidebar
Call BltItemSideBar
```
And then search for the next line in the same sub, and add the following code above it: ' Release DC
```
' Draw item sidebar text
Call DrawItemSideBarText
```
in **modText** add the following sub near the bottom:
```
Public Sub DrawItemSideBarText()
Dim text As String
Dim i As Long

For i = 1 To MAX_SIDEBAR_ITEMS
    If ItemSideBar(i).visible = True Then
        If ItemSideBar(i).itemnum < 1 Or ItemSideBar(i).itemnum > NumItems Then Exit Sub
        If Item(ItemSideBar(i).itemnum).Type = ITEM_TYPE_CURRENCY Then
            ' Currency, these get a different kind of message.
            text = "You looted " & Trim(Str(ItemSideBar(i).Value)) & " " & Trim(Item(ItemSideBar(i).itemnum).Name)
        Else
            ' Normal item message.
            text = "You looted " & Trim(CheckGrammar(Trim(Item(ItemSideBar(i).itemnum).Name)))
        End If
        Call DrawText(TexthDC, Camera.Left + 6 + PIC_X, (Camera.top + ScreenY) - ((PIC_Y * i) - (PIC_Y / 6)), text, QBColor(Black))
    End If
Next i

End Sub
```
Now in **modHandleData** add the following sub at the bottom:
```
Private Sub HandleSendSideBarItem(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer
Dim n As Long

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()

    n = MAX_SIDEBAR_ITEMS
    Do While n >= 2
        ItemSideBar(n).itemnum = ItemSideBar(n - 1).itemnum
        ItemSideBar(n).value = ItemSideBar(n - 1).value
        ItemSideBar(n).timer = ItemSideBar(n - 1).timer
        ItemSideBar(n).visible = ItemSideBar(n - 1).visible
        n = n - 1
    Loop

    ItemSideBar(1).itemnum = Buffer.ReadLong()
    ItemSideBar(1).value = Buffer.ReadLong()
    ItemSideBar(1).visible = True
    ItemSideBar(1).timer = SIDEBAR_TIMER

End Sub
```
and add the following line under the other entries in Sub InitMessages:
```
HandleDataSub(SSendSideBarItem) = GetAddress(AddressOf HandleSendSideBarItem)
```

Now head for **modGameLogic** and add the following piece of code to the bottom:
```
Public Function CheckGrammar(ByVal Word As String, Optional ByVal Caps As Byte = 0) As String
Dim FirstLetter As String * 1

    FirstLetter = LCase$(Left$(Word, 1))

    If FirstLetter = "$" Then
      CheckGrammar = (Mid$(Word, 2, Len(Word) - 1))
      Exit Function
    End If

    If FirstLetter Like "*[aeiou]*" Then
        If Caps Then CheckGrammar = "An " & Word Else CheckGrammar = "an " & Word
    Else
        If Caps Then CheckGrammar = "A " & Word Else CheckGrammar = "a " & Word
    End If
End Function

Private Sub HandleItemSideBarTimers()
Dim i As Long
    For i = 1 To MAX_SIDEBAR_ITEMS
        ' If the sidebar is visible, continue!
        If ItemSideBar(i).visible = True Then
            ' Take a number out of the timer.
            ItemSideBar(i).timer = ItemSideBar(i).timer - 1

            ' If the timer is below 1, hide the sidebar item.
            If ItemSideBar(i).timer < 1 Then ItemSideBar(i).visible = False
        End If
    Next i
End Sub

```
and head for Sub Gameloop, and locate the next piece of code:
```
' check ping
            Call GetPing
            Call DrawPing
            tmr10000 = Tick + 10000
        End If
```
add the following snippet below this.
```
If tmr1000 < Tick Then
            Call HandleItemSideBarTimers
            tmr1000 = Tick + 1000
        End If
```
now head for the start of this sub, and add the following command to the dim section:
```
Dim tmr1000 as long
```
And that should be all for the client side!

**Server-Side**

In **modEnumerations** look for Public Enum ServerPackets, and add the following line near the bottom. Right before the commented line.
```
SSendSideBarItem
```
Head into **modServerTCP**, and add this code to the bottom:
```
Public Sub SendSideBarItem(ByVal Index As Long, ByVal ItemID As Long, ByVal itemvalue As Long)
Dim Buffer As clsBuffer
    Set Buffer = New clsBuffer

    Buffer.WriteLong SSendSideBarItem
    Buffer.WriteLong ItemID
    Buffer.WriteLong itemvalue
    SendDataTo Index, Buffer.ToArray()
    Set Buffer = Nothing
End Sub
```
And done!

* * *

Right, a little explaining.. I did -NOT- provide a method of integrating this in the loot system, or my chest system. The subs I modified for that are here:

Chest System:
```
Sub HandleMapGetItem(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddR As Long, ByVal ExtraVar As Long)
    Dim a As Long ' For - Next loops
    Dim b As Long ' Inventory slot
    Dim c As Long ' Chest ID
    Dim d As Long ' array
    Dim e As Long ' random number generator
    Dim F As Long ' counter

    If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).Type = TILE_TYPE_CHEST Then
        ' Assign the chest's number to this value.. Easier to read through
        c = Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).Data1

        ' Check for RTE9
        If c < 0 Or c > MAX_CHESTS Then Exit Sub

        ' See if the chest has a name, if not.. well, ignore it!
        If Len(Chest(c).Name) < 1 Then Exit Sub

        ' See if the user has ever looted this chest before.
        If Player(Index).ChestState(c) <> 1 Then
            ' He hasn't! FREE LOOTZ!

            ' What type of chest is it?
            If Chest(c).Type = CHEST_TYPE_ALL Then
                ' Hand the user all the items in the chest, rawr!
                For a = 1 To MAX_CHEST_ITEMS
                    ' Check if the chest has an item in it, and if it's a legal item number.
                    If Chest(c).ItemNum(a) > 0 And Chest(c).ItemNum(a) <= MAX_ITEMS Then
                        b = FindOpenInvSlot(Index, Chest(c).ItemNum(a))
                        Call SendSideBarItem(Index, Chest(c).ItemNum(a), Chest(c).ItemVal(a))
                        Call SetPlayerInvItemNum(Index, b, Chest(c).ItemNum(a))
                        Call SetPlayerInvItemValue(Index, b, GetPlayerInvItemValue(Index, b) + Chest(c).ItemVal(a))
                        Call SendInventoryUpdate(Index, b)
                    End If
                Next
                Player(Index).ChestState(c) = 1
            ElseIf Chest(c).Type = CHEST_TYPE_RANDOM Then
                ' Time to be a little tricky, and hand the guy a random item.

                ' Set the counter to zero.
                F = 0
                For a = 1 To MAX_CHEST_ITEMS
                    ' Check if the chest has an item in it, and if it's a legal item number.
                    If Chest(c).ItemNum(a) > 0 And Chest(c).ItemNum(a) <= MAX_ITEMS Then
                        F = F + 1
                    Else
                        Exit For
                    End If
                Next

                ' if e is too low.. exit to prevent issues.
                If F < 1 Then Exit Sub

                ' Now that we have an array of the items the chest can give.. Let's randomize this shit!
                e = RAND(1, F)

                ' Now we can hand out the item. ;]
                b = FindOpenInvSlot(Index, Chest(c).ItemNum(e))
                Call SendSideBarItem(Index, Chest(c).ItemNum(a), Chest(c).ItemVal(a))
                Call SetPlayerInvItemNum(Index, b, Chest(c).ItemNum(e))
                Call SetPlayerInvItemValue(Index, b, GetPlayerInvItemValue(Index, b) + Chest(c).ItemVal(e))
                Call SendInventoryUpdate(Index, b)
                Player(Index).ChestState(c) = 1
            Else
                ' A non existant state! RUN FOR YOUR LIVES!
                Exit Sub
            End If
        Else
            ' He has, notify the player.
            Call PlayerMsg(Index, "You have already looted this chest!", BrightRed)
        End If
    Else
        Call PlayerMapGetItem(Index)
    End If
End Sub
```
Regular Loot System:
```
Sub PlayerMapGetItem(ByVal Index As Long)
    Dim i As Long
    Dim n As Long
    Dim mapNum As Long
    Dim Msg As String
    Dim ItemNum As Long
    Dim ItemVal As Long

    If Not IsPlaying(Index) Then Exit Sub
    mapNum = GetPlayerMap(Index)

    For i = 1 To MAX_MAP_ITEMS
        ' See if theres even an item here
        If (MapItem(mapNum, i).Num > 0) And (MapItem(mapNum, i).Num <= MAX_ITEMS) Then
            ' our drop?
            If CanPlayerPickupItem(Index, i) Then
                ' Check if item is at the same location as the player
                If (MapItem(mapNum, i).x = GetPlayerX(Index)) Then
                    If (MapItem(mapNum, i).y = GetPlayerY(Index)) Then
                        ' Find open slot
                        n = FindOpenInvSlot(Index, MapItem(mapNum, i).Num)

                        ' Open slot available?
                        If n <> 0 Then
                            ' Set item in players inventor
                            Call SetPlayerInvItemNum(Index, n, MapItem(mapNum, i).Num)
                            ItemNum = MapItem(mapNum, i).Num

                            If Item(GetPlayerInvItemNum(Index, n)).Type = ITEM_TYPE_CURRENCY Then
                                ItemVal = MapItem(mapNum, i).Value
                                Call SetPlayerInvItemValue(Index, n, GetPlayerInvItemValue(Index, n) + MapItem(mapNum, i).Value)
                                Msg = MapItem(mapNum, i).Value & " " & Trim$(Item(GetPlayerInvItemNum(Index, n)).Name)
                            Else
                                Call SetPlayerInvItemValue(Index, n, 0)
                                Msg = Trim$(Item(GetPlayerInvItemNum(Index, n)).Name)
                            End If

                            Call SendInventoryUpdate(Index, n)
                            Call SpawnItemSlot(i, 0, 0, GetPlayerMap(Index), 0, 0)
                            Call SendSideBarItem(Index, ItemNum, ItemVal)

                            ' Erase item from the map
                            ClearMapItem i, mapNum
                            Exit For
                        Else
                            Call PlayerMsg(Index, "Your inventory is full.", BrightRed)
                            Exit For
                        End If
                    End If
                End If
            End If
        End If
    Next
End Sub
```
There, take what you need to know from those subs or copy/paste them over the originals. I don't care :P

Now then, explaining my constants:
**MAX_SIDEBAR_ITEMS**
This constant controls the maximum amount of sidebar items rendered, and tracked.

**SIDEBAR_TIMER**
This constant holds the amount of seconds that it takes for a sidebar message to dissapear.

The code below shows how to call this feature from the server:
```
Call SendSideBarItem(Index, ItemNum, ItemValue)
```
Not that hard now, is it! Ofcourse you'll need to figure out where to put it, if you're using a custom version of your own of the above two subs, but hey! I'm sure you can figure it out.

Enjoy the system, use it.. edit it.. Whatever! If I'm correct I included all the data and subs there are.. I wrote this before I made a tutorial out of it. Wasn't intended to be shared at first. :] Enjoy
Link to comment
Share on other sites

Not my problem, it's not supposed to be a full game ready solution. People can easily adjust the color and font if they wanted to.

I can read it just fine though, and it's the idea I cared about. How people end up using it is up to them, which is why I never wrote a tutorial section to integrate it. It's more of a for the heck of it/because I can addon for my chest system

And if you're so picky, go do it yourself and don't complain. :P
Link to comment
Share on other sites

god yami your a bucking feast. and by that I mean ducking beast.

EDIT: Yami, you have the same code repeated twice. it's the one going in modgamelogic.

Double Edit:

Theres a glitch when switching maps. The text and picture seems to jump to the right on the screen, If you want I can upload a pic. But its exactly the same, just the picture + text is far to the right instead of hugging the left side. I am using normally size picscreen btw.

Also, when your map is big and scrolls, the text seems to blt weird along with the picture, and moves with the scrolling, but goes back into place. It's all a little bit odd.
Link to comment
Share on other sites

I can't seem to reproduce your side jumping glitch, but I can reproduce and fix the scrolling map one. I never accounted for people using scrolling maps, because I tend not to. ;] So I completely forgout about it, and used a static system, which doesn't render well with moving screens.

Anyway, here's the fix for the scrolling maps, with any luck it'll fix the switching sides too:

Replace your BltItemSideBar with this:
```
Public Sub BltItemSideBar()
Dim rec As DxVBLib.RECT
Dim i As Long

    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    For i = 1 To MAX_SIDEBAR_ITEMS
        If ItemSideBar(i).itemnum < 1 Or ItemSideBar(i).itemnum > NumItems Then Exit Sub
        If ItemSideBar(i).visible = True Then
            If DDS_Item(Item(ItemSideBar(i).itemnum).Pic) Is Nothing Then
                Call InitDDSurf("items\" & Item(ItemSideBar(i).itemnum).Pic, DDSD_Item(Item(ItemSideBar(i).itemnum).Pic), DDS_Item(Item(ItemSideBar(i).itemnum).Pic))
            End If

            With rec
                .top = 0
                .Bottom = PIC_Y
                .Left = 0
                .Right = PIC_X
            End With

            Call Engine_BltFast(Camera.Left + 3, Camera.top + ScreenY - (PIC_Y * i + 3), DDS_Item(Item(ItemSideBar(i).itemnum).Pic), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
        End If
    Next i

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "BltItemSideBar", "modDirectDraw7", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
And your DrawItemSideBer() with this:
```
Public Sub DrawItemSideBarText()
Dim text As String
Dim i As Long

For i = 1 To MAX_SIDEBAR_ITEMS
    If ItemSideBar(i).visible = True Then
        If ItemSideBar(i).itemnum < 1 Or ItemSideBar(i).itemnum > NumItems Then Exit Sub
        If Item(ItemSideBar(i).itemnum).Type = ITEM_TYPE_CURRENCY Then
            ' Currency, these get a different kind of message.
            text = "You looted " & Trim(Str(ItemSideBar(i).Value)) & " " & Trim(Item(ItemSideBar(i).itemnum).Name)
        Else
            ' Normal item message.
            text = "You looted " & Trim(CheckGrammar(Trim(Item(ItemSideBar(i).itemnum).Name)))
        End If
        Call DrawText(TexthDC, Camera.Left + 6 + PIC_X, (Camera.top + ScreenY) - ((PIC_Y * i) - (PIC_Y / 6)), text, QBColor(Black))
    End If
Next i

End Sub
```
It now uses the camera's location instead of picscreen's size ;] So it moves smoothly.

edit: Updated the OP with this change. :]
Link to comment
Share on other sites

Depends on what I'm making for my game next.. I just finished my character Customization, but it's not in a state I'm willing to share. :P Needs some refining.. Maybe then I'll consider it. (Unlikely though) I have several other things planned, maybe those will be worth sharing. ;]
Link to comment
Share on other sites

  • 2 weeks later...
  • 2 months later...
  • 2 weeks later...
  • 1 month later...
Did you forget to do these steps?

then head for Sub Render_Graphics, and the following piece of code right above this commented line : ' Lock the backbuffer so we can draw text and names
```
' blt the item sidebar
Call BltItemSideBar

```

And then search for the next line in the same sub, and add the following code above it: ' Release DC
```
' Draw item sidebar text
Call DrawItemSideBarText

```
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...