Example #1
0
    def activate(self, activator=None):
        if CountUpTile.activate(self, activator):
            xu = self.map.size.x // 4
            yu = self.map.size.y // 4
            b = Menu(Position(xu, yu),
                     Position(xu * 2, yu * 2),
                     title="Camera Control")
            b.add('1', "View cameras")
            b.add(
                '2', "Switch %s cameras" %
                (CameraConsole.cameras_on and 'off' or 'on'))
            b.add('x', "Exit")

            c = b.get_key()
            del b

            cams = self.map.find_all(StaticCamera, Monster)

            if c == '1':
                for cam in cams:
                    self.map.prepare_fov(cam.pos, reset=False)
                self.map.player.handle_keys()

            elif c == '2':
                if CameraConsole.cameras_on:
                    for cam in cams:
                        cam.add_effect(StatusEffect.BLIND)
                else:
                    for cam in cams:
                        cam.remove_effect(StatusEffect.BLIND)

                CameraConsole.cameras_on = not CameraConsole.cameras_on

            return True
        return False
Example #2
0
    def pickup(self, i):
        """returns True if i picked up successfully"""
        # TODO: move all this into HasInventory interface
        assert isinstance(i, Item), "Can't pick up a %s" % i

        if isinstance(i, Evidence):
            self.evidence.append(i)
            if not i.pos is None:  # found it in a locker
                self.map.remove(i)
            return Player.ITEM_PICKUP_COST

        item_index = None
        items = self.items
        if isinstance(i, SlotItem):
            items = [self.slot_items[i.valid_slot]]
        if not None in items:
            # prompt to drop something; drop it

            xu = self.map.size.x // 4
            yu = self.map.size.y // 4
            b = Menu(Position(xu, yu),
                     Position(xu * 2, yu * 2),
                     title="Pick Up")
            b.add('x', str(i))
            b.add_spacer()
            for idx in range(len(items)):
                v = items[idx]
                b.add('%d' % (idx + 1), str(v))
            c = b.get_key()

            if isinstance(c, str) and c.isnumeric():
                item_index = int(c) - 1
            self.redraw_screen()
            del b
            if item_index is None or item_index >= len(items):
                return 0.0
            items[item_index].drop_at(self.pos)
            self.map.add(items[item_index])
        else:
            item_index = items.index(None)

        if isinstance(i, SlotItem):
            self.slot_items[i.valid_slot] = i
        else:
            self.items[item_index] = i

        if not i.pos is None:  # if taken from locker or other bonus
            self.map.remove(i)
        i.take_by(self)
        return Player.ITEM_PICKUP_COST
Example #3
0
    def drop(self):
        # prompt to drop something; drop it
        xu = self.map.size.x // 4
        yu = self.map.size.y // 4
        b = Menu(Position(xu, yu), Position(xu * 2, yu * 2), title="Drop")

        b.add('x', 'Do nothing')
        b.add_spacer()

        for idx in range(len(self.items)):
            v = self.items[idx]
            if not v is None:
                b.add('%d' % (idx + 1), str(v))

        b.add_spacer()
        idx += 1

        for k in self.slot_keys:
            idx += 1
            if not self.slot_items[k] is None:
                b.add('%d' % idx, str(self.slot_items[k]))

        c = b.get_key()

        item_index = None
        if isinstance(c, str) and c.isnumeric():
            item_index = int(c) - 1
        self.redraw_screen()
        del b

        if item_index is None:
            return 0.0

        i = None
        if item_index < len(self.items):
            i = self.items[item_index]
            self.items[item_index] = None
        elif item_index < len(self.items) + len(self.slot_keys):
            k = self.slot_keys[item_index - len(self.items)]
            i = self.slot_items[k]
            self.slot_items[k] = None

        if not i is None:
            i.drop_at(self.pos)
            self.map.add(i)
            return self.ITEM_DROP_COST

        return 0.0
