Stackable inventory with search as you type

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Post Reply
Message
Author
jeffster
Veteran
Posts: 409
Joined: Wed Feb 03, 2021 9:55 pm
Contact:

Stackable inventory with search as you type

#1 Post by jeffster »

Yet another stackable inventory. This time you can type item name to quickly find matching items:
inv2.jpg
inv2.jpg (37.38 KiB) Viewed 688 times
The zip below contains ready-to-play distributive, with pictures etc. Just unpack it and run "game" folder with Ren'Py 8 SDK.

Code: Select all

define items = {
    "book": ("book.png", "Description of book"),
    "bug":  ("bug.png",  "Description of bug"),
    "dice": ("dice.png", "Description of dice"),
    "film": ("film.png", "Description of film"),
    "look": ("look.png", "Description of look"),
    "pawn": ("pawn.png", "Description of pawn"),
    "sun":  ("sun.png",  "Description of sun"),
    "talk": ("talk.png", "Description of talk"),
    "tool": ("tool.png", "Description of tool"),
    "wand": ("wand.png", "Description of wand"),
}

default inventory = []          # [ [item_name, amount] ]

default filtered_names = []     # for search_fly function

init python:
    def set_item(item_name, amount):
        """ Universal function to add or remove inventory items """
        try:
            i = [x[0] for x in inventory].index(item_name)
            if amount <= 0:
                inventory.pop(i)
            else:
                inventory[i][1] = amount
        except:
            if amount > 0:
                inventory.append([item_name, amount])

    def get_item(item_name):
        """ Get amount of those items """
        try:
            i = [x[0] for x in inventory].index(item_name)
            return inventory[i][1]
        except:
            return 0

    def search_fly(searching, interact=True):
        """ Searching as you type when N symbols were entered """
        if len(searching) >= 2:         # <- N == 2
            store.filtered_names = [
                x for x in items.keys() if searching.casefold() in \
                                renpy.translate_string(x).casefold()]
            if interact:
                renpy.restart_interaction()

    class SearchInputValue(InputValue):
        def __init__(self, default_value="", default=False):
            super(SearchInputValue, self).__init__()
            self.text_value = default_value
            self.default = default

        def get_text(self):
            return self.text_value

        def set_text(self, s):
            self.text_value = s
            search_fly(s)

        def enter(self):
            return self.text_value

screen inv(page_number=0, current_item=""):
    default searchVal = SearchInputValue(current_item, default=False)

    text f"{len(inventory)} items. Page {page_number+1}":
        align (0.5, 0.0)
        size 48

    grid 4 2:
        xalign 0.5
        ypos 80
        spacing 12
        for i in range(8*page_number, 8*page_number+8):
            if i < len(inventory):
                button:
                    size_group "items"
                    background "#345"
                    hover_background "#579"
                    hovered searchVal.Disable()
                    vbox:
                        xalign 0.5
                        add items[inventory[i][0]][0]       # pic
                        text inventory[i][0]:               # name
                            size 42
                            yoffset 24
                        text str(inventory[i][1]):          # amount
                            xalign 1.0
                            yoffset -64
                            color "#FF0"

                    tooltip items[inventory[i][0]][1]   # description
                    action Return((inventory[i][0], inventory[i][1]))

    if page_number > 0:
        textbutton "<" align (0.2, 0.2) action Return(-1):
            text_size 96
            hovered searchVal.Disable()

    if page_number < (len(inventory)-1)//8:
        textbutton ">" align (0.8, 0.2) action Return(1):
            text_size 96
            hovered searchVal.Disable()

    if current_item:
        textbutton "-" align (0.4, 0.9) action Return("-"):
            text_size 96
            hovered searchVal.Disable()
        textbutton "+" align (0.6, 0.9) action Return("+"):
            text_size 96
            hovered searchVal.Disable()
        button:
            align (0.5, 0.9)
            size_group "items"
            background "#123"
            hover_background "#345"
            hovered searchVal.Disable()
            vbox:
                align (0.5, 0.5)
                add items[current_item][0] yoffset 12
                text str(get_item(current_item)):
                    xalign 1.0
                    xoffset 12
                    color "#FF0"
            tooltip items[current_item][1]
            action Return(current_item)

    hbox:
        xalign 0.5
        ypos 0.6
        yanchor 0.0
        spacing 8
        vbox:
            align (1.0, 0.0)
            spacing 4
            ysize 36
            style "itemName"
            button:
                action searchVal.Enable()
                hovered searchVal.Enable()
                background "#597"
                hover_background "#7B9"
                xfill True
                tooltip "Search"
                input:
                    value searchVal
                    copypaste True
                    color "#000"
            for n in filtered_names:
                button:
                    background "#345"
                    hover_background "#579"
                    hovered searchVal.Disable()
                    size_group "names"
                    text "[n!t]"
                    action Return(n)
                    tooltip items[n][1]

    $ tooltip = GetTooltip()
    if tooltip:
        text "[tooltip]" align (0.5, 0.5)

style itemName:
    xsize 600
    background "#345"
    hover_background "#579"


label start:
    python:
        n = 0
        for i in items:
            set_item(i, n)
            n += 1

        pageN = 0
        current_item = ""

label loop:
    call screen inv(pageN, current_item)

    if type(_return) is int:
        # -1 or 1 to flip through pages
        $ pageN = min(max(pageN+_return, 0), (len(inventory)-1)//8)

    elif type(_return) is str:
        # "-" or "+" to modify an item amount

        if _return == '-':
            $ set_item(current_item, get_item(current_item)-1)

        elif _return == '+':
            $ set_item(current_item, get_item(current_item)+1)

        else:
            # An item to select by name
            python:
                if _return in items:
                    current_item = _return
                    del filtered_names[:]
                elif len(filtered_names) == 1:
                    current_item = filtered_names[0]
                    del filtered_names[:]
                elif not filtered_names:
                    renpy.notify(f"No such item: {_return}")

    elif type(_return) is tuple:
        # first element is an item name
        $ current_item = _return[0]

    jump loop
Attachments
Inventory_game.zip
(156.61 KiB) Downloaded 19 times

Post Reply

Who is online

Users browsing this forum: Google [Bot]