Ejemplo n.º 1
0
def run(main_gui_class):
	# https://leomoon.com/journal/python/high-dpi-scaling-in-pyqt5/
	QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True) #enable highdpi scaling
	QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True) #use highdpi icons

	app = QtWidgets.QApplication(sys.argv)

	# START APPLICATION
	MainWindow = QtWidgets.QMainWindow()
	ui = main_gui_class()
	ui.MainWindow = MainWindow  # Allow class to set internals
	ui.setupUi(MainWindow)
	if hasattr(ui, 'save_defaults'):
		MainWindow.closeEvent = lambda self: ui.save_defaults()
	MainWindow.show()

	app.setStyle('Fusion')
	stylesheet_file = config.resource_path(Path("apps/GUI/shared/stylesheets/darkorange.css"))
	with open(stylesheet_file) as f:
		MainWindow.setStyleSheet(f.read())

	# APPLICATION EXIT
	try:
		ret = app.exec_()
	except:  # This doesn't catch a lot of things, since often abort is called
		if hasattr(ui, 'save_defaults'):
			ui.save_defaults()
		raise
	sys.exit(ret)
Ejemplo n.º 2
0
	def get_equipment(force_update=False):
		def filter(i):
			partial = {k: v for k, v in i.items() if k in [
				'name', 'id', 'weight', 'wiki_url', 'equipment', 'weapon'
			]}
			
			## Convert stances from a list to a dictionary
			if partial['weapon'] is not None:
				partial['weapon']['stances'] = {
					s['combat_style']: s for s in partial['weapon']['stances']
				}
			
			## Corrections
			# For some reason, "Mithril crossbow" is incorrectly called "Mith crossbow".
			partial['name'] = "Mithril crossbow" if partial['name'] == 'Mith crossbow' else partial['name']
			
			# Salamander's incorrectly have None as the attack style
			if partial['name'] in ["Black salamander", "Red salamander", "Orange salamander", "Swamp lizard"]:
				partial['weapon']['stances']['scorch']['attack_style'] = "aggressive"
				partial['weapon']['stances']['scorch']['attack_style'] = "ranged"
				partial['weapon']['stances']['scorch']['attack_style'] = "magic"

			# Crystal staff is a powered staff
			if 'Crystal staff (' in partial['name']:
				partial['weapon']['weapon_type'] = 'trident-class_weapons'

			## Add useful information to stance
			if partial['weapon'] is not None:
				partial['weapon']['stances'] = {
					k: {**s, 
						'combat_class': get_combat_class(s),
						'weapon_type': partial['weapon']['weapon_type'],
					} for k, s in partial['weapon']['stances'].items()
				}
			
			return partial

		equipment = {}
		for slot in ItemDatabase.SLOTS:
			file_name = f'items-{slot}.json'
			file_path = config.resource_path(Path(f"skills/combat/data/{file_name}"))
			if not file_path.exists() or force_update:
				r = requests.get(ItemDatabase.SLOT_BASE_URL+'/'+file_name)

				with open(file_path, 'w') as f:
					f.write(r.text)

			with open(file_path, 'r') as f:
				equipment.update({int(ID): filter(item) for ID, item in json.load(f).items() if item['equipable_by_player']})

		# Add an unarmed weapon
		UNARMED_ID = 20720  # Bruma Torch is the same as unarmed
		assert 0 not in equipment
		equipment[0] = deepcopy(equipment[UNARMED_ID])
		equipment[0]['name'] = 'Unarmed'
		equipment[0]['id'] = 0
		equipment[0]['weight'] = 0
		equipment[0]['wiki_url'] = "https://oldschool.runescape.wiki/w/Unarmed"

		return equipment
Ejemplo n.º 3
0
    def get_monsters(force_update=False):
        def filter(i):
            return Monster(i)

        file_name = 'monsters-complete.json'
        file_path = config.resource_path(
            Path(f"skills/combat/data/{file_name}"))
        if not file_path.exists() or force_update:
            r = requests.get(MONSTER_LIST_BASE_URL + '/' + file_name)
            if r.status_code != 200:
                raise ValueError("Unable to retrieve monster data.")
            with open(file_path, 'w') as f:
                f.write(r.text)

        with open(file_path, 'r') as f:
            monsters = {
                int(ID): filter(item)
                for ID, item in json.load(f).items()
            }

        return monsters
Ejemplo n.º 4
0
 def get_data_path(self, file):
     return config.resource_path(f"apps/optimize/data/{file}")
Ejemplo n.º 5
0
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)

        icon = QtGui.QIcon()
        icon.addFile(str(config.resource_path("apps/GUI/images/logo.png")),
                     QtCore.QSize(), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)

        self.load_defaults()
        self.loadouts = []
        self.monster_panel.add.clicked.connect(self.add_monster)
        self.optimize_panel.evaluate.clicked.connect(self.on_evaluate)
        self.optimize_panel.dec_selected_set.clicked.connect(
            lambda: self.change_selected_set(change=-1))
        self.optimize_panel.inc_selected_set.clicked.connect(
            lambda: self.change_selected_set(change=+1))
        self.optimize_panel.selected_set_index.returnPressed.connect(
            lambda: self.change_selected_set(index=int(
                self.optimize_panel.selected_set_index.text())))
        self.optimize_panel.opponents.itemDoubleClicked.connect(
            lambda item: self.monster_panel.fill_monster(
                item.text(), self.optimize_panel.data.monsters[item.text()]))
        self.optimize_panel.selected_set_index.setValidator(
            QtGui.QIntValidator())

        self.actionOverview.triggered.connect(lambda: QtWidgets.QMessageBox(
            QtWidgets.QMessageBox.Information, 'Help - Overview', self.
            OVERVIEW_TEXT).exec_())
        self.actionPlayer_Panel.triggered.connect(
            lambda: QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information,
                                          'Help - Player Panel', self.
                                          PLAYER_TEXT).exec_())
        self.actionMonster_Panel.triggered.connect(
            lambda: QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information,
                                          'Help - Monster Panel', self.
                                          MONSTER_TEXT).exec_())
        self.actionOptimize_Panel.triggered.connect(
            lambda: QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information,
                                          'Help - Optimize Panel', self.
                                          OPTIMIZE_TEXT).exec_())
        self.actionShortcuts.triggered.connect(lambda: QtWidgets.QMessageBox(
            QtWidgets.QMessageBox.Information, 'Help - Shortcuts', self.
            SHORTCUTS_TEXT).exec_())

        def update(do):
            if do:
                self.update_status(
                    'Updating Equipment...')  # These don't seem to work
                get_equipment_data(force_update=True)
                self.update_status('Updating Monsters...')
                get_monster_data(force_update=True)
                self.update_status(
                    'Finished Updating Database!')  # but this does.

        self.actionUpdate_Now.triggered.connect(lambda: update(
            QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Question, 'Update Now',
                "Would you like to download the latest equipment and monsters? You only need to do this "
                "if you want to use those new entities. "
                "If something is missing after updating, it is also possible that the osrsbox database has not yet been updated. "
                "Try again on another day.", QtWidgets.QMessageBox.Yes |
                QtWidgets.QMessageBox.No).exec_() == QtWidgets.QMessageBox.Yes)
                                                )

        self.optimize_panel.evaluate.setToolTip(
            "Determine the optimal gear for your configuration.")
        self.optimize_panel.dharok.setToolTip(
            "What's your average hp? 0 means don't consider dharok.")
        self.optimize_panel.obsidian.setToolTip(
            "The obsidian armour set, along with the necklace.")

        shortcut = QtWidgets.QShortcut(QtGui.QKeySequence("Shift+Return"),
                                       self.optimize_panel)
        shortcut.activated.connect(self.on_evaluate)

        def update_style(style_sheet_text=None):
            if style_sheet_text is None:
                style_sheet_text = self.MainWindow.styleSheet()
            self.MainWindow.setStyleSheet(
                style_sheet_text + '\n' +
                f'QWidget{{font-size: {self.fontsize}px;}}')

        def increase():
            self.fontsize += 1
            update_style()

        def decrease():
            if self.fontsize > 2:
                self.fontsize -= 1
            update_style()

        # Allow font size changes in menu
        self.fontsize = self.MainWindow.font().pointSize()
        self.actionIncrease_Size.setShortcut("Ctrl++")
        self.actionDecrease_Size.setShortcut("Ctrl+-")
        self.actionIncrease_Size.triggered.connect(increase)
        self.actionDecrease_Size.triggered.connect(decrease)

        # Load stylesheet options into menu
        for style_sheet in glob.glob(
                str(config.resource_path(
                    "apps/GUI/shared/stylesheets/*.?ss"))):
            option = os.path.basename(style_sheet).split('.')[
                0]  # Raw file name, no extension
            name = f'style_{option}'
            setattr(self, name, QtWidgets.QAction(self.MainWindow))
            item = getattr(self, name)
            item.setObjectName(name)
            item.setText(option)
            self.menuView.addAction(item)
            item.triggered.connect(lambda _=None, style_sheet=style_sheet:
                                   update_style(open(style_sheet).read()))

        # Ctrl+click and shift+click equipment adds it to ignore/adjust panel respectively
        def modifier(slot):
            mods = QtWidgets.QApplication.keyboardModifiers()
            if mods == QtCore.Qt.ShiftModifier:
                modify_text = self.ignore_adjust_panel.prepend_ignore
            elif mods == QtCore.Qt.ControlModifier:
                modify_text = self.ignore_adjust_panel.prepend_adjust
            else:
                return
            modify_text(getattr(self.optimize_panel, slot).currentText())

        for slot in slots:
            dropdown = getattr(self.optimize_panel, slot)
            dropdown.activated.connect(
                lambda _=None, slot=slot: modifier(slot))