Example #4
0
 def apply_to(self, map_array):
     r = []
     kw2 = len(self.masks[0]) // 2
     kh2 = len(self.masks[0][0]) // 2
     for mci in range(kw2, len(map_array) - kw2):
         for mri in range(kh2, len(map_array[mci]) - kh2):
             for mask in self.masks:
                 ok = True
                 for kci in range(-kw2, kw2 + 1):
                     for kri in range(-kh2, kh2 + 1):
                         #print("%2x&%2x "%(map_array[mci+kci][mri+kri], mask[kci+kw2][kri+kh2]), end="")
                         if not (map_array[mci + kci][mri + kri]
                                 & mask[kci + kw2][kri + kh2]) and not (
                                     map_array[mci + kci][mri + kri] == 0
                                     and mask[kci + kw2][kri + kh2]
                                     & MapPattern.WALL):
                             #print("!", end="")
                             ok = False
                             #break
                     #print()
                     if not ok:
                         break
                 #print("-----------------")
                 if ok:
                     #print("WOOOOOO")
                     r.append(Position(mci, mri))
                 #return r
     return r
Example #5
0
 def __init__(self, pos):
     Tile.__init__(self, pos, Door.CLOSED['symbol'], Door.CLOSED['colour'],
                   Door.CLOSED['walkcost'], Door.CLOSED['transparency'])
     CountUp.__init__(self, Door.CLOSED['timer'])
     TurnTaker.__init__(self, 5)
     self.unseen_symbol = Door.CLOSED[
         'symbol']  # always shows as closed when can't be seen
     self.state = Door.CLOSED
     self.bar = HBar(Position(pos.x - 1, pos.y - 1), 3,
                     Door.CLOSED['barcolour'], libtcod.darkest_grey)
     self.bar.max_value = self.count_to - 1
     self.bar.timeout = 5.0
     self._trying_to_open = False
Example #6
0
    def activate(self, activator=None):
        if CountUpTile.activate(self, activator):
            xu = self.map.size.x // 4
            yu = self.map.size.y // 4
            b = Menu(Position(xu, yu),
                     Position(xu * 2, yu * 2),
                     title="Trap Control")
            b.add('1', "View traps")
            b.add(
                '2',
                "%s traps" % (TrapConsole.traps_on and 'Disable' or 'Enable'))
            b.add('3', "Set off traps")
            b.add('x', "Exit")

            c = b.get_key()
            del b

            traps = self.map.find_all(Trap, Tile)

            if c == '1':
                for t in traps:
                    t.visible_to_player = True
                self.map.player.handle_keys()

            elif c == '2':
                for trap in traps:
                    trap.enabled = TrapConsole.traps_on

                TrapConsole.traps_on = not TrapConsole.traps_on

            elif c == '3':
                for trap in traps:
                    trap.trip()

            return True
        return False
Example #7
0
    def redraw_screen(self, t=0):
        # draw and flush screen
        if not UI.need_update(t):
            # clearly one of the libtcod functions here causes the wait for the next frame
            sleep(1.0 / Player.LIMIT_FPS)
            return

        self.map.draw()
        self.draw_ui(Position(0, Player.SCREEN_SIZE.y - 3))
        UI.draw_all(t)

        libtcod.console_flush()

        # clear screen
        libtcod.console_clear(0)
Example #8
0
 def __init__(self,
              pos,
              symbol,
              colour,
              walk_cost=0.0,
              transparency=0.0,
              may_block_movement=False,
              count_up=10):
     Tile.__init__(self, pos, symbol, colour, walk_cost, transparency,
                   may_block_movement)
     CountUp.__init__(self, count_up + 1)
     #TurnTaker.__init__(self, 0)
     Activatable.__init__(self)
     self.bar = HBar(Position(pos.x - 2, pos.y - 1), 5, libtcod.light_blue,
                     libtcod.darkest_grey)
     self.bar.max_value = self.count_to - 1
     self.bar.timeout = 5.0
Example #9
0
# system imports
import os
import sys

# libtcod
import libtcodpy as libtcod

# our imports
from interfaces import Position, TurnTaker
from ui import UI
from maps import Map
from player import Player
from errors import GameOverError, LevelWinError

SCREEN_SIZE = Position(80, 50)
LIMIT_FPS = 10
RANDOM_SEED = 1999
MAP = None
PLAYER = None

# for now
if len(sys.argv) > 1 and sys.argv[0].startswith('DalekRL') and len(
        sys.argv[1]) > 0:
    RANDOM_SEED = int(sys.argv[1]) - 1


