def find(self, selected, item_type, entry_type, find): if not selected.IsOk(): self.status_bar.SetStatusText('No matches found') return # Get next item item = get_next_item(self.part_sets_list, selected) if not item.IsOk(): item, _ = get_first_item(self.part_sets_list) # Loop over while item != selected: data = self.part_sets_list.GetItemData(item) if (type(data) == item_type and (find is None or (isinstance(find, int) and data[entry_type] == find) or (isinstance(find, str) and find.lower() in data[entry_type].lower()))): self.select_found(item, entry_type) break item = get_next_item(self.part_sets_list, item) if not item.IsOk(): item, _ = get_first_item(self.part_sets_list) else: self.status_bar.SetStatusText('No matches found')
def reindex(self): # Set indexes first item, _ = get_first_item(self.entry_list) index = 1 mappings = {} while item.IsOk(): entry = self.entry_list.GetItemData(item) old_address, entry.address = entry.address, index_to_address(index) mappings[old_address] = entry.address self.entry_list.SetItemText(item, f'Entry {index}') item = get_next_item(self.entry_list, item) index += 1 # Set parent/child/sibling/root item, _ = get_first_item(self.entry_list) root = 0 entries = [self.entry_list.GetItemData(self.entry_list.GetRootItem())] while item.IsOk(): entry = self.entry_list.GetItemData(item) text = self.entry_list.GetItemText(item) sibling = self.entry_list.GetNextSibling(item) child, _ = self.entry_list.GetFirstChild(item) parent = self.entry_list.GetItemParent(item) sibling_address = self.entry_list.GetItemData( sibling).address if sibling.IsOk() else 0 child_address = self.entry_list.GetItemData( child).address if child.IsOk() else 0 # Root will always be one of the immediate childs to Entry 0 if parent == self.entry_list.GetRootItem(): root = entry.address # If the mapping for the sibling/child has been deleted, reset it if entry.sibling: entry.sibling = mappings.get(entry.sibling, 0) if not entry.sibling: entry.sibling = sibling_address if entry.child: entry.child = mappings.get(entry.child, 0) if not entry.child: entry.child = child_address entry.parent = self.entry_list.GetItemData( parent ).address if parent != self.entry_list.GetRootItem() else 0 entry.root = root if sibling_address != entry.sibling: text += f", Sibling: {address_to_index(entry.sibling)}" if child_address != entry.child: text += f", Child: {address_to_index(entry.child)}" self.entry_list.SetItemText(item, text) entries.append(entry) item = get_next_item(self.entry_list, item) self.parent.bcm.entries = entries
def get_children(self, entry): parents = [self.entry_list.GetItemData(entry).address] children = [] item = get_next_item(self.entry_list, entry) while item.IsOk(): data = self.entry_list.GetItemData(item) if data.parent not in parents: break parents.append(data.address) children.append(item) item = get_next_item(self.entry_list, item) return children
def reindex(self, selected=None): for i, entry in enumerate(self.bac.entries): entry.index = i # entry.flags = entry.flags & 0xF if len(entry.sub_entries) > 0 else (entry.flags & 0x0F) | 0x80000000 entry.sub_entries.sort(key=lambda n: n.type) for j, sub_entry in enumerate(entry.sub_entries): sub_entry.index = j sub_entry.items.sort(key=lambda n: n.start_time) for k, item in enumerate(sub_entry.items): item.index = k item, _ = get_first_item(self.entry_list) hidden = self.parent.hidden.GetValue() # Fix tree names while item.IsOk(): to_delete = None data = self.entry_list.GetItemData(item) if data.get_name() == 'Entry': if selected != item and hidden and not self.entry_list.GetFirstChild( item)[0].IsOk(): to_delete = item else: self.entry_list.SetItemText( item, f'{data.index}: Entry (0x{data.flags:X})') elif data.get_name() == 'SubEntry': if selected != item and hidden and not self.entry_list.GetFirstChild( item)[0].IsOk(): to_delete = item else: self.entry_list.SetItemText( item, f'{data.type}: {data.get_type_name()}') sub_entry = self.entry_list.GetItemData(item) for entry in sub_entry.items: item = get_next_item(self.entry_list, item) self.entry_list.SetItemData(item, entry) # UNLEASHED: do the same as the build_sub_tree function if entry.description and entry.description_type: self.entry_list.SetItemText( item, str(entry.start_time) + " - " + entry.description.get( entry.__getattr__(entry.description_type), 'Unknown')) else: self.entry_list.SetItemText( item, str(entry.start_time)) item = get_next_item(self.entry_list, item) if to_delete: self.entry_list.Delete(to_delete)
def reindex_part_colors(self, selected=None): if not self.bcs: return if not self.bcs.part_colors: return item = self.part_color_list.GetRootItem() part_color_name = '' part_color_index = 0 color_index = 0 while item: data = self.part_color_list.GetItemData(item) if isinstance(data, PartColor): self.part_color_list.SetItemText( item, f"{part_color_index}: {data.name}") part_color_name = data.name part_color_index += 1 color_index = 0 elif isinstance(data, Color): if part_color_index - 1 > len(color_db): data.part_color_index = 0 data.color = 0 image_index = color_db[part_color_index - 1][color_index] if part_color_name == 'eye_': bitmap = wx.Bitmap.FromRGBA(16, 16, *data.color4[:3], 255) else: bitmap = wx.Bitmap.FromRGBA(16, 16, *data.color1[:3], 255) color_db.image_list.Replace(image_index, bitmap) self.part_color_list.SetItemText(item, f"{color_index}") color_index += 1 item = get_next_item(self.part_color_list, item)
def find(self, selected, entry_type, find): if not selected.IsOk(): self.status_bar.SetStatusText('No matches found') return item = get_next_item(self.entry_list, selected) while item != selected: data = self.entry_list.GetItemData(item) if find is None or data[entry_type] == find or ( isinstance(data[entry_type], float) and abs(data[entry_type] - find) < 0.000001): self.select_found(item, entry_type) break item = get_next_item(self.entry_list, item) if not item.IsOk(): item = get_first_item(self.entry_list)[0] else: self.status_bar.SetStatusText('No matches found')
def find(self, item_type, entry_type, value): item = get_first_item(self.entry_list)[0] while item.IsOk(): data = self.entry_list.GetItemData(item) if self.entry == data: item = self.entry_list.GetNextSibling(item) continue elif isinstance(data, item_type) and data[entry_type] == value: return 'Conflict Found!' item = get_next_item(self.entry_list, item) return ''
def convert_for_skill_creator(self): if not self.bac: with wx.MessageDialog(self, "No BAC loaded!", "Error") as dlg: dlg.ShowModal() return # Get Choices choices = set() item, _ = get_first_item(self.entry_list) while item.IsOk(): data = self.entry_list.GetItemData(item) item = get_next_item(self.entry_list, item) if 'skill_id' not in data.__fields__: continue if data.skill_id != 0 and data.skill_id != 0xFFFF and data.skill_id != 0xBACA: choices.update([str(data.skill_id)]) if not choices: with wx.MessageDialog(self, "Cannot find any Skill IDs to convert", "Error") as dlg: dlg.ShowModal() return # Show Dialog with ConvertDialog(self, list(choices)) as dlg: if dlg.ShowModal() != wx.ID_OK: return skill_id = dlg.GetValue() # Do conversion item, _ = get_first_item(self.entry_list) changed = 0 while item.IsOk(): data = self.entry_list.GetItemData(item) if 'skill_id' in data.__fields__ and data.skill_id == skill_id: data.skill_id = 0xBACA changed += 1 item = get_next_item(self.entry_list, item) self.on_select(None) pub.sendMessage('set_status_bar', text=f'Changed {changed} skill ids to 0xBACA')
def find_next_available_index(self, item_type, entry, dependency, depend_value): max_value = 0 item = get_first_item(self.entry_list)[0] while item.IsOk(): data = self.entry_list.GetItemData(item) if isinstance(data, item_type) and \ (not dependency or data[dependency] == depend_value) and data[entry] != 0xFFFF: max_value = max(data[entry], max_value) item = get_next_item(self.entry_list, item) return max_value + 1
def on_replace_all(self, _): if not color_db.bcs: self.status_bar.SetStatusText("BCS Not Loaded") return item_type, fields = FIND_ITEM_TYPES[self.items.GetSelection()] entry_type = fields[self.entry.GetSelection()] find = self.find_ctrl.GetValue() replace = self.replace_ctrl.GetValue() if "name" not in entry_type: try: find = int(self.find_ctrl.GetValue(), 0) replace = int(self.replace_ctrl.GetValue(), 0) except ValueError: self.status_bar.SetStatusText("Invalid Value") return count = 0 skipped = 0 skipped_entries = set() item, _ = get_first_item(self.part_sets_list) while item.IsOk(): data = self.part_sets_list.GetItemData(item) res = self.replace_item(data, item_type, entry_type, find, replace, skipped_entries) if res == Replace.REPLACED: count += 1 elif res == Replace.SKIPPED: skipped += 1 item = get_next_item(self.part_sets_list, item) self.main_panel.pages["Part Sets"].on_select(None) pub.sendMessage('reindex_part_sets') msg = f'Replaced {count} entry(s) (skipped {skipped}). ' if skipped: msg += "Check your part colors" self.status_bar.SetStatusText(msg) if item_type == ColorSelector and skipped_entries: if entry_type == "part_colors": msg = "\n".join( f" * Color Selector ({cs[0]}, {cs[1]}) -> ({replace}, {cs[1]})" for cs in sorted(skipped_entries)) else: msg = "\n".join( f" * Color Selector ({cs[0]}, {cs[1]}) -> ({cs[0]}, {replace})" for cs in sorted(skipped_entries)) with MultiMessageDialog( self, f"The following Color Selectors were skipped.\n" f"Please check your part colors.", "Warning", msg, wx.OK) as dlg: dlg.ShowModal()
def relabel(self, index): item = self.entry_list.GetRootItem() for _ in range(index): item = get_next_item(self.entry_list, item) entry = self.entry_list.GetItemData(item) sibling = self.entry_list.GetNextSibling(item) child, _ = self.entry_list.GetFirstChild(item) sibling_address = self.entry_list.GetItemData( sibling).address if sibling.IsOk() else 0 child_address = self.entry_list.GetItemData( child).address if child.IsOk() else 0 text = f'Entry {index}' if sibling_address != entry.sibling: text += f", Sibling: {address_to_index(entry.sibling)}" if child_address != entry.child: text += f", Child: {address_to_index(entry.child)}" self.entry_list.SetItemText(item, text)
def reindex_bodies(self, selected=None): if not self.bcs: return if not self.bcs.bodies: return body_index = 0 bone_scale_index = 0 item = self.body_list.GetRootItem() while item: data = self.body_list.GetItemData(item) if isinstance(data, Body): self.body_list.SetItemText(item, f"{body_index}: Body") body_index += 1 bone_scale_index = 0 elif isinstance(data, BoneScale): self.body_list.SetItemText(item, f"{bone_scale_index}: {data.name}") bone_scale_index += 1 item = get_next_item(self.body_list, item)
def on_replace_all(self, _): entry_type = self.choices[self.entry.GetSelection()] try: find = self.get_value(self.find_ctrl) replace = self.get_value(self.replace_ctrl) except ValueError: self.status_bar.SetStatusText("Invalid Value") return None count = 0 item = get_first_item(self.entry_list)[0] while item.IsOk(): data = self.entry_list.GetItemData(item) if data[entry_type] == find or ( isinstance(data[entry_type], float) and abs(data[entry_type] - find) < 0.000001): data[entry_type] = replace count += 1 item = get_next_item(self.entry_list, item) pub.sendMessage('on_select', _=None) self.status_bar.SetStatusText(f'Replaced {count} entry(s)')
def reindex_skeletons(self, selected=None): if not self.bcs: return if not self.bcs.skeletons: return item = self.skeleton_list.GetRootItem() skeleton_index = 0 bone_index = 0 while item: data = self.skeleton_list.GetItemData(item) if isinstance(data, Skeleton): self.skeleton_list.SetItemText(item, f"{skeleton_index}: Skeleton") skeleton_index += 1 bone_index = 0 elif isinstance(data, Bone): self.skeleton_list.SetItemText(item, f"{bone_index}: {data.name}") bone_index += 1 item = get_next_item(self.skeleton_list, item)
def reindex_part_sets(self, selected=None): if not self.bcs: return if not self.bcs.part_sets: return item = root = self.part_set_list.GetRootItem() part_set_index = 0 color_selector_index = 0 physics_index = 0 while item: data = self.part_set_list.GetItemData(item) num_children = self.part_set_list.GetChildrenCount(item) if isinstance(data, PartSet): self.part_set_list.SetItemText(item, f"{part_set_index}: Part Set") part_set_index += 1 elif isinstance(data, Part): color_selector_index = 0 physics_index = 0 elif isinstance(data, ColorSelector): name = self.bcs.part_colors[data.part_colors].name try: image = color_db[data.part_colors][data.color] self.part_set_list.SetItemText( item, f"{color_selector_index}: {name}, {data.color}") self.part_set_list.SetItemImage(item, image) except IndexError: self.part_set_list.SetItemText( item, f"{color_selector_index}: NULL, -1") self.part_set_list.SetItemImage(item, -1) color_selector_index += 1 elif isinstance(data, Physics): self.part_set_list.SetItemText(item, f"{physics_index}") physics_index += 1 elif item != root and num_children == 0: self.part_set_list.Delete(item) item = get_next_item(self.part_set_list, item)
def on_replace_all(self, _): item_type = ITEM_TYPES[self.items.GetSelection()] entry_type = item_type.bac_record.__fields__[self.entry.GetSelection()] try: find = self.get_value(self.find_ctrl) replace = self.get_value(self.replace_ctrl) except ValueError as e: print(e) self.status_bar.SetStatusText("Invalid Value") return None count = 0 item = get_first_item(self.entry_list)[0] while item.IsOk(): data = self.entry_list.GetItemData(item) if type(data) == item_type and ( data[entry_type] == find or (isinstance(data[entry_type], float) and abs(data[entry_type] - find) < 0.000001)): data[entry_type] = replace count += 1 item = get_next_item(self.entry_list, item) pub.sendMessage('on_select', _=None) pub.sendMessage('reindex') self.status_bar.SetStatusText(f'Replaced {count} entry(s)')