예제 #1
0
 def __init__(self, parent=None):
     super(OverviewWidget, self).__init__(parent)
     # objects, sub-windows
     self.ui = None
     self._btn_reload = None
     self._aswidget = None
     self.world = XNovaWorld_instance()
     # build progress widgets
     self.bp_widgets = dict()  # build progress widgets
     self.bp_widgets_sy = dict()  # shipyard build progress widgets
     self.bp_widgets_res = dict()  # researches build progress widgets
예제 #2
0
파일: test01.py 프로젝트: minlexx/xnovacmd
def printer_thread():
    import time
    from ui.xnova.xn_data import XNPlanet
    from ui.xnova.xn_world import XNovaWorld_instance
    from ui.xnova import xn_logger

    logger = xn_logger.get('test01', debug=True)
    world = XNovaWorld_instance()
    planets = world.get_planets()

    world.script_test01_command = 'running'

    logger.info('Started.')

    # logger.info('Planets:')
    # for planet in planets:
    #    logger.info('{0}'.format(str(planet)))
    # logger.info('End planets.')

    while True:
        time.sleep(1)
        # print('   test01 running...')
        if world.script_test01_command == 'stop':
            break

        if world.script_test01_command == 'pn':
            planet_id = planets[0].planet_id
            post_url = '?set=overview&mode=renameplanet&pl={0}'.format(
                planet_id)
            post_data = dict()
            # post_data['action'] = 'Покинуть колонию'
            post_data['action'] = 'Сменить название'
            post_data['newname'] = 'XX9-WV'
            referer = 'http://uni4.xnova.su/?set=overview&mode=renameplanet'
            world._page_downloader.post(post_url,
                                        post_data=post_data,
                                        referer=referer)
            logger.debug('Rename planet complete to [{0}]'.format(
                post_data['newname']))
            # clear command
            world.script_test01_command = 'running'

    del world.script_test01_command

    logger.info('Stopped.')
예제 #3
0
 def __init__(self, parent=None):
     super(OverviewWidget, self).__init__(parent)
     # objects, sub-windows
     self.ui = None
     self._btn_reload = None
     self._aswidget = None
     self.world = XNovaWorld_instance()
     # build progress widgets
     self.bp_widgets = dict()  # build progress widgets
     self.bp_widgets_sy = dict()  # shipyard build progress widgets
     self.bp_widgets_res = dict()  # researches build progress widgets
예제 #4
0
파일: test01.py 프로젝트: minlexx/xnovacmd
def printer_thread():
    import time
    from ui.xnova.xn_data import XNPlanet
    from ui.xnova.xn_world import XNovaWorld_instance
    from ui.xnova import xn_logger

    logger = xn_logger.get('test01', debug=True)
    world = XNovaWorld_instance()
    planets = world.get_planets()

    world.script_test01_command = 'running'

    logger.info('Started.')

    # logger.info('Planets:')
    # for planet in planets:
    #    logger.info('{0}'.format(str(planet)))
    # logger.info('End planets.')

    while True:
        time.sleep(1)
        # print('   test01 running...')
        if world.script_test01_command == 'stop':
            break

        if world.script_test01_command == 'pn':
            planet_id = planets[0].planet_id
            post_url = '?set=overview&mode=renameplanet&pl={0}'.format(planet_id)
            post_data = dict()
            # post_data['action'] = 'Покинуть колонию'
            post_data['action'] = 'Сменить название'
            post_data['newname'] = 'XX9-WV'
            referer = 'http://uni4.xnova.su/?set=overview&mode=renameplanet'
            world._page_downloader.post(post_url, post_data=post_data, referer=referer)
            logger.debug('Rename planet complete to [{0}]'.format(post_data['newname']))
            # clear command
            world.script_test01_command = 'running'

    del world.script_test01_command

    logger.info('Stopped.')
예제 #5
0
 def __init__(self, parent: QWidget):
     super(GalaxyView, self).__init__(parent)
     self.world = XNovaWorld_instance()
     #
     # setup frame
     self.setFrameShadow(QFrame.Raised)
     self.setFrameShape(QFrame.StyledPanel)
     #
     self._layout = QVBoxLayout()
     self.setLayout(self._layout)
     # temp
     self._layout.addWidget(QLabel('galaxy view', self))
예제 #6
0
 def __init__(self, parent: QWidget):
     super(GalaxyOwnPlanetSelectorWidget, self).__init__(parent)
     self.world = XNovaWorld_instance()
     # setup frame
     self.setFrameShadow(QFrame.Raised)
     self.setFrameShape(QFrame.StyledPanel)
     # layout
     self._layout = QVBoxLayout()
     self._layout.setContentsMargins(6, 6, 6, 6)
     self._layout.setSpacing(0)
     self.setLayout(self._layout)
     # label
     self._lbl = QLabel(self.tr('Select planet:'), self)
     # combo
     self._cb = QComboBox(self)
     self._cb.setEditable(False)
     self._cb.setInsertPolicy(QComboBox.InsertAtBottom)
     self._cb.currentIndexChanged.connect(self.on_cb_currentChanged)
     # finalize layout
     self._layout.addWidget(self._lbl, 0, Qt.AlignHCenter)
     self._layout.addWidget(self._cb, 0, Qt.AlignCenter)
     # ...
     self.fill_planets()
예제 #7
0
 def __init__(self, parent: QWidget):
     super(GalaxyCoordsSelectorWidget, self).__init__(parent)
     # data
     self._coords = [1, 1]  # galaxy, system
     self.world = XNovaWorld_instance()
     #
     # setup frame
     self.setFrameShape(QFrame.NoFrame)
     self.setFrameShadow(QFrame.Raised)
     #
     self._layout = QHBoxLayout()
     self._layout.setContentsMargins(0, 0, 0, 0)
     self._layout.setSpacing(3)
     self.setLayout(self._layout)
     #
     self._planet_selector = GalaxyOwnPlanetSelectorWidget(self)
     self._planet_selector.planetSelected.connect(self.on_planet_selected)
     #
     self._galaxy_selector = GalaxyCoordSingleSelectorWidget(self)
     self._galaxy_selector.setCoordRange(1, 5)
     self._galaxy_selector.setTitle(self.tr('Galaxy'))
     self._galaxy_selector.coordChanged.connect(self.on_gal_changed)
     self._system_selector = GalaxyCoordSingleSelectorWidget(self)
     self._system_selector.setCoordRange(1, 499)
     self._system_selector.setTitle(self.tr('Solar system'))
     self._system_selector.coordChanged.connect(self.on_sys_changed)
     #
     self._btn_navigate = QPushButton(self)
     self._btn_navigate.setText(self.tr('Navigate'))
     self._btn_navigate.clicked.connect(self.on_btn_navigate)
     #
     self._layout.addWidget(self._planet_selector, 0)
     self._layout.addWidget(self._galaxy_selector, 0)
     self._layout.addWidget(self._system_selector, 0)
     self._layout.addWidget(self._btn_navigate, 0)
     self._layout.addStretch(1)
예제 #8
0
class GalaxyOwnPlanetSelectorWidget(QFrame):

    planetSelected = pyqtSignal(int)

    def __init__(self, parent: QWidget):
        super(GalaxyOwnPlanetSelectorWidget, self).__init__(parent)
        self.world = XNovaWorld_instance()
        # setup frame
        self.setFrameShadow(QFrame.Raised)
        self.setFrameShape(QFrame.StyledPanel)
        # layout
        self._layout = QVBoxLayout()
        self._layout.setContentsMargins(6, 6, 6, 6)
        self._layout.setSpacing(0)
        self.setLayout(self._layout)
        # label
        self._lbl = QLabel(self.tr('Select planet:'), self)
        # combo
        self._cb = QComboBox(self)
        self._cb.setEditable(False)
        self._cb.setInsertPolicy(QComboBox.InsertAtBottom)
        self._cb.currentIndexChanged.connect(self.on_cb_currentChanged)
        # finalize layout
        self._layout.addWidget(self._lbl, 0, Qt.AlignHCenter)
        self._layout.addWidget(self._cb, 0, Qt.AlignCenter)
        # ...
        self.fill_planets()

    def fill_planets(self):
        planets = self.world.get_planets()
        for pl in planets:
            st = '{0} {1}'.format(pl.name, pl.coords.coords_str())
            dt = QVariant(pl.planet_id)
            self._cb.addItem(st, dt)

    @pyqtSlot(int)
    def on_cb_currentChanged(self, index: int):
        if index == -1:
            return
        planet_id = int(self._cb.currentData(Qt.UserRole))
        self.planetSelected.emit(planet_id)
예제 #9
0
class GalaxyOwnPlanetSelectorWidget(QFrame):

    planetSelected = pyqtSignal(int)

    def __init__(self, parent: QWidget):
        super(GalaxyOwnPlanetSelectorWidget, self).__init__(parent)
        self.world = XNovaWorld_instance()
        # setup frame
        self.setFrameShadow(QFrame.Raised)
        self.setFrameShape(QFrame.StyledPanel)
        # layout
        self._layout = QVBoxLayout()
        self._layout.setContentsMargins(6, 6, 6, 6)
        self._layout.setSpacing(0)
        self.setLayout(self._layout)
        # label
        self._lbl = QLabel(self.tr('Select planet:'), self)
        # combo
        self._cb = QComboBox(self)
        self._cb.setEditable(False)
        self._cb.setInsertPolicy(QComboBox.InsertAtBottom)
        self._cb.currentIndexChanged.connect(self.on_cb_currentChanged)
        # finalize layout
        self._layout.addWidget(self._lbl, 0, Qt.AlignHCenter)
        self._layout.addWidget(self._cb, 0, Qt.AlignCenter)
        # ...
        self.fill_planets()

    def fill_planets(self):
        planets = self.world.get_planets()
        for pl in planets:
            st = '{0} {1}'.format(pl.name, pl.coords.coords_str())
            dt = QVariant(pl.planet_id)
            self._cb.addItem(st, dt)

    @pyqtSlot(int)
    def on_cb_currentChanged(self, index: int):
        if index == -1:
            return
        planet_id = int(self._cb.currentData(Qt.UserRole))
        self.planetSelected.emit(planet_id)
예제 #10
0
 def __init__(self, parent: QWidget):
     super(GalaxyWidget, self).__init__(parent)
     self.world = XNovaWorld_instance()
     # main layout
     self._layout = QVBoxLayout()
     self._layout.setContentsMargins(0, 0, 0, 0)
     self._layout.setSpacing(2)
     self.setLayout(self._layout)
     # sub-widgets
     self._galaxy_coords = GalaxyCoordsSelectorWidget(self)
     self._galaxy_coords.setGalaxyRange(1, 5)
     self._galaxy_coords.setSystemRange(1, 499)
     self._galaxy_coords.coordsChanged.connect(self.on_coords_cahnged)
     self._galaxyview = GalaxyView(self)
     # scrollarea
     self._sa_galaxy = QScrollArea(self)
     self._sa_galaxy.setMinimumWidth(400)
     self._sa_galaxy.setMinimumHeight(300)
     self._sa_galaxy.setWidget(self._galaxyview)
     #
     self._layout.addWidget(self._galaxy_coords)
     self._layout.addWidget(self._sa_galaxy)