def init():
    # init window
    font = os.path.join(b'resources', b'consolas10x10_gs_tc.png')
    libtcod.console_set_custom_font(
Example #10
0
def sync_positions(date_since,date_now,countryLookup,rest):

    field_list = "id,externalID,address,title,status,clientCorporation,dateLastModified,dateAdded,description,isOpen"

    position_list_query = "search/JobOrder?query=dateLastModified:[{0} TO {1}] AND isDeleted:0&sort=dateLastModified&fields={2}&count=100".format(date_since,date_now,field_list)

    url = position_list_query

    print(url)

    jres = make_list_request(url,rest)

    positions=[]
    if jres != None:

        position_list=jres["Results"]
        total_records=jres["TotalRecords"]

        for pos in position_list:

            #print(pos)

            position=Position()
            position.id="p" + str(pos["id"])

            if "title" in pos:
                if pos["title"] != None:
                    position.job_title=pos["title"].encode("utf-8").strip()

            if "address" in pos:
                addr = pos["address"]
                if "countryID" in addr:
                    if addr["countryID"] != None:
                        if addr["countryID"] in countryLookup :
                            position.position_location=countryLookup[addr["countryID"]].encode("utf-8")

                if "city" in addr:
                    if addr["city"] != None:
                        position.city=addr["city"].encode("utf-8").strip()

                if "state" in addr:
                    if addr["state"] != None:
                        position.state=addr["state"].encode("utf-8").strip()

                if "zip" in addr:
                    if addr["zip"] != None:
                        position.postal_code=addr["zip"].encode("utf-8").strip()

            if "clientCorporation" in pos:
                company = pos["clientCorporation"]
                if "name" in company:
                    if company["name"] != None:
                        position.company_name=company["name"].encode("utf-8").strip()

            if "externalID" in pos:
                if pos["externalID"] != None:
                    position.position_id=pos["externalID"].encode("utf-8").strip()

            if "status" in pos:
                if pos["status"] != None:
                    position.status=pos["status"].encode("utf-8").strip()

            if "isOpen" in pos:
                if pos["isOpen"] != None:
                    if pos["isOpen"] == True:
                        position.open_closed="Open"
                    else:
                        position.open_closed="Closed"

            if "dateAdded" in pos:
                if pos["dateAdded"] != None:
                    date_added = datetime.fromtimestamp(int(pos["dateAdded"])/1000).strftime('%Y-%m-%dT%H:%M:%S')
                    position.date_entered=date_added

            if "dateLastModified" in pos:
                if pos["dateLastModified"] != None:
                    date_last_modified = datetime.fromtimestamp(int(pos["dateLastModified"])/1000).strftime('%Y-%m-%dT%H:%M:%S')
                    position.last_modified=date_last_modified

            if "description" in pos:
                if pos["description"] != None:
                    position.job_description_words=cleanup_text(strip_html_bs(pos["description"].encode("utf-8")))

            positions.append(position)

    return positions
Example #11
0
def sync_positions(date_since, date_now, rest):

    #salesforce is limited to 2000 records returned but will return the total number of rows
    #we iterate through 2000 at a time updating the query criteria with the LastModifiedDate of
    #the last processed record
    keep_processing = True
    work_done = False

    while keep_processing:

        results = rest.make_rest_call(
            "query?q=SELECT+Id,Name,TR1__Account_Name__c,TR1__City__c,TR1__Client_Job_Description__c,LastModifiedDate,CreatedDate+FROM+TR1__Job__c+WHERE+LastModifiedDate+>+{0}+ORDER+BY+LastModifiedDate+asc"
            .format(date_since))

        result_rows = len(results["records"])

        if result_rows > 0:

            total_result_rows = results["totalSize"]

            print(results["totalSize"], len(results["records"]))

            positions = []

            for pos in results["records"]:

                position = Position()
                position.id = "p" + str(pos["Id"])

                if "Name" in pos:
                    if pos["Name"] != None:
                        position.job_title = pos["Name"].encode(
                            "utf-8").strip()

                if "TR1__Account_Name__c" in pos:
                    if pos["TR1__Account_Name__c"] != None:
                        position.company_name = pos[
                            "TR1__Account_Name__c"].encode("utf-8").strip()

                if "TR1__City__c" in pos:
                    if pos["TR1__City__c"] != None:
                        position.position_location = pos[
                            "TR1__City__c"].encode("utf-8").strip()

                if "TR1__Client_Job_Description__c" in pos:
                    if pos["TR1__Client_Job_Description__c"] != None:
                        position.description = cleanup_text(
                            strip_html_bs(
                                pos["TR1__Client_Job_Description__c"].encode(
                                    "utf-8").strip()))

                if "CreatedDate" in pos:
                    if pos["CreatedDate"] != None:
                        date_added = pos["CreatedDate"]
                        position.date_entered = date_added

                if "LastModifiedDate" in pos:
                    if pos["LastModifiedDate"] != None:
                        date_last_modified = pos["LastModifiedDate"]
                        position.last_modified = date_last_modified

                positions.append(position)

            write_position_data(positions)

            work_done = True
            if total_result_rows > 2000:
                date_since = results["records"][-1][
                    "LastModifiedDate"].replace(".000+0000", "Z")
            else:
                keep_processing = False
        else:
            keep_processing = False

    return work_done
Example #12
0
class Player(Activator, TurnTaker, StatusEffect, HasInventory, LightSource,
             Mappable):
    # these don't really belong here
    SCREEN_SIZE = Position(80, 50)
    LIMIT_FPS = 15
    MAX_TIMEOUT = 5

    # these do though
    ITEM_ACTIVATE_COST = 0.6
    ITEM_PICKUP_COST = 1.0
    ITEM_DROP_COST = 1.0

    def __init__(self, pos=None):
        Mappable.__init__(self, pos, '@', libtcod.white)
        StatusEffect.__init__(self)
        TurnTaker.__init__(self, 1)
        HasInventory.__init__(
            self, 3,
            (SlotItem.HEAD_SLOT, SlotItem.BODY_SLOT, SlotItem.FEET_SLOT))
        LightSource.__init__(self, 2, 0.1)
        self.items = [None, None, None]
        self.slot_items = {
            SlotItem.HEAD_SLOT: None,
            SlotItem.BODY_SLOT: None,
            SlotItem.FEET_SLOT: None,
        }
        self.turns = 0
        self.evidence = []
        self.levels_seen = 1

        # init items (must be done this way to invoke any pickup triggers)
        #  - inv items
        self.pickup(Item.random(None, self, 2, 1.5))
        self.pickup(Item.random(None, self, 1))
        #  - slot items
        self.pickup(NightVisionGoggles(self))
        self.pickup(NinjaSuit(self))
        self.pickup(RunningShoes(self))

        self.KEYMAP = {
            'k': self.move_n,
            'j': self.move_s,
            'h': self.move_w,
            'l': self.move_e,
            'y': self.move_nw,
            'u': self.move_ne,
            'b': self.move_sw,
            'n': self.move_se,
            '.': self.do_nothing,
            '1': self.use_item1,
            '2': self.use_item2,
            '3': self.use_item3,
            '4': self.use_head,
            '5': self.use_body,
            '6': self.use_feet,
            'Q': sys.exit,
            'R': self.reset_game,
            ' ': self.interact,
            'd': self.drop,
            'L': self.debug_lighting,
        }

    #@property
    #def light_level(self):
    #    # cap min light level
    #    l = self.map.light_level(self.pos)
    #    if libtcod.color_get_hsv(l)[2] < 0.2:
    #        return libtcod.dark_grey
    #    return l

    def __str__(self):
        return "Player at %s" % self.pos

    def use_item(self, slot):
        assert slot in self.slot_items.keys() or slot < len(
            self.items), "Using undefined item slot"

        item = None
        if slot in self.slot_items.keys():
            item = self.slot_items[slot]
        elif isinstance(slot, int):
            item = self.items[slot]

        if item is None:
            return 0.0
        assert isinstance(item, Activatable)

        if item.activate(self):
            return Player.ITEM_ACTIVATE_COST
        else:
            return 0.0

    def draw_ui(self, pos, max_size=80):
        # UI constants TODO: move them
        COL_W = 24
        C_MARGIN_W = 1

        # print inventory items
        for i in range(len(self.items)):
            libtcod.console_print(0, pos.x, pos.y + i, "%d." % (i + 1))
            if self.items[i] is None:
                libtcod.console_print(0, pos.x + 3, pos.y + i,
                                      "--- Nothing ---")
            else:
                self.items[i].draw_ui(pos + (3, i), COL_W)

        # print slot items
        i = 4
        for s in self.slot_keys:
            libtcod.console_print(0, pos.x + COL_W + 3 + C_MARGIN_W,
                                  pos.y + i - 4, "%d." % (i))
            if self.slot_items[s] is None:
                libtcod.console_print(0, pos.x + COL_W + 3 + C_MARGIN_W + 3,
                                      pos.y + i - 4, "--- Nothing ---")
            else:
                self.slot_items[s].draw_ui(
                    pos + (COL_W + 3 + C_MARGIN_W + 3, i - 4), COL_W)
            i += 1

        # print info
        libtcod.console_print(0, pos.x + COL_W * 2 + C_MARGIN_W * 2 + 3 + 3,
                              pos.y, "Level:    %5d" % self.levels_seen)
        libtcod.console_print(0, pos.x + COL_W * 2 + C_MARGIN_W * 2 + 3 + 3,
                              pos.y + 1, "Evidence: %5d" % len(self.evidence))
        libtcod.console_print(0, pos.x + COL_W * 2 + C_MARGIN_W * 2 + 3 + 3,
                              pos.y + 2, "Turns:    %5d" % self.turns)

    def reset_fov(self):
        if self.has_effect(StatusEffect.BLIND):
            return self.map.prepare_fov(self.pos, 4)
        elif self.has_effect(StatusEffect.X_RAY_VISION):
            return self.map.prepare_fov(self.pos, 10)
        else:
            return self.map.prepare_fov(self.pos, 0)

    def pickup(self, i):
        """returns True if i picked up successfully"""
        # TODO: move all this into HasInventory interface
        assert isinstance(i, Item), "Can't pick up a %s" % i

        if isinstance(i, Evidence):
            self.evidence.append(i)
            if not i.pos is None:  # found it in a locker
                self.map.remove(i)
            return Player.ITEM_PICKUP_COST

        item_index = None
        items = self.items
        if isinstance(i, SlotItem):
            items = [self.slot_items[i.valid_slot]]
        if not None in items:
            # prompt to drop something; drop it

            xu = self.map.size.x // 4
            yu = self.map.size.y // 4
            b = Menu(Position(xu, yu),
                     Position(xu * 2, yu * 2),
                     title="Pick Up")
            b.add('x', str(i))
            b.add_spacer()
            for idx in range(len(items)):
                v = items[idx]
                b.add('%d' % (idx + 1), str(v))
            c = b.get_key()

            if isinstance(c, str) and c.isnumeric():
                item_index = int(c) - 1
            self.redraw_screen()
            del b
            if item_index is None or item_index >= len(items):
                return 0.0
            items[item_index].drop_at(self.pos)
            self.map.add(items[item_index])
        else:
            item_index = items.index(None)

        if isinstance(i, SlotItem):
            self.slot_items[i.valid_slot] = i
        else:
            self.items[item_index] = i

        if not i.pos is None:  # if taken from locker or other bonus
            self.map.remove(i)
        i.take_by(self)
        return Player.ITEM_PICKUP_COST

    def do_nothing(self):
        return self.move((0, 0))  # triggers try_movement on current square

    def reset_game(self):
        raise GameOverError

    def debug_lighting(self):
        if not self.map is None:
            self.map.debug_lighting()
        return 0.0

    def move_n(self):
        return self.move((0, -1))

    def move_s(self):
        return self.move((0, 1))

    def move_w(self):
        return self.move((-1, 0))

    def move_e(self):
        return self.move((1, 0))

    def move_ne(self):
        return self.move((1, -1))

    def move_nw(self):
        return self.move((-1, -1))

    def move_se(self):
        return self.move((1, 1))

    def move_sw(self):
        return self.move((-1, 1))

    def use_item1(self):
        return self.use_item(0)

    def use_item2(self):
        return self.use_item(1)

    def use_item3(self):
        return self.use_item(2)

    def use_head(self):
        return self.use_item(SlotItem.HEAD_SLOT)

    def use_body(self):
        return self.use_item(SlotItem.BODY_SLOT)

    def use_feet(self):
        return self.use_item(SlotItem.FEET_SLOT)

    def interact(self):
        # TODO: manage situation where multiple items are on same tile gracefully
        r = 0.0
        i = self.map.find_at_pos(self.pos, Item)
        if not i is None:
            r += self.pickup(i)
        for i in self.map.find_all_at_pos(self.pos, Tile):
            if isinstance(i, Activatable):
                if i.activate(self):
                    r += 1.0
        #return r # whilst we can calculate cumulative cost of all this stuff; actually want to end turn regardless
        return 1.0

    def drop(self):
        # prompt to drop something; drop it
        xu = self.map.size.x // 4
        yu = self.map.size.y // 4
        b = Menu(Position(xu, yu), Position(xu * 2, yu * 2), title="Drop")

        b.add('x', 'Do nothing')
        b.add_spacer()

        for idx in range(len(self.items)):
            v = self.items[idx]
            if not v is None:
                b.add('%d' % (idx + 1), str(v))

        b.add_spacer()
        idx += 1

        for k in self.slot_keys:
            idx += 1
            if not self.slot_items[k] is None:
                b.add('%d' % idx, str(self.slot_items[k]))

        c = b.get_key()

        item_index = None
        if isinstance(c, str) and c.isnumeric():
            item_index = int(c) - 1
        self.redraw_screen()
        del b

        if item_index is None:
            return 0.0

        i = None
        if item_index < len(self.items):
            i = self.items[item_index]
            self.items[item_index] = None
        elif item_index < len(self.items) + len(self.slot_keys):
            k = self.slot_keys[item_index - len(self.items)]
            i = self.slot_items[k]
            self.slot_items[k] = None

        if not i is None:
            i.drop_at(self.pos)
            self.map.add(i)
            return self.ITEM_DROP_COST

        return 0.0

    def take_turn(self):
        # runs just before handle_keys, so expensive ops run whilst player chooses what to do
        Talker.stop_all_talk()
        self.reset_fov()
        #self.map.recalculate_lighting()

        self.turns += 1
        t_remaining = 1.0  # TODO: weight this based on passive buffs
        have_used_item = False

        while t_remaining > 0.0:
            self.map.recalculate_dirty()
            try:
                # handle player input (and redraw screen)
                f = self.handle_keys()

                # TODO: fix this monstrous way of detecting item use
                if f.__name__.startswith('use_'):
                    if not have_used_item:
                        have_used_item = True
                    else:
                        # TODO: this is wrong! two consecutive item uses should
                        #       register as two valid keypresses
                        raise InvalidMoveError

                t_remaining -= f()

            except InvalidMoveContinueError:
                print("You can't move like that")

            except InvalidMoveError:
                # this is ok, like teleporting
                t_remaining = 0.0

    def handle_keys(self):
        """returns pointer to function to call"""
        k = libtcod.Key()
        m = libtcod.Mouse()

        for t in range(Player.LIMIT_FPS * Player.MAX_TIMEOUT):
            if t % 5 == 0:
                self.redraw_screen(t / Player.LIMIT_FPS)

            ev = libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, k, m)
            if ev and k and k.pressed and chr(k.c) in self.KEYMAP:
                return self.KEYMAP.get(chr(k.c))

        # redraw screen after first second after keypress
        self.redraw_screen(Player.MAX_TIMEOUT)

        # call this before going into while loop to make sure no keypresses get dropped
        ev = libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, k, m)

        while True:
            if k and k.pressed and chr(k.c) in self.KEYMAP:
                return self.KEYMAP.get(chr(k.c))
            k = libtcod.console_wait_for_keypress(True)

    def redraw_screen(self, t=0):
        # draw and flush screen
        if not UI.need_update(t):
            # clearly one of the libtcod functions here causes the wait for the next frame
            sleep(1.0 / Player.LIMIT_FPS)
            return

        self.map.draw()
        self.draw_ui(Position(0, Player.SCREEN_SIZE.y - 3))
        UI.draw_all(t)

        libtcod.console_flush()

        # clear screen
        libtcod.console_clear(0)

    def refresh_turntaker(self):
        TurnTaker.refresh_turntaker(self)
        for i in self.items + list(self.slot_items.values()):
            # switch off active rundownitem items before level transition
            if isinstance(i, RunDownItem) and i.is_active:
                print("switching off %s" % i)
                i.activate()
            elif isinstance(i, TurnTaker):
                i.refresh_turntaker()

            # TODO: this isn't great :(
            if hasattr(i, 'bar') and isinstance(i.bar, UI):
                i.bar.refresh_ui_list()