예제 #11
0
 def __init__(self, parent: QWidget):
     super(GalaxyOwnPlanetSelectorWidget, self).__init__(parent)
     self.world = XNovaWorld_instance()
     # setup frame
     self.setFrameShadow(QFrame.Raised)
     self.setFrameShape(QFrame.StyledPanel)
     # layout
     self._layout = QVBoxLayout()
     self._layout.setContentsMargins(6, 6, 6, 6)
     self._layout.setSpacing(0)
     self.setLayout(self._layout)
     # label
     self._lbl = QLabel(self.tr('Select planet:'), self)
     # combo
     self._cb = QComboBox(self)
     self._cb.setEditable(False)
     self._cb.setInsertPolicy(QComboBox.InsertAtBottom)
     self._cb.currentIndexChanged.connect(self.on_cb_currentChanged)
     # finalize layout
     self._layout.addWidget(self._lbl, 0, Qt.AlignHCenter)
     self._layout.addWidget(self._cb, 0, Qt.AlignCenter)
     # ...
     self.fill_planets()
예제 #12
0
 def __init__(self, parent: QWidget):
     super(GalaxyCoordsSelectorWidget, self).__init__(parent)
     # data
     self._coords = [1, 1]  # galaxy, system
     self.world = XNovaWorld_instance()
     #
     # setup frame
     self.setFrameShape(QFrame.NoFrame)
     self.setFrameShadow(QFrame.Raised)
     #
     self._layout = QHBoxLayout()
     self._layout.setContentsMargins(0, 0, 0, 0)
     self._layout.setSpacing(3)
     self.setLayout(self._layout)
     #
     self._planet_selector = GalaxyOwnPlanetSelectorWidget(self)
     self._planet_selector.planetSelected.connect(self.on_planet_selected)
     #
     self._galaxy_selector = GalaxyCoordSingleSelectorWidget(self)
     self._galaxy_selector.setCoordRange(1, 5)
     self._galaxy_selector.setTitle(self.tr('Galaxy'))
     self._galaxy_selector.coordChanged.connect(self.on_gal_changed)
     self._system_selector = GalaxyCoordSingleSelectorWidget(self)
     self._system_selector.setCoordRange(1, 499)
     self._system_selector.setTitle(self.tr('Solar system'))
     self._system_selector.coordChanged.connect(self.on_sys_changed)
     #
     self._btn_navigate = QPushButton(self)
     self._btn_navigate.setText(self.tr('Navigate'))
     self._btn_navigate.clicked.connect(self.on_btn_navigate)
     #
     self._layout.addWidget(self._planet_selector, 0)
     self._layout.addWidget(self._galaxy_selector, 0)
     self._layout.addWidget(self._system_selector, 0)
     self._layout.addWidget(self._btn_navigate, 0)
     self._layout.addStretch(1)
예제 #13
0
class PlanetWidget(QFrame):
    """
    Provides view of galaxy/solarsystem contents as table widget
    """

    requestOpenGalaxy = pyqtSignal(XNCoords)

    def __init__(self, parent: QWidget):
        super(PlanetWidget, self).__init__(parent)
        #
        self.world = XNovaWorld_instance()
        self._planet = XNPlanet()
        # setup frame
        self.setFrameShape(QFrame.StyledPanel)
        self.setFrameShadow(QFrame.Raised)
        # layout
        self._layout = QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(3)
        self.setLayout(self._layout)
        # basic info panel
        self._bipanel = Planet_BasicInfoPanel(self)
        self._bipanel.requestOpenGalaxy.connect(self.on_request_open_galaxy)
        self._bipanel.requestRefreshPlanet.connect(
            self.on_request_refresh_planet)
        self._bipanel.requestRenamePlanet.connect(
            self.on_request_rename_planet)
        # build progress widgets
        self._bpw_buildings = BuildProgressWidget(self)
        self._bpw_buildings.hide()
        self._bpw_buildings.hide_planet_name()
        self._bpw_buildings.layout().setContentsMargins(5, 2, 5, 2)
        self._bpw_shipyard = BuildProgressWidget(self)
        self._bpw_shipyard.hide()
        self._bpw_shipyard.hide_planet_name()
        self._bpw_shipyard.layout().setContentsMargins(5, 2, 5, 2)
        self._bpw_research = BuildProgressWidget(self)
        self._bpw_research.hide()
        self._bpw_research.hide_planet_name()
        self._bpw_research.layout().setContentsMargins(5, 2, 5, 2)
        # buildings
        self._cf_buildings = CollapsibleFrame(self)
        self._cf_buildings.setTitle(self.tr('Buildings'))
        self._sa_buildings = QScrollArea(self._cf_buildings)
        self._bip_buildings = Planet_BuildItemsPanel(self._sa_buildings)
        self._bip_buildings.set_type(Planet_BuildItemsPanel.TYPE_BUILDINGS)
        self._bip_buildings.show()
        self._sa_buildings.setWidget(self._bip_buildings)
        self._cf_buildings.addWidget(self._sa_buildings)
        # shipyard
        self._cf_shipyard = CollapsibleFrame(self)
        self._cf_shipyard.setTitle(self.tr('Shipyard'))
        self._sa_shipyard = QScrollArea(self._cf_shipyard)
        self._bip_shipyard = Planet_BuildItemsPanel(self._cf_shipyard)
        self._bip_shipyard.set_type(Planet_BuildItemsPanel.TYPE_SHIPYARD)
        self._sa_shipyard.setWidget(self._bip_shipyard)
        self._cf_shipyard.addWidget(self._sa_shipyard)
        # research
        self._cf_research = CollapsibleFrame(self)
        self._cf_research.setTitle(self.tr('Research'))
        self._sa_research = QScrollArea(self._cf_research)
        self._bip_research = Planet_BuildItemsPanel(self._cf_research)
        self._bip_research.set_type(Planet_BuildItemsPanel.TYPE_RESEARCHES)
        self._sa_research.setWidget(self._bip_research)
        self._cf_research.addWidget(self._sa_research)
        # layout finalize
        self._layout.addWidget(self._bipanel)
        self._layout.addWidget(self._bpw_buildings)
        self._layout.addWidget(self._bpw_shipyard)
        self._layout.addWidget(self._bpw_research)
        self._layout.addWidget(self._cf_buildings)
        self._layout.addWidget(self._cf_shipyard)
        self._layout.addWidget(self._cf_research)
        # expand buildings frame by default
        self._cf_buildings.expand()
        #
        # connect signals
        self._cf_buildings.expanded.connect(self.on_frame_buildings_expanded)
        self._cf_buildings.collapsed.connect(self.on_frame_buildings_collapsed)
        self._cf_shipyard.expanded.connect(self.on_frame_shipyard_expanded)
        self._cf_shipyard.collapsed.connect(self.on_frame_shipyard_collapsed)
        self._cf_research.expanded.connect(self.on_frame_research_expanded)
        self._cf_research.collapsed.connect(self.on_frame_research_collapsed)
        #
        self._bpw_buildings.requestCancelBuild.connect(
            self.on_request_cancel_build)
        self._bpw_research.requestCancelBuild.connect(
            self.on_request_cancel_build)
        #
        self._bip_buildings.requestBuildItem.connect(
            self.on_request_build_item)
        self._bip_buildings.requestDowngradeItem.connect(
            self.on_request_downgrade_item)
        self._bip_shipyard.requestBuildItem.connect(self.on_request_build_item)
        self._bip_research.requestBuildItem.connect(self.on_request_build_item)
        #
        # create timer
        self._timer = QTimer(self)
        self._timer.timeout.connect(self.on_timer)

    def get_tab_type(self) -> str:
        return 'planet'

    def setPlanet(self, planet: XNPlanet):
        self._planet = planet
        # setup basic info panel
        self._bipanel.setup_from_planet(self._planet)
        # setup build progress widgets
        self._bpw_buildings.update_from_planet(planet, typ='')
        self._bpw_shipyard.update_from_planet(
            planet, typ=BuildProgressWidget.BPW_TYPE_SHIPYARD)
        self._bpw_research.update_from_planet(
            planet, typ=BuildProgressWidget.BPW_TYPE_RESEARCH)
        # setup build items panels (in collapsible frames)
        self._bip_buildings.set_planet(planet)
        self._bip_shipyard.set_planet(planet)
        self._bip_research.set_planet(planet)
        #
        # start/restart timer
        self._timer.stop()
        self._timer.setInterval(1000)
        self._timer.setSingleShot(False)
        self._timer.start()

    def planet(self) -> XNPlanet:
        return self._planet

    @pyqtSlot()
    def on_timer(self):
        # update basic info panel - refresh resources
        self._bipanel.update_resources()
        # update build progress widgets - tick builds
        self._bpw_buildings.update_from_planet(self._planet)
        self._bpw_shipyard.update_from_planet(
            self._planet, BuildProgressWidget.BPW_TYPE_SHIPYARD)
        self._bpw_research.update_from_planet(
            self._planet, BuildProgressWidget.BPW_TYPE_RESEARCH)

    @pyqtSlot(XNCoords)
    def on_request_open_galaxy(self, coords: XNCoords):
        self.requestOpenGalaxy.emit(coords)

    @pyqtSlot()
    def on_request_refresh_planet(self):
        self.world.signal(self.world.SIGNAL_RELOAD_PLANET,
                          planet_id=self._planet.planet_id)

    @pyqtSlot(int, str)
    def on_request_rename_planet(self, planet_id: int, planet_name: str):
        self.world.signal(self.world.SIGNAL_RENAME_PLANET,
                          planet_id=planet_id,
                          new_name=planet_name)

    @pyqtSlot(XNPlanetBuildingItem)
    def on_request_cancel_build(self, bitem: XNPlanetBuildingItem):
        if bitem is None:
            return
        if (bitem.remove_link is None) or (bitem.remove_link == ''):
            return
        self.world.signal(XNovaWorld.SIGNAL_BUILD_CANCEL,
                          planet_id=self._planet.planet_id,
                          bitem=bitem)

    @pyqtSlot(XNPlanetBuildingItem, int)
    def on_request_build_item(self, bitem: XNPlanetBuildingItem,
                              quantity: int):
        if bitem is None:
            return
        self.world.signal(XNovaWorld.SIGNAL_BUILD_ITEM,
                          planet_id=self._planet.planet_id,
                          bitem=bitem,
                          quantity=quantity)

    @pyqtSlot(XNPlanetBuildingItem)
    def on_request_downgrade_item(self, bitem: XNPlanetBuildingItem):
        if bitem is None:
            return
        if not bitem.is_building_item:
            logger.warn('Cannot dismantle item that is '
                        'not building: {0}'.format(bitem))
            return
        downgrade_price = '{0} {3},  {1} {4},  {2} {5}'.format(
            self.tr('Metal'), self.tr('Crystal'), self.tr('Deit'),
            int(bitem.cost_met // 2), int(bitem.cost_cry // 2),
            int(bitem.cost_deit // 2))
        btn = QMessageBox.question(
            self, self.tr('Downgrade building'),
            self.tr('Are you sure you want to downgrade this building?') +
            '\n' + '{0} {1} {2}\n{3}: {4}'.format(
                bitem.name, self.tr('lv.'), bitem.level, self.tr('Cost'),
                downgrade_price), QMessageBox.Yes | QMessageBox.No)
        if btn == QMessageBox.Yes:
            self.world.signal(XNovaWorld.SIGNAL_BUILD_DISMANTLE,
                              planet_id=self._planet.planet_id,
                              bitem=bitem)

    @pyqtSlot()
    def on_frame_buildings_collapsed(self):
        pass

    @pyqtSlot()
    def on_frame_buildings_expanded(self):
        # collapse other frames
        self._cf_shipyard.collapse()
        self._cf_research.collapse()

    @pyqtSlot()
    def on_frame_shipyard_collapsed(self):
        pass

    @pyqtSlot()
    def on_frame_shipyard_expanded(self):
        # collapse other frames
        self._cf_buildings.collapse()
        self._cf_research.collapse()

    @pyqtSlot()
    def on_frame_research_collapsed(self):
        pass

    @pyqtSlot()
    def on_frame_research_expanded(self):
        # collapse other frames
        self._cf_buildings.collapse()
        self._cf_shipyard.collapse()
예제 #14
0
class GalaxyCoordsSelectorWidget(QFrame):
    """
    Groups together two controls to select galaxy and system
    coordinates with a button to navigate there.
    TODO: it can also show maybe bookmarks? :D
    """

    coordsChanged = pyqtSignal(int, int)

    def __init__(self, parent: QWidget):
        super(GalaxyCoordsSelectorWidget, self).__init__(parent)
        # data
        self._coords = [1, 1]  # galaxy, system
        self.world = XNovaWorld_instance()
        #
        # setup frame
        self.setFrameShape(QFrame.NoFrame)
        self.setFrameShadow(QFrame.Raised)
        #
        self._layout = QHBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(3)
        self.setLayout(self._layout)
        #
        self._planet_selector = GalaxyOwnPlanetSelectorWidget(self)
        self._planet_selector.planetSelected.connect(self.on_planet_selected)
        #
        self._galaxy_selector = GalaxyCoordSingleSelectorWidget(self)
        self._galaxy_selector.setCoordRange(1, 5)
        self._galaxy_selector.setTitle(self.tr('Galaxy'))
        self._galaxy_selector.coordChanged.connect(self.on_gal_changed)
        self._system_selector = GalaxyCoordSingleSelectorWidget(self)
        self._system_selector.setCoordRange(1, 499)
        self._system_selector.setTitle(self.tr('Solar system'))
        self._system_selector.coordChanged.connect(self.on_sys_changed)
        #
        self._btn_navigate = QPushButton(self)
        self._btn_navigate.setText(self.tr('Navigate'))
        self._btn_navigate.clicked.connect(self.on_btn_navigate)
        #
        self._layout.addWidget(self._planet_selector, 0)
        self._layout.addWidget(self._galaxy_selector, 0)
        self._layout.addWidget(self._system_selector, 0)
        self._layout.addWidget(self._btn_navigate, 0)
        self._layout.addStretch(1)

    def coordGalaxy(self) -> int:
        return self._coords[0]

    def coordSystem(self) -> int:
        return self._coords[1]

    def coords(self) -> list:
        return self._coords

    def setCoords(self, galaxy: int, system: int, do_emit: bool = True):
        prev_coords = self._coords
        self._galaxy_selector.setCoord(galaxy)  # does all range-checking
        self._system_selector.setCoord(system)  # does all range-checking
        # get actual fixed coords
        self._coords[0] = self._galaxy_selector.coord()
        self._coords[1] = self._system_selector.coord()
        # compare and emit
        if do_emit:
            if (prev_coords[0] != self._coords[0]) or (prev_coords[1] != self._coords[1]):
                self.coordsChanged.emit(self._coords[0], self._coords[1])

    def setGalaxyRange(self, gal_min: int, gal_max: int):
        self._galaxy_selector.setCoordRange(gal_min, gal_max)

    def setSystemRange(self, sys_min: int, sys_max: int):
        self._system_selector.setCoordRange(sys_min, sys_max)

    @pyqtSlot(int)
    def on_gal_changed(self, c: int):
        self._coords[0] = c
        self.coordsChanged.emit(self._coords[0], self._coords[1])

    @pyqtSlot(int)
    def on_sys_changed(self, c: int):
        self._coords[1] = c
        self.coordsChanged.emit(self._coords[0], self._coords[1])

    @pyqtSlot()
    def on_btn_navigate(self):
        # get actual coords
        self._coords[0] = self._galaxy_selector.coord()
        self._coords[1] = self._system_selector.coord()
        # just force refresh like coords changed
        self.coordsChanged.emit(self._coords[0], self._coords[1])

    @pyqtSlot(int)
    def on_planet_selected(self, planet_id: int):
        planet = self.world.get_planet(planet_id)
        if planet is None:
            return
        logger.debug('    navigating to: {0}'.format(planet.coords.coords_str()))
        self.setCoords(planet.coords.galaxy, planet.coords.system)
예제 #15
0
파일: stopper.py 프로젝트: minlexx/xnovacmd
from ui.xnova.xn_world import XNovaWorld_instance
from ui.xnova import xn_logger


logger = xn_logger.get("test01_stopper", debug=True)
world = XNovaWorld_instance()

try:
    existing = world.script_command
    # if this fails, no such member exists, an exception will be raised
    # else, continue
    # world.script_test01_command = 'stop'
    world.script_command = "stop"
    # world.script_test01_command = 'pn'
    logger.info('sent "stop" command to scripts.')
except AttributeError as ea:
    logger.info("probably script is not running.")
    pass
예제 #16
0
from ui.xnova.xn_world import XNovaWorld_instance
from ui.xnova.xn_data import XNPlanet, XNPlanetBuildingItem
from ui.xnova import xn_logger

logger = xn_logger.get('test01_stopper', debug=True)
world = XNovaWorld_instance()


def energy_need_for_gid(gid: int, level: int) -> int:
    if (gid == 1) or (gid == 2) or (gid == 12):
        e = (10 * level) * (1.1**level)
        return round(e)
    if gid == 3:
        e = (30 * level) * (1.1**level)
        return round(e)
    return -1


try:
    planets = world.get_planets()
    if len(planets) > 0:
        planet = planets[0]
        for bitem in planet.buildings_items:
            e = energy_need_for_gid(bitem.gid, bitem.level)
            if e != -1:
                print('{0} lv {1} need {2} energy'.format(
                    bitem.name, bitem.level, e))
except Exception as ex:
    logger.exception('Exception happened')
예제 #17
0
class PlanetWidget(QFrame):
    """
    Provides view of galaxy/solarsystem contents as table widget
    """

    requestOpenGalaxy = pyqtSignal(XNCoords)

    def __init__(self, parent: QWidget):
        super(PlanetWidget, self).__init__(parent)
        #
        self.world = XNovaWorld_instance()
        self._planet = XNPlanet()
        # setup frame
        self.setFrameShape(QFrame.StyledPanel)
        self.setFrameShadow(QFrame.Raised)
        # layout
        self._layout = QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(3)
        self.setLayout(self._layout)
        # basic info panel
        self._bipanel = Planet_BasicInfoPanel(self)
        self._bipanel.requestOpenGalaxy.connect(self.on_request_open_galaxy)
        self._bipanel.requestRefreshPlanet.connect(
                self.on_request_refresh_planet)
        self._bipanel.requestRenamePlanet.connect(self.on_request_rename_planet)
        # build progress widgets
        self._bpw_buildings = BuildProgressWidget(self)
        self._bpw_buildings.hide()
        self._bpw_buildings.hide_planet_name()
        self._bpw_buildings.layout().setContentsMargins(5, 2, 5, 2)
        self._bpw_shipyard = BuildProgressWidget(self)
        self._bpw_shipyard.hide()
        self._bpw_shipyard.hide_planet_name()
        self._bpw_shipyard.layout().setContentsMargins(5, 2, 5, 2)
        self._bpw_research = BuildProgressWidget(self)
        self._bpw_research.hide()
        self._bpw_research.hide_planet_name()
        self._bpw_research.layout().setContentsMargins(5, 2, 5, 2)
        # buildings
        self._cf_buildings = CollapsibleFrame(self)
        self._cf_buildings.setTitle(self.tr('Buildings'))
        self._sa_buildings = QScrollArea(self._cf_buildings)
        self._bip_buildings = Planet_BuildItemsPanel(self._sa_buildings)
        self._bip_buildings.set_type(Planet_BuildItemsPanel.TYPE_BUILDINGS)
        self._bip_buildings.show()
        self._sa_buildings.setWidget(self._bip_buildings)
        self._cf_buildings.addWidget(self._sa_buildings)
        # shipyard
        self._cf_shipyard = CollapsibleFrame(self)
        self._cf_shipyard.setTitle(self.tr('Shipyard'))
        self._sa_shipyard = QScrollArea(self._cf_shipyard)
        self._bip_shipyard = Planet_BuildItemsPanel(self._cf_shipyard)
        self._bip_shipyard.set_type(Planet_BuildItemsPanel.TYPE_SHIPYARD)
        self._sa_shipyard.setWidget(self._bip_shipyard)
        self._cf_shipyard.addWidget(self._sa_shipyard)
        # research
        self._cf_research = CollapsibleFrame(self)
        self._cf_research.setTitle(self.tr('Research'))
        self._sa_research = QScrollArea(self._cf_research)
        self._bip_research = Planet_BuildItemsPanel(self._cf_research)
        self._bip_research.set_type(Planet_BuildItemsPanel.TYPE_RESEARCHES)
        self._sa_research.setWidget(self._bip_research)
        self._cf_research.addWidget(self._sa_research)
        # layout finalize
        self._layout.addWidget(self._bipanel)
        self._layout.addWidget(self._bpw_buildings)
        self._layout.addWidget(self._bpw_shipyard)
        self._layout.addWidget(self._bpw_research)
        self._layout.addWidget(self._cf_buildings)
        self._layout.addWidget(self._cf_shipyard)
        self._layout.addWidget(self._cf_research)
        # expand buildings frame by default
        self._cf_buildings.expand()
        #
        # connect signals
        self._cf_buildings.expanded.connect(self.on_frame_buildings_expanded)
        self._cf_buildings.collapsed.connect(self.on_frame_buildings_collapsed)
        self._cf_shipyard.expanded.connect(self.on_frame_shipyard_expanded)
        self._cf_shipyard.collapsed.connect(self.on_frame_shipyard_collapsed)
        self._cf_research.expanded.connect(self.on_frame_research_expanded)
        self._cf_research.collapsed.connect(self.on_frame_research_collapsed)
        #
        self._bpw_buildings.requestCancelBuild.connect(
                self.on_request_cancel_build)
        self._bpw_research.requestCancelBuild.connect(
                self.on_request_cancel_build)
        #
        self._bip_buildings.requestBuildItem.connect(self.on_request_build_item)
        self._bip_buildings.requestDowngradeItem.connect(
                self.on_request_downgrade_item)
        self._bip_shipyard.requestBuildItem.connect(self.on_request_build_item)
        self._bip_research.requestBuildItem.connect(self.on_request_build_item)
        #
        # create timer
        self._timer = QTimer(self)
        self._timer.timeout.connect(self.on_timer)

    def get_tab_type(self) -> str:
        return 'planet'

    def setPlanet(self, planet: XNPlanet):
        self._planet = planet
        # setup basic info panel
        self._bipanel.setup_from_planet(self._planet)
        # setup build progress widgets
        self._bpw_buildings.update_from_planet(planet, typ='')
        self._bpw_shipyard.update_from_planet(planet,
                typ=BuildProgressWidget.BPW_TYPE_SHIPYARD)
        self._bpw_research.update_from_planet(planet,
                typ=BuildProgressWidget.BPW_TYPE_RESEARCH)
        # setup build items panels (in collapsible frames)
        self._bip_buildings.set_planet(planet)
        self._bip_shipyard.set_planet(planet)
        self._bip_research.set_planet(planet)
        #
        # start/restart timer
        self._timer.stop()
        self._timer.setInterval(1000)
        self._timer.setSingleShot(False)
        self._timer.start()

    def planet(self) -> XNPlanet:
        return self._planet

    @pyqtSlot()
    def on_timer(self):
        # update basic info panel - refresh resources
        self._bipanel.update_resources()
        # update build progress widgets - tick builds
        self._bpw_buildings.update_from_planet(self._planet)
        self._bpw_shipyard.update_from_planet(self._planet,
                BuildProgressWidget.BPW_TYPE_SHIPYARD)
        self._bpw_research.update_from_planet(self._planet,
                BuildProgressWidget.BPW_TYPE_RESEARCH)

    @pyqtSlot(XNCoords)
    def on_request_open_galaxy(self, coords: XNCoords):
        self.requestOpenGalaxy.emit(coords)

    @pyqtSlot()
    def on_request_refresh_planet(self):
        self.world.signal(self.world.SIGNAL_RELOAD_PLANET,
                planet_id=self._planet.planet_id)

    @pyqtSlot(int, str)
    def on_request_rename_planet(self, planet_id: int, planet_name: str):
        self.world.signal(self.world.SIGNAL_RENAME_PLANET,
                planet_id=planet_id, new_name=planet_name)

    @pyqtSlot(XNPlanetBuildingItem)
    def on_request_cancel_build(self, bitem: XNPlanetBuildingItem):
        if bitem is None:
            return
        if (bitem.remove_link is None) or (bitem.remove_link == ''):
            return
        self.world.signal(XNovaWorld.SIGNAL_BUILD_CANCEL,
                          planet_id=self._planet.planet_id,
                          bitem=bitem)

    @pyqtSlot(XNPlanetBuildingItem, int)
    def on_request_build_item(self, bitem: XNPlanetBuildingItem,
                              quantity: int):
        if bitem is None:
            return
        self.world.signal(XNovaWorld.SIGNAL_BUILD_ITEM,
                          planet_id=self._planet.planet_id,
                          bitem=bitem,
                          quantity=quantity)

    @pyqtSlot(XNPlanetBuildingItem)
    def on_request_downgrade_item(self, bitem: XNPlanetBuildingItem):
        if bitem is None:
            return
        if not bitem.is_building_item:
            logger.warn('Cannot dismantle item that is '
                    'not building: {0}'.format(bitem))
            return
        downgrade_price = '{0} {3},  {1} {4},  {2} {5}'.format(
                self.tr('Metal'), self.tr('Crystal'), self.tr('Deit'),
                int(bitem.cost_met//2),
                int(bitem.cost_cry // 2),
                int(bitem.cost_deit // 2))
        btn = QMessageBox.question(self,
                self.tr('Downgrade building'),
                self.tr('Are you sure you want to downgrade this building?')
                        + '\n' + '{0} {1} {2}\n{3}: {4}'.format(
                        bitem.name,
                        self.tr('lv.'),
                        bitem.level,
                        self.tr('Cost'),
                        downgrade_price),
                QMessageBox.Yes | QMessageBox.No)
        if btn == QMessageBox.Yes:
            self.world.signal(XNovaWorld.SIGNAL_BUILD_DISMANTLE,
                              planet_id=self._planet.planet_id,
                              bitem=bitem)

    @pyqtSlot()
    def on_frame_buildings_collapsed(self):
        pass

    @pyqtSlot()
    def on_frame_buildings_expanded(self):
        # collapse other frames
        self._cf_shipyard.collapse()
        self._cf_research.collapse()

    @pyqtSlot()
    def on_frame_shipyard_collapsed(self):
        pass

    @pyqtSlot()
    def on_frame_shipyard_expanded(self):
        # collapse other frames
        self._cf_buildings.collapse()
        self._cf_research.collapse()

    @pyqtSlot()
    def on_frame_research_collapsed(self):
        pass

    @pyqtSlot()
    def on_frame_research_expanded(self):
        # collapse other frames
        self._cf_buildings.collapse()
        self._cf_shipyard.collapse()
예제 #18
0
class GalaxyCoordsSelectorWidget(QFrame):
    """
    Groups together two controls to select galaxy and system
    coordinates with a button to navigate there.
    TODO: it can also show maybe bookmarks? :D
    """

    coordsChanged = pyqtSignal(int, int)

    def __init__(self, parent: QWidget):
        super(GalaxyCoordsSelectorWidget, self).__init__(parent)
        # data
        self._coords = [1, 1]  # galaxy, system
        self.world = XNovaWorld_instance()
        #
        # setup frame
        self.setFrameShape(QFrame.NoFrame)
        self.setFrameShadow(QFrame.Raised)
        #
        self._layout = QHBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(3)
        self.setLayout(self._layout)
        #
        self._planet_selector = GalaxyOwnPlanetSelectorWidget(self)
        self._planet_selector.planetSelected.connect(self.on_planet_selected)
        #
        self._galaxy_selector = GalaxyCoordSingleSelectorWidget(self)
        self._galaxy_selector.setCoordRange(1, 5)
        self._galaxy_selector.setTitle(self.tr('Galaxy'))
        self._galaxy_selector.coordChanged.connect(self.on_gal_changed)
        self._system_selector = GalaxyCoordSingleSelectorWidget(self)
        self._system_selector.setCoordRange(1, 499)
        self._system_selector.setTitle(self.tr('Solar system'))
        self._system_selector.coordChanged.connect(self.on_sys_changed)
        #
        self._btn_navigate = QPushButton(self)
        self._btn_navigate.setText(self.tr('Navigate'))
        self._btn_navigate.clicked.connect(self.on_btn_navigate)
        #
        self._layout.addWidget(self._planet_selector, 0)
        self._layout.addWidget(self._galaxy_selector, 0)
        self._layout.addWidget(self._system_selector, 0)
        self._layout.addWidget(self._btn_navigate, 0)
        self._layout.addStretch(1)

    def coordGalaxy(self) -> int:
        return self._coords[0]

    def coordSystem(self) -> int:
        return self._coords[1]

    def coords(self) -> list:
        return self._coords

    def setCoords(self, galaxy: int, system: int, do_emit: bool = True):
        prev_coords = self._coords
        self._galaxy_selector.setCoord(galaxy)  # does all range-checking
        self._system_selector.setCoord(system)  # does all range-checking
        # get actual fixed coords
        self._coords[0] = self._galaxy_selector.coord()
        self._coords[1] = self._system_selector.coord()
        # compare and emit
        if do_emit:
            if (prev_coords[0] != self._coords[0]) or (prev_coords[1] !=
                                                       self._coords[1]):
                self.coordsChanged.emit(self._coords[0], self._coords[1])

    def setGalaxyRange(self, gal_min: int, gal_max: int):
        self._galaxy_selector.setCoordRange(gal_min, gal_max)

    def setSystemRange(self, sys_min: int, sys_max: int):
        self._system_selector.setCoordRange(sys_min, sys_max)

    @pyqtSlot(int)
    def on_gal_changed(self, c: int):
        self._coords[0] = c
        self.coordsChanged.emit(self._coords[0], self._coords[1])

    @pyqtSlot(int)
    def on_sys_changed(self, c: int):
        self._coords[1] = c
        self.coordsChanged.emit(self._coords[0], self._coords[1])

    @pyqtSlot()
    def on_btn_navigate(self):
        # get actual coords
        self._coords[0] = self._galaxy_selector.coord()
        self._coords[1] = self._system_selector.coord()
        # just force refresh like coords changed
        self.coordsChanged.emit(self._coords[0], self._coords[1])

    @pyqtSlot(int)
    def on_planet_selected(self, planet_id: int):
        planet = self.world.get_planet(planet_id)
        if planet is None:
            return
        logger.debug('    navigating to: {0}'.format(
            planet.coords.coords_str()))
        self.setCoords(planet.coords.galaxy, planet.coords.system)
예제 #19
0
 def __init__(self, parent: QWidget):
     super(PlanetWidget, self).__init__(parent)
     #
     self.world = XNovaWorld_instance()
     self._planet = XNPlanet()
     # setup frame
     self.setFrameShape(QFrame.StyledPanel)
     self.setFrameShadow(QFrame.Raised)
     # layout
     self._layout = QVBoxLayout()
     self._layout.setContentsMargins(0, 0, 0, 0)
     self._layout.setSpacing(3)
     self.setLayout(self._layout)
     # basic info panel
     self._bipanel = Planet_BasicInfoPanel(self)
     self._bipanel.requestOpenGalaxy.connect(self.on_request_open_galaxy)
     self._bipanel.requestRefreshPlanet.connect(
         self.on_request_refresh_planet)
     self._bipanel.requestRenamePlanet.connect(
         self.on_request_rename_planet)
     # build progress widgets
     self._bpw_buildings = BuildProgressWidget(self)
     self._bpw_buildings.hide()
     self._bpw_buildings.hide_planet_name()
     self._bpw_buildings.layout().setContentsMargins(5, 2, 5, 2)
     self._bpw_shipyard = BuildProgressWidget(self)
     self._bpw_shipyard.hide()
     self._bpw_shipyard.hide_planet_name()
     self._bpw_shipyard.layout().setContentsMargins(5, 2, 5, 2)
     self._bpw_research = BuildProgressWidget(self)
     self._bpw_research.hide()
     self._bpw_research.hide_planet_name()
     self._bpw_research.layout().setContentsMargins(5, 2, 5, 2)
     # buildings
     self._cf_buildings = CollapsibleFrame(self)
     self._cf_buildings.setTitle(self.tr('Buildings'))
     self._sa_buildings = QScrollArea(self._cf_buildings)
     self._bip_buildings = Planet_BuildItemsPanel(self._sa_buildings)
     self._bip_buildings.set_type(Planet_BuildItemsPanel.TYPE_BUILDINGS)
     self._bip_buildings.show()
     self._sa_buildings.setWidget(self._bip_buildings)
     self._cf_buildings.addWidget(self._sa_buildings)
     # shipyard
     self._cf_shipyard = CollapsibleFrame(self)
     self._cf_shipyard.setTitle(self.tr('Shipyard'))
     self._sa_shipyard = QScrollArea(self._cf_shipyard)
     self._bip_shipyard = Planet_BuildItemsPanel(self._cf_shipyard)
     self._bip_shipyard.set_type(Planet_BuildItemsPanel.TYPE_SHIPYARD)
     self._sa_shipyard.setWidget(self._bip_shipyard)
     self._cf_shipyard.addWidget(self._sa_shipyard)
     # research
     self._cf_research = CollapsibleFrame(self)
     self._cf_research.setTitle(self.tr('Research'))
     self._sa_research = QScrollArea(self._cf_research)
     self._bip_research = Planet_BuildItemsPanel(self._cf_research)
     self._bip_research.set_type(Planet_BuildItemsPanel.TYPE_RESEARCHES)
     self._sa_research.setWidget(self._bip_research)
     self._cf_research.addWidget(self._sa_research)
     # layout finalize
     self._layout.addWidget(self._bipanel)
     self._layout.addWidget(self._bpw_buildings)
     self._layout.addWidget(self._bpw_shipyard)
     self._layout.addWidget(self._bpw_research)
     self._layout.addWidget(self._cf_buildings)
     self._layout.addWidget(self._cf_shipyard)
     self._layout.addWidget(self._cf_research)
     # expand buildings frame by default
     self._cf_buildings.expand()
     #
     # connect signals
     self._cf_buildings.expanded.connect(self.on_frame_buildings_expanded)
     self._cf_buildings.collapsed.connect(self.on_frame_buildings_collapsed)
     self._cf_shipyard.expanded.connect(self.on_frame_shipyard_expanded)
     self._cf_shipyard.collapsed.connect(self.on_frame_shipyard_collapsed)
     self._cf_research.expanded.connect(self.on_frame_research_expanded)
     self._cf_research.collapsed.connect(self.on_frame_research_collapsed)
     #
     self._bpw_buildings.requestCancelBuild.connect(
         self.on_request_cancel_build)
     self._bpw_research.requestCancelBuild.connect(
         self.on_request_cancel_build)
     #
     self._bip_buildings.requestBuildItem.connect(
         self.on_request_build_item)
     self._bip_buildings.requestDowngradeItem.connect(
         self.on_request_downgrade_item)
     self._bip_shipyard.requestBuildItem.connect(self.on_request_build_item)
     self._bip_research.requestBuildItem.connect(self.on_request_build_item)
     #
     # create timer
     self._timer = QTimer(self)
     self._timer.timeout.connect(self.on_timer)
예제 #20
0
class OverviewWidget(QWidget):
    def __init__(self, parent=None):
        super(OverviewWidget, self).__init__(parent)
        # objects, sub-windows
        self.ui = None
        self._btn_reload = None
        self._aswidget = None
        self.world = XNovaWorld_instance()
        # build progress widgets
        self.bp_widgets = dict()  # build progress widgets
        self.bp_widgets_sy = dict()  # shipyard build progress widgets
        self.bp_widgets_res = dict()  # researches build progress widgets

    def load_ui(self):
        # layout
        self._layout = QVBoxLayout()
        self._layout_topbuttons = QHBoxLayout()
        self.setLayout(self._layout)
        self._layout.addLayout(self._layout_topbuttons)
        # sub-windows
        # reload button
        self._btn_reload = QPushButton(self.tr('Refresh overview'), self)
        self._btn_reload.setIcon(QIcon(':i/reload.png'))
        self._btn_reload.clicked.connect(self.on_btn_refresh_overview)
        self._layout_topbuttons.addWidget(self._btn_reload)
        self._layout_topbuttons.addStretch()
        # group box to hold builds info
        self._gb_builds = CollapsibleFrame(self)
        self._gb_builds.setTitle(self.tr('Building Jobs'))
        self._layout.addWidget(self._gb_builds)
        # groupbox to hold shipyard builds info
        self._gb_shipyard = CollapsibleFrame(self)
        self._gb_shipyard.setTitle(self.tr('Shipyard Jobs'))
        self._layout.addWidget(self._gb_shipyard)
        # groupbox to hold researches in progress info
        self._gb_research = CollapsibleFrame(self)
        self._gb_research.setTitle(self.tr('Researches'))
        self._layout.addWidget(self._gb_research)
        # groupbox to hold account stats widget
        self._gb_accstats = CollapsibleFrame(self)
        self._gb_accstats.setTitle(self.tr('Statistics'))
        self._layout.addWidget(self._gb_accstats)
        # account stats widget
        self._aswidget = Overview_AccStatsWidget(self)
        self._aswidget.load_ui()
        self._aswidget.show()
        self._gb_accstats.addWidget(self._aswidget)
        self._gb_accstats.expand()  # staticstics expanded by default
        # add final spacer
        self._layout.addStretch()

    def update_account_info(self):
        a = self.world.get_account_info()
        if self._aswidget is not None:
            self._aswidget.update_account_info(a)

    def get_bpw_for_planet(self, planet_id: int, typ: str='') -> BuildProgressWidget:
        if typ == '':
            if planet_id in self.bp_widgets:
                return self.bp_widgets[planet_id]
            # create BPW for planet
            bpw = BuildProgressWidget(self)
            bpw.requestCancelBuildWithPlanet.connect(self.on_request_build_cancel_with_planet)
            self._gb_builds.addWidget(bpw)
            self.bp_widgets[planet_id] = bpw
            bpw.hide()
            return bpw
        elif typ == BuildProgressWidget.BPW_TYPE_SHIPYARD:
            if planet_id in self.bp_widgets_sy:
                return self.bp_widgets_sy[planet_id]
            # create BPW for planet shipyard
            bpw = BuildProgressWidget(self)
            bpw.requestCancelBuildWithPlanet.connect(self.on_request_build_cancel_with_planet)
            self._gb_shipyard.addWidget(bpw)
            self.bp_widgets_sy[planet_id] = bpw
            bpw.hide()
            return bpw
        elif typ == BuildProgressWidget.BPW_TYPE_RESEARCH:
            if planet_id in self.bp_widgets_res:
                return self.bp_widgets_res[planet_id]
            # create BPW for planet shipyard
            bpw = BuildProgressWidget(self)
            bpw.requestCancelBuildWithPlanet.connect(self.on_request_build_cancel_with_planet)
            self._gb_research.addWidget(bpw)
            self.bp_widgets_res[planet_id] = bpw
            bpw.hide()
            return bpw
        else:
            logger.error('get_bpw_for_planet(): unknown typre requested: {0}'.format(typ))

    def update_builds(self):
        self.setUpdatesEnabled(False)  # big visual changes may follow, stop screen flicker
        # delete existing build progress widgets (do not do it, just hide)
        for bpw in self.bp_widgets.values():
            bpw.hide()
        for bpw in self.bp_widgets_sy.values():
            bpw.hide()
        planets = self.world.get_planets()
        for pl in planets:
            # buildings
            bpw = self.get_bpw_for_planet(pl.planet_id)
            bpw.update_from_planet(pl)
            # shipyard
            if len(pl.shipyard_progress_items) > 0:
                bpw = self.get_bpw_for_planet(pl.planet_id, BuildProgressWidget.BPW_TYPE_SHIPYARD)
                bpw.show()
                bpw.update_from_planet(pl, BuildProgressWidget.BPW_TYPE_SHIPYARD)
            # researches
            bpw = self.get_bpw_for_planet(pl.planet_id, BuildProgressWidget.BPW_TYPE_RESEARCH)
            bpw.update_from_planet(pl, BuildProgressWidget.BPW_TYPE_RESEARCH)
        # make equal widths (this is not working, why?)
        # self._equalize_builds_widths()
        self.setUpdatesEnabled(True)

    def _equalize_builds_widths(self):
        maxwidth = -1
        for bpw in self.bp_widgets:
            w = bpw.get_els_widths()
            if w > maxwidth:
                maxwidth = w
        for bpw in self.bp_widgets:
            w = bpw.make_as_wide_as(maxwidth)
        logger.debug('got max width: {0}'.format(maxwidth))

    @pyqtSlot()
    def on_btn_refresh_overview(self):
        self.world.signal(self.world.SIGNAL_RELOAD_PAGE, page_name='overview')

    @pyqtSlot(XNPlanetBuildingItem, int)
    def on_request_build_cancel_with_planet(self, bitem: XNPlanetBuildingItem, planet_id: int):
        self.world.signal(self.world.SIGNAL_BUILD_CANCEL,
                          planet_id=planet_id,
                          bitem=bitem)
예제 #21
0
class OverviewWidget(QWidget):
    def __init__(self, parent=None):
        super(OverviewWidget, self).__init__(parent)
        # objects, sub-windows
        self.ui = None
        self._btn_reload = None
        self._aswidget = None
        self.world = XNovaWorld_instance()
        # build progress widgets
        self.bp_widgets = dict()  # build progress widgets
        self.bp_widgets_sy = dict()  # shipyard build progress widgets
        self.bp_widgets_res = dict()  # researches build progress widgets

    def load_ui(self):
        # layout
        self._layout = QVBoxLayout()
        self._layout_topbuttons = QHBoxLayout()
        self.setLayout(self._layout)
        self._layout.addLayout(self._layout_topbuttons)
        # sub-windows
        # reload button
        self._btn_reload = QPushButton(self.tr('Refresh overview'), self)
        self._btn_reload.setIcon(QIcon(':i/reload.png'))
        self._btn_reload.clicked.connect(self.on_btn_refresh_overview)
        self._layout_topbuttons.addWidget(self._btn_reload)
        self._layout_topbuttons.addStretch()
        # group box to hold builds info
        self._gb_builds = CollapsibleFrame(self)
        self._gb_builds.setTitle(self.tr('Building Jobs'))
        self._layout.addWidget(self._gb_builds)
        # groupbox to hold shipyard builds info
        self._gb_shipyard = CollapsibleFrame(self)
        self._gb_shipyard.setTitle(self.tr('Shipyard Jobs'))
        self._layout.addWidget(self._gb_shipyard)
        # groupbox to hold researches in progress info
        self._gb_research = CollapsibleFrame(self)
        self._gb_research.setTitle(self.tr('Researches'))
        self._layout.addWidget(self._gb_research)
        # groupbox to hold account stats widget
        self._gb_accstats = CollapsibleFrame(self)
        self._gb_accstats.setTitle(self.tr('Statistics'))
        self._layout.addWidget(self._gb_accstats)
        # account stats widget
        self._aswidget = Overview_AccStatsWidget(self)
        self._aswidget.load_ui()
        self._aswidget.show()
        self._gb_accstats.addWidget(self._aswidget)
        self._gb_accstats.expand()  # staticstics expanded by default
        # add final spacer
        self._layout.addStretch()

    def update_account_info(self):
        a = self.world.get_account_info()
        if self._aswidget is not None:
            self._aswidget.update_account_info(a)

    def get_bpw_for_planet(self,
                           planet_id: int,
                           typ: str = '') -> BuildProgressWidget:
        if typ == '':
            if planet_id in self.bp_widgets:
                return self.bp_widgets[planet_id]
            # create BPW for planet
            bpw = BuildProgressWidget(self)
            bpw.requestCancelBuildWithPlanet.connect(
                self.on_request_build_cancel_with_planet)
            self._gb_builds.addWidget(bpw)
            self.bp_widgets[planet_id] = bpw
            bpw.hide()
            return bpw
        elif typ == BuildProgressWidget.BPW_TYPE_SHIPYARD:
            if planet_id in self.bp_widgets_sy:
                return self.bp_widgets_sy[planet_id]
            # create BPW for planet shipyard
            bpw = BuildProgressWidget(self)
            bpw.requestCancelBuildWithPlanet.connect(
                self.on_request_build_cancel_with_planet)
            self._gb_shipyard.addWidget(bpw)
            self.bp_widgets_sy[planet_id] = bpw
            bpw.hide()
            return bpw
        elif typ == BuildProgressWidget.BPW_TYPE_RESEARCH:
            if planet_id in self.bp_widgets_res:
                return self.bp_widgets_res[planet_id]
            # create BPW for planet shipyard
            bpw = BuildProgressWidget(self)
            bpw.requestCancelBuildWithPlanet.connect(
                self.on_request_build_cancel_with_planet)
            self._gb_research.addWidget(bpw)
            self.bp_widgets_res[planet_id] = bpw
            bpw.hide()
            return bpw
        else:
            logger.error(
                'get_bpw_for_planet(): unknown typre requested: {0}'.format(
                    typ))

    def update_builds(self):
        self.setUpdatesEnabled(
            False)  # big visual changes may follow, stop screen flicker
        # delete existing build progress widgets (do not do it, just hide)
        for bpw in self.bp_widgets.values():
            bpw.hide()
        for bpw in self.bp_widgets_sy.values():
            bpw.hide()
        planets = self.world.get_planets()
        for pl in planets:
            # buildings
            bpw = self.get_bpw_for_planet(pl.planet_id)
            bpw.update_from_planet(pl)
            # shipyard
            if len(pl.shipyard_progress_items) > 0:
                bpw = self.get_bpw_for_planet(
                    pl.planet_id, BuildProgressWidget.BPW_TYPE_SHIPYARD)
                bpw.show()
                bpw.update_from_planet(pl,
                                       BuildProgressWidget.BPW_TYPE_SHIPYARD)
            # researches
            bpw = self.get_bpw_for_planet(
                pl.planet_id, BuildProgressWidget.BPW_TYPE_RESEARCH)
            bpw.update_from_planet(pl, BuildProgressWidget.BPW_TYPE_RESEARCH)
        # make equal widths (this is not working, why?)
        # self._equalize_builds_widths()
        self.setUpdatesEnabled(True)

    def _equalize_builds_widths(self):
        maxwidth = -1
        for bpw in self.bp_widgets:
            w = bpw.get_els_widths()
            if w > maxwidth:
                maxwidth = w
        for bpw in self.bp_widgets:
            w = bpw.make_as_wide_as(maxwidth)
        logger.debug('got max width: {0}'.format(maxwidth))

    @pyqtSlot()
    def on_btn_refresh_overview(self):
        self.world.signal(self.world.SIGNAL_RELOAD_PAGE, page_name='overview')

    @pyqtSlot(XNPlanetBuildingItem, int)
    def on_request_build_cancel_with_planet(self, bitem: XNPlanetBuildingItem,
                                            planet_id: int):
        self.world.signal(self.world.SIGNAL_BUILD_CANCEL,
                          planet_id=planet_id,
                          bitem=bitem)
예제 #22
0
def auto_builder_thread():
    import time
    from enum import IntEnum
    from ui.xnova.xn_data import XNPlanet, XNPlanetBuildingItem
    from ui.xnova.xn_world import XNovaWorld_instance, XNovaWorld
    from ui.xnova.xn_techtree import XNTechTree_instance
    from ui.xnova import xn_logger

    class BGid(IntEnum):
        METAL_FACTORY = 1
        CRYSTAL_FACTORY = 2
        DEIT_FACTORY = 3
        SOLAR_STATION = 4
        FACTORY = 14
        NANITES = 15
        SHIPYARD = 21
        METAL_SILO = 22
        CRYSTAL_SILO = 23
        DEIT_SILO = 24
        LAB = 31
        ROCKET_SILO = 44

    logger = xn_logger.get('auto_builder', debug=True)

    world = XNovaWorld_instance()
    world.script_command = 'running'

    WORK_INTERVAL = 145  # seconds
    IMPERIUM_REFRESH_INTERVAL = 300  # seconds

    def check_bonus(world: XNovaWorld):
        bonus_url = world.get_bonus_url()
        if bonus_url is not None:
            logger.info('Detected that bonus is available, get it!')
            world.signal(world.SIGNAL_GET_URL,
                         url=bonus_url,
                         referer='?set=overview')
            time.sleep(10)
            world.clear_bonus_url()
            time.sleep(2)

    def energy_need_for_gid(gid: int, level: int) -> int:
        if (gid == 1) or (gid == 2) or (gid == 12):
            e = (10 * level) * (1.1**level)
            return round(e)
        if gid == 3:
            e = (30 * level) * (1.1**level)
            return round(e)
        # error! incorrect gid supplied?
        tt = XNTechTree_instance()
        item = tt.find_item_by_gid(gid)
        s = 'Don\'t know how to calculate energy need for gid={0} "{1}" ({2})'.format(
            gid, item.name, item.category)
        logger.error(s)
        raise RuntimeError(s)

    def calc_planet_next_building(planet: XNPlanet) -> XNPlanetBuildingItem:
        if planet.is_moon or planet.is_base:
            return None
        met_level = 0
        cry_level = 0
        deit_level = 0
        ss_level = 0
        #
        met_bitem = planet.find_bitem_by_gid(int(BGid.METAL_FACTORY))
        if met_bitem is not None:
            met_level = met_bitem.level
        cry_bitem = planet.find_bitem_by_gid(int(BGid.CRYSTAL_FACTORY))
        if cry_bitem is not None:
            cry_level = cry_bitem.level
        deit_bitem = planet.find_bitem_by_gid(int(BGid.DEIT_FACTORY))
        if deit_bitem is not None:
            deit_level = deit_bitem.level
        ss_bitem = planet.find_bitem_by_gid(int(BGid.SOLAR_STATION))
        if ss_bitem is not None:
            ss_level = ss_bitem.level
        free_energy = planet.energy.energy_left
        #
        # first, check energy
        if free_energy <= 1:
            logger.info('Planet [{0}] has too low energy ({1}), must '
                        'build solar station!'.format(planet.name,
                                                      free_energy))
            return ss_bitem
        # second, check robotics factory, if it is below level 10
        factory_level = 0
        factory_bitem = planet.find_bitem_by_gid(int(BGid.FACTORY))
        if factory_bitem is not None:
            factory_level = factory_bitem.level
            if factory_bitem.level < 10:
                # check resources, this will build factory before any
                # any other building only if enough resources NOW, do not wait
                if (planet.res_current.met >= factory_bitem.cost_met) and \
                        (planet.res_current.cry >= factory_bitem.cost_cry) and \
                        (planet.res_current.deit >= factory_bitem.cost_deit):
                    logger.info(
                        'Planet [{0}] Factory level < 10 and have res for it,'
                        ' build Factory!'.format(planet.name))
                    return factory_bitem
        # maybe build shipyard? :)
        shipyard_bitem = planet.find_bitem_by_gid(int(BGid.SHIPYARD))
        if shipyard_bitem is not None:
            if shipyard_bitem.level < factory_level:
                if (planet.res_current.met >= shipyard_bitem.cost_met) and \
                        (planet.res_current.cry >= shipyard_bitem.cost_cry) and \
                        (planet.res_current.deit >= shipyard_bitem.cost_deit):
                    logger.info(
                        'Planet [{0}] Shipyard level < {1} and have res for it,'
                        ' build Factory!'.format(planet.name, factory_level))
                    return shipyard_bitem
        # maybe build nanites factory? :)
        if factory_level >= 10:
            nanites_bitem = planet.find_bitem_by_gid(int(BGid.NANITES))
            if nanites_bitem is not None:
                if (planet.res_current.met >= nanites_bitem.cost_met) and \
                        (planet.res_current.cry >= nanites_bitem.cost_cry) and \
                        (planet.res_current.deit >= nanites_bitem.cost_deit):
                    logger.info('Planet [{0}] can build NANITES!'.format(
                        planet.name))
                    return nanites_bitem
        # maybe build rocket silo?
        rs_bitem = planet.find_bitem_by_gid(int(BGid.ROCKET_SILO))
        if rs_bitem is not None:
            if rs_bitem.level < 2:
                if (planet.res_current.met >= rs_bitem.cost_met) and \
                        (planet.res_current.cry >= rs_bitem.cost_cry) and \
                        (planet.res_current.deit >= rs_bitem.cost_deit):
                    logger.info(
                        'Planet [{0}] can build rocket silo lv {1}'.format(
                            planet.name, rs_bitem.level + 1))
                    return rs_bitem
        #
        # other resources buildings
        logger.info(
            'Planet [{0}] m/c/d/e levels: {1}/{2}/{3}/{4} free_en: {5}'.format(
                planet.name, met_level, cry_level, deit_level, ss_level,
                free_energy))
        if ss_level < met_level:
            return ss_bitem
        #
        # calc energy needs
        met_eneed = energy_need_for_gid(int(BGid.METAL_FACTORY), met_level+1) \
            - energy_need_for_gid(int(BGid.METAL_FACTORY), met_level)
        cry_eneed = energy_need_for_gid(int(BGid.CRYSTAL_FACTORY), cry_level+1) \
            - energy_need_for_gid(int(BGid.CRYSTAL_FACTORY), cry_level)
        deit_eneed = energy_need_for_gid(int(BGid.DEIT_FACTORY), deit_level+1) \
            - energy_need_for_gid(int(BGid.DEIT_FACTORY), deit_level)
        logger.info('Planet [{0}] needed en: {1}/{2}/{3}'.format(
            planet.name, met_eneed, cry_eneed, deit_eneed))
        # try to fit in energy some buildings
        if (met_level < ss_level) and (met_eneed <= free_energy):
            return met_bitem
        if (cry_level < (ss_level - 2)) and (cry_eneed <= free_energy):
            return cry_bitem
        if (deit_level < (ss_level - 4)) and (deit_eneed <= free_energy):
            return deit_bitem
        #
        # check resources storage capacity
        if planet.res_max_silos.met > 0:
            if planet.res_current.met / planet.res_max_silos.met >= 0.7:
                silo_bitem = planet.find_bitem_by_gid(int(BGid.METAL_SILO))
                logger.info('Planet [{0}] needs metal silo!'.format(
                    planet.name))
                return silo_bitem
        if planet.res_max_silos.cry > 0:
            if planet.res_current.cry / planet.res_max_silos.cry >= 0.7:
                silo_bitem = planet.find_bitem_by_gid(int(BGid.CRYSTAL_SILO))
                logger.info('Planet [{0}] needs crystal silo!'.format(
                    planet.name))
                return silo_bitem
        if planet.res_max_silos.deit > 0:
            if planet.res_current.deit / planet.res_max_silos.deit >= 0.7:
                silo_bitem = planet.find_bitem_by_gid(int(BGid.DEIT_SILO))
                logger.info('Planet [{0}] needs deit silo!'.format(
                    planet.name))
                return silo_bitem
        #
        # default - build solar station
        logger.warn(
            'Planet [{0}] for some reason cannot decide what to build, '
            'will build solar station by default'.format(planet.name))
        return ss_bitem

    def check_planet_buildings(world: XNovaWorld, planet: XNPlanet):
        # is there any building in progress on planet now?
        build_in_progress = False
        bitem = XNPlanetBuildingItem()
        for bitem_ in planet.buildings_items:
            if bitem_.is_in_progress():
                build_in_progress = True
                bitem = bitem_
                break
        if build_in_progress:
            logger.info(
                'Planet [{0}] has still build in progress {1} lv {2}'.format(
                    planet.name, bitem.name, bitem.level + 1))
            return
        # no builds in progress, we can continue

        bitem = calc_planet_next_building(planet)
        if bitem is None:
            logger.error(
                'Planet [{0}]: for some reason could not calculate '
                'next building, some internal error? Try to relogin and '
                'refresh all world.'.format(planet.name))
            return

        logger.info('Planet [{0}] Next building will be: {1} lv {2}'.format(
            planet.name, bitem.name, bitem.level + 1))
        logger.info('Planet [{0}] Its price: {1}m {2}c {3}d'.format(
            planet.name, bitem.cost_met, bitem.cost_cry, bitem.cost_deit))
        logger.info('Planet [{0}] We have: {1}m {2}c {3}d'.format(
            planet.name, int(planet.res_current.met),
            int(planet.res_current.cry), int(planet.res_current.deit)))
        # do we have enough resources to build it?
        if (planet.res_current.met >= bitem.cost_met) and \
                (planet.res_current.cry >= bitem.cost_cry) and \
                (planet.res_current.deit >= bitem.cost_deit):
            logger.info(
                'Planet [{0}] We have enough resources to build it, trigger!'.
                format(planet.name))
            world.signal(world.SIGNAL_BUILD_ITEM,
                         planet_id=planet.planet_id,
                         bitem=bitem,
                         quantity=0)
            logger.info(
                'Planet [{0}] Signal to build this item has been sent to world thread, wait 10s...'
                .format(planet.name))
            time.sleep(10)  # actually wait
        else:
            logger.warn(
                'Planet [{0}] We DO NOT have enough resources to build [{1} lv {2}]...'
                .format(planet.name, bitem.name, bitem.level + 1))

    last_work_time = time.time() - WORK_INTERVAL
    last_imperium_refresh_time = time.time()

    logger.info('Started.')

    while True:
        time.sleep(1)
        if world.script_command == 'stop':
            break

        cur_time = time.time()
        if cur_time - last_work_time >= WORK_INTERVAL:
            last_work_time = cur_time
            # logger.debug('{0} seconds have passed, working...'.format(WORK_INTERVAL))
            check_bonus(world)
            planets = world.get_planets()
            if len(planets) < 1:
                continue
            for planet in planets:
                check_planet_buildings(world, planet)
                time.sleep(1)
                if world.script_command == 'stop':
                    break
        # if we didn't sleep long enough for a work_interval

        # refresh imperium from time to time
        if cur_time - last_imperium_refresh_time >= IMPERIUM_REFRESH_INTERVAL:
            logger.info('Time to refresh imperium...')
            last_imperium_refresh_time = cur_time
            world.signal(world.SIGNAL_RELOAD_PAGE, page_name='imperium')
    # while True

    del world.script_command

    logger.info('Stopped.')
예제 #23
0
 def __init__(self, parent: QWidget):
     super(PlanetWidget, self).__init__(parent)
     #
     self.world = XNovaWorld_instance()
     self._planet = XNPlanet()
     # setup frame
     self.setFrameShape(QFrame.StyledPanel)
     self.setFrameShadow(QFrame.Raised)
     # layout
     self._layout = QVBoxLayout()
     self._layout.setContentsMargins(0, 0, 0, 0)
     self._layout.setSpacing(3)
     self.setLayout(self._layout)
     # basic info panel
     self._bipanel = Planet_BasicInfoPanel(self)
     self._bipanel.requestOpenGalaxy.connect(self.on_request_open_galaxy)
     self._bipanel.requestRefreshPlanet.connect(
             self.on_request_refresh_planet)
     self._bipanel.requestRenamePlanet.connect(self.on_request_rename_planet)
     # build progress widgets
     self._bpw_buildings = BuildProgressWidget(self)
     self._bpw_buildings.hide()
     self._bpw_buildings.hide_planet_name()
     self._bpw_buildings.layout().setContentsMargins(5, 2, 5, 2)
     self._bpw_shipyard = BuildProgressWidget(self)
     self._bpw_shipyard.hide()
     self._bpw_shipyard.hide_planet_name()
     self._bpw_shipyard.layout().setContentsMargins(5, 2, 5, 2)
     self._bpw_research = BuildProgressWidget(self)
     self._bpw_research.hide()
     self._bpw_research.hide_planet_name()
     self._bpw_research.layout().setContentsMargins(5, 2, 5, 2)
     # buildings
     self._cf_buildings = CollapsibleFrame(self)
     self._cf_buildings.setTitle(self.tr('Buildings'))
     self._sa_buildings = QScrollArea(self._cf_buildings)
     self._bip_buildings = Planet_BuildItemsPanel(self._sa_buildings)
     self._bip_buildings.set_type(Planet_BuildItemsPanel.TYPE_BUILDINGS)
     self._bip_buildings.show()
     self._sa_buildings.setWidget(self._bip_buildings)
     self._cf_buildings.addWidget(self._sa_buildings)
     # shipyard
     self._cf_shipyard = CollapsibleFrame(self)
     self._cf_shipyard.setTitle(self.tr('Shipyard'))
     self._sa_shipyard = QScrollArea(self._cf_shipyard)
     self._bip_shipyard = Planet_BuildItemsPanel(self._cf_shipyard)
     self._bip_shipyard.set_type(Planet_BuildItemsPanel.TYPE_SHIPYARD)
     self._sa_shipyard.setWidget(self._bip_shipyard)
     self._cf_shipyard.addWidget(self._sa_shipyard)
     # research
     self._cf_research = CollapsibleFrame(self)
     self._cf_research.setTitle(self.tr('Research'))
     self._sa_research = QScrollArea(self._cf_research)
     self._bip_research = Planet_BuildItemsPanel(self._cf_research)
     self._bip_research.set_type(Planet_BuildItemsPanel.TYPE_RESEARCHES)
     self._sa_research.setWidget(self._bip_research)
     self._cf_research.addWidget(self._sa_research)
     # layout finalize
     self._layout.addWidget(self._bipanel)
     self._layout.addWidget(self._bpw_buildings)
     self._layout.addWidget(self._bpw_shipyard)
     self._layout.addWidget(self._bpw_research)
     self._layout.addWidget(self._cf_buildings)
     self._layout.addWidget(self._cf_shipyard)
     self._layout.addWidget(self._cf_research)
     # expand buildings frame by default
     self._cf_buildings.expand()
     #
     # connect signals
     self._cf_buildings.expanded.connect(self.on_frame_buildings_expanded)
     self._cf_buildings.collapsed.connect(self.on_frame_buildings_collapsed)
     self._cf_shipyard.expanded.connect(self.on_frame_shipyard_expanded)
     self._cf_shipyard.collapsed.connect(self.on_frame_shipyard_collapsed)
     self._cf_research.expanded.connect(self.on_frame_research_expanded)
     self._cf_research.collapsed.connect(self.on_frame_research_collapsed)
     #
     self._bpw_buildings.requestCancelBuild.connect(
             self.on_request_cancel_build)
     self._bpw_research.requestCancelBuild.connect(
             self.on_request_cancel_build)
     #
     self._bip_buildings.requestBuildItem.connect(self.on_request_build_item)
     self._bip_buildings.requestDowngradeItem.connect(
             self.on_request_downgrade_item)
     self._bip_shipyard.requestBuildItem.connect(self.on_request_build_item)
     self._bip_research.requestBuildItem.connect(self.on_request_build_item)
     #
     # create timer
     self._timer = QTimer(self)
     self._timer.timeout.connect(self.on_timer)
예제 #24
0
def auto_builder_thread():
    import time
    from enum import IntEnum
    from ui.xnova.xn_data import XNPlanet, XNPlanetBuildingItem
    from ui.xnova.xn_world import XNovaWorld_instance, XNovaWorld
    from ui.xnova.xn_techtree import XNTechTree_instance
    from ui.xnova import xn_logger

    class BGid(IntEnum):
        METAL_FACTORY = 1
        CRYSTAL_FACTORY = 2
        DEIT_FACTORY = 3
        SOLAR_STATION = 4
        FACTORY = 14
        NANITES = 15
        SHIPYARD = 21
        METAL_SILO = 22
        CRYSTAL_SILO = 23
        DEIT_SILO = 24
        LAB = 31
        ROCKET_SILO = 44

    logger = xn_logger.get("auto_builder", debug=True)

    world = XNovaWorld_instance()
    world.script_command = "running"

    WORK_INTERVAL = 145  # seconds
    IMPERIUM_REFRESH_INTERVAL = 300  # seconds

    def check_bonus(world: XNovaWorld):
        bonus_url = world.get_bonus_url()
        if bonus_url is not None:
            logger.info("Detected that bonus is available, get it!")
            world.signal(world.SIGNAL_GET_URL, url=bonus_url, referer="?set=overview")
            time.sleep(10)
            world.clear_bonus_url()
            time.sleep(2)

    def energy_need_for_gid(gid: int, level: int) -> int:
        if (gid == 1) or (gid == 2) or (gid == 12):
            e = (10 * level) * (1.1 ** level)
            return round(e)
        if gid == 3:
            e = (30 * level) * (1.1 ** level)
            return round(e)
        # error! incorrect gid supplied?
        tt = XNTechTree_instance()
        item = tt.find_item_by_gid(gid)
        s = 'Don\'t know how to calculate energy need for gid={0} "{1}" ({2})'.format(gid, item.name, item.category)
        logger.error(s)
        raise RuntimeError(s)

    def calc_planet_next_building(planet: XNPlanet) -> XNPlanetBuildingItem:
        if planet.is_moon or planet.is_base:
            return None
        met_level = 0
        cry_level = 0
        deit_level = 0
        ss_level = 0
        #
        met_bitem = planet.find_bitem_by_gid(int(BGid.METAL_FACTORY))
        if met_bitem is not None:
            met_level = met_bitem.level
        cry_bitem = planet.find_bitem_by_gid(int(BGid.CRYSTAL_FACTORY))
        if cry_bitem is not None:
            cry_level = cry_bitem.level
        deit_bitem = planet.find_bitem_by_gid(int(BGid.DEIT_FACTORY))
        if deit_bitem is not None:
            deit_level = deit_bitem.level
        ss_bitem = planet.find_bitem_by_gid(int(BGid.SOLAR_STATION))
        if ss_bitem is not None:
            ss_level = ss_bitem.level
        free_energy = planet.energy.energy_left
        #
        # first, check energy
        if free_energy <= 1:
            logger.info(
                "Planet [{0}] has too low energy ({1}), must " "build solar station!".format(planet.name, free_energy)
            )
            return ss_bitem
        # second, check robotics factory, if it is below level 10
        factory_level = 0
        factory_bitem = planet.find_bitem_by_gid(int(BGid.FACTORY))
        if factory_bitem is not None:
            factory_level = factory_bitem.level
            if factory_bitem.level < 10:
                # check resources, this will build factory before any
                # any other building only if enough resources NOW, do not wait
                if (
                    (planet.res_current.met >= factory_bitem.cost_met)
                    and (planet.res_current.cry >= factory_bitem.cost_cry)
                    and (planet.res_current.deit >= factory_bitem.cost_deit)
                ):
                    logger.info(
                        "Planet [{0}] Factory level < 10 and have res for it," " build Factory!".format(planet.name)
                    )
                    return factory_bitem
        # maybe build shipyard? :)
        shipyard_bitem = planet.find_bitem_by_gid(int(BGid.SHIPYARD))
        if shipyard_bitem is not None:
            if shipyard_bitem.level < factory_level:
                if (
                    (planet.res_current.met >= shipyard_bitem.cost_met)
                    and (planet.res_current.cry >= shipyard_bitem.cost_cry)
                    and (planet.res_current.deit >= shipyard_bitem.cost_deit)
                ):
                    logger.info(
                        "Planet [{0}] Shipyard level < {1} and have res for it,"
                        " build Factory!".format(planet.name, factory_level)
                    )
                    return shipyard_bitem
        # maybe build nanites factory? :)
        if factory_level >= 10:
            nanites_bitem = planet.find_bitem_by_gid(int(BGid.NANITES))
            if nanites_bitem is not None:
                if (
                    (planet.res_current.met >= nanites_bitem.cost_met)
                    and (planet.res_current.cry >= nanites_bitem.cost_cry)
                    and (planet.res_current.deit >= nanites_bitem.cost_deit)
                ):
                    logger.info("Planet [{0}] can build NANITES!".format(planet.name))
                    return nanites_bitem
        # maybe build rocket silo?
        rs_bitem = planet.find_bitem_by_gid(int(BGid.ROCKET_SILO))
        if rs_bitem is not None:
            if rs_bitem.level < 2:
                if (
                    (planet.res_current.met >= rs_bitem.cost_met)
                    and (planet.res_current.cry >= rs_bitem.cost_cry)
                    and (planet.res_current.deit >= rs_bitem.cost_deit)
                ):
                    logger.info("Planet [{0}] can build rocket silo lv {1}".format(planet.name, rs_bitem.level + 1))
                    return rs_bitem
        #
        # other resources buildings
        logger.info(
            "Planet [{0}] m/c/d/e levels: {1}/{2}/{3}/{4} free_en: {5}".format(
                planet.name, met_level, cry_level, deit_level, ss_level, free_energy
            )
        )
        if ss_level < met_level:
            return ss_bitem
        #
        # calc energy needs
        met_eneed = energy_need_for_gid(int(BGid.METAL_FACTORY), met_level + 1) - energy_need_for_gid(
            int(BGid.METAL_FACTORY), met_level
        )
        cry_eneed = energy_need_for_gid(int(BGid.CRYSTAL_FACTORY), cry_level + 1) - energy_need_for_gid(
            int(BGid.CRYSTAL_FACTORY), cry_level
        )
        deit_eneed = energy_need_for_gid(int(BGid.DEIT_FACTORY), deit_level + 1) - energy_need_for_gid(
            int(BGid.DEIT_FACTORY), deit_level
        )
        logger.info("Planet [{0}] needed en: {1}/{2}/{3}".format(planet.name, met_eneed, cry_eneed, deit_eneed))
        # try to fit in energy some buildings
        if (met_level < ss_level) and (met_eneed <= free_energy):
            return met_bitem
        if (cry_level < (ss_level - 2)) and (cry_eneed <= free_energy):
            return cry_bitem
        if (deit_level < (ss_level - 4)) and (deit_eneed <= free_energy):
            return deit_bitem
        #
        # check resources storage capacity
        if planet.res_max_silos.met > 0:
            if planet.res_current.met / planet.res_max_silos.met >= 0.7:
                silo_bitem = planet.find_bitem_by_gid(int(BGid.METAL_SILO))
                logger.info("Planet [{0}] needs metal silo!".format(planet.name))
                return silo_bitem
        if planet.res_max_silos.cry > 0:
            if planet.res_current.cry / planet.res_max_silos.cry >= 0.7:
                silo_bitem = planet.find_bitem_by_gid(int(BGid.CRYSTAL_SILO))
                logger.info("Planet [{0}] needs crystal silo!".format(planet.name))
                return silo_bitem
        if planet.res_max_silos.deit > 0:
            if planet.res_current.deit / planet.res_max_silos.deit >= 0.7:
                silo_bitem = planet.find_bitem_by_gid(int(BGid.DEIT_SILO))
                logger.info("Planet [{0}] needs deit silo!".format(planet.name))
                return silo_bitem
        #
        # default - build solar station
        logger.warn(
            "Planet [{0}] for some reason cannot decide what to build, "
            "will build solar station by default".format(planet.name)
        )
        return ss_bitem

    def check_planet_buildings(world: XNovaWorld, planet: XNPlanet):
        # is there any building in progress on planet now?
        build_in_progress = False
        bitem = XNPlanetBuildingItem()
        for bitem_ in planet.buildings_items:
            if bitem_.is_in_progress():
                build_in_progress = True
                bitem = bitem_
                break
        if build_in_progress:
            logger.info(
                "Planet [{0}] has still build in progress {1} lv {2}".format(planet.name, bitem.name, bitem.level + 1)
            )
            return
        # no builds in progress, we can continue

        bitem = calc_planet_next_building(planet)
        if bitem is None:
            logger.error(
                "Planet [{0}]: for some reason could not calculate "
                "next building, some internal error? Try to relogin and "
                "refresh all world.".format(planet.name)
            )
            return

        logger.info("Planet [{0}] Next building will be: {1} lv {2}".format(planet.name, bitem.name, bitem.level + 1))
        logger.info(
            "Planet [{0}] Its price: {1}m {2}c {3}d".format(
                planet.name, bitem.cost_met, bitem.cost_cry, bitem.cost_deit
            )
        )
        logger.info(
            "Planet [{0}] We have: {1}m {2}c {3}d".format(
                planet.name, int(planet.res_current.met), int(planet.res_current.cry), int(planet.res_current.deit)
            )
        )
        # do we have enough resources to build it?
        if (
            (planet.res_current.met >= bitem.cost_met)
            and (planet.res_current.cry >= bitem.cost_cry)
            and (planet.res_current.deit >= bitem.cost_deit)
        ):
            logger.info("Planet [{0}] We have enough resources to build it, trigger!".format(planet.name))
            world.signal(world.SIGNAL_BUILD_ITEM, planet_id=planet.planet_id, bitem=bitem, quantity=0)
            logger.info(
                "Planet [{0}] Signal to build this item has been sent to world thread, wait 10s...".format(planet.name)
            )
            time.sleep(10)  # actually wait
        else:
            logger.warn(
                "Planet [{0}] We DO NOT have enough resources to build [{1} lv {2}]...".format(
                    planet.name, bitem.name, bitem.level + 1
                )
            )

    last_work_time = time.time() - WORK_INTERVAL
    last_imperium_refresh_time = time.time()

    logger.info("Started.")

    while True:
        time.sleep(1)
        if world.script_command == "stop":
            break

        cur_time = time.time()
        if cur_time - last_work_time >= WORK_INTERVAL:
            last_work_time = cur_time
            # logger.debug('{0} seconds have passed, working...'.format(WORK_INTERVAL))
            check_bonus(world)
            planets = world.get_planets()
            if len(planets) < 1:
                continue
            for planet in planets:
                check_planet_buildings(world, planet)
                time.sleep(1)
                if world.script_command == "stop":
                    break
        # if we didn't sleep long enough for a work_interval

        # refresh imperium from time to time
        if cur_time - last_imperium_refresh_time >= IMPERIUM_REFRESH_INTERVAL:
            logger.info("Time to refresh imperium...")
            last_imperium_refresh_time = cur_time
            world.signal(world.SIGNAL_RELOAD_PAGE, page_name="imperium")
    # while True

    del world.script_command

    logger.info("Stopped.")
예제 #25
0
from ui.xnova.xn_world import XNovaWorld_instance
from ui.xnova import xn_logger


logger = xn_logger.get('test01_stopper', debug=True)
world = XNovaWorld_instance()

try:
    existing = world.script_command
    # if this fails, no such member exists, an exception will be raised
    # else, continue
    # world.script_test01_command = 'stop'
    world.script_command = 'stop'
    # world.script_test01_command = 'pn'
    logger.info('sent "stop" command to scripts.')
except AttributeError as ea:
    logger.info('probably script is not running.')
    pass
예제 #26
0
from ui.xnova.xn_world import XNovaWorld_instance
from ui.xnova.xn_data import XNPlanet, XNPlanetBuildingItem
from ui.xnova import xn_logger


logger = xn_logger.get('test01_stopper', debug=True)
world = XNovaWorld_instance()


def energy_need_for_gid(gid: int, level: int) -> int:
    if (gid == 1) or (gid == 2) or (gid == 12):
        e = (10 * level) * (1.1 ** level)
        return round(e)
    if gid == 3:
        e = (30 * level) * (1.1 ** level)
        return round(e)
    return -1


try:
    planets = world.get_planets()
    if len(planets) > 0:
        planet = planets[0]
        for bitem in planet.buildings_items:
            e = energy_need_for_gid(bitem.gid, bitem.level)
            if e != -1:
                print('{0} lv {1} need {2} energy'.format(bitem.name, bitem.level, e))
except Exception as ex:
    logger.exception('Exception happened')