Example #1
0
    def hide(self):
        super().hide()
        self.is_visible = False
        for pr in self.properties.widgets():
            pr.hide()

        flag = Systems.get_current() is not None
        flag = not len(Systems.get_current().asteroids +
                       Systems.get_current().satellites) if flag else False
        self.parent.set_skippable('Planetary Orbit', flag)
Example #2
0
    def suggest(self, planet, orbit, star):
        data = None
        planets_in_system = len(Systems.get_current().planets)
        e = round(0.584 * pow(planets_in_system, -1.2),
                  3) if planets_in_system > 1 else None
        if planet.habitable and orbit.temperature == 'habitable':
            data = recomendation['habitable']
            if e is not None and e <= 0.2:
                data.update({'e': e})

        elif planet.clase == 'Terrestial Planet':
            data = recomendation['inner']
            if e is not None and e <= 0.2:
                data.update({'e': e})

        elif planet.clase in ('Gas Giant', 'Super Jupiter', 'Puffy Giant',
                              'Gas Dwarf'):
            data = recomendation['giant']
            data.update(self.analyze_giants(planet, orbit, star))
            if data.get('eccentric', False):
                pass
            elif e is not None and 0.001 <= e <= 0.09:
                data.update({'e': e})

        self.format = data
Example #3
0
 def show(self):
     system = Systems.get_current()
     if system is not None:
         planets = [i for i in system.planets if i.orbit is None]
         if not len(
                 self.listed_objects.get_widgets_from_layer(
                     Systems.get_current_idx())):
             self.populate(planets)
     super().show()
Example #4
0
    def show_name(self):
        self.image.fill(COLOR_BOX, (0, 21, self.rect.w, 16))
        planet = self.curr_planet
        if planet is not None:
            text = 'Atmosphere of planet'
            idx = Systems.get_current().planets.index(planet)
            text += ' #' + str(idx) + ' (' + planet.clase + ')'

            self.write(text, self.f2, centerx=self.rect.centerx, y=21)
Example #5
0
 def show_mass(self):
     try:
         mass = Systems.get_current().get_available_mass()
     except AttributeError:
         mass = q(0, 'jupiter_mass')
     if not self.show_jovian_mass:
         mass = mass.to('earth_mass')
     attr = '{:,g~}'.format((round(mass, 4)))
     return attr
Example #6
0
    def analyze_giants(planet, orbit, star):
        planets_in_system = len(Systems.get_current().planets)
        e = round(0.584 * pow(planets_in_system, -1.2),
                  3) if planets_in_system > 1 else None
        # average eccentricity

        clase = planet.clase in ('Puffy Giant', 'Gas Giant')
        orbita = 0.04 <= orbit.a.m <= 0.5
        period = q(sqrt(pow(orbit.a.m, 3) / star.mass.m),
                   'year').to('day').m >= 3
        if all([clase, orbita, period]) is True:
            return recomendation['hot']

        clase = planet.clase == 'Super Jupiter'
        orbita = 0.04 <= orbit.a.m <= 1.2 * star.frost_line.m
        if all([clase, orbita]) is True:
            # this is more of a warning than a suggestion, since a super jupiter
            # can't be placed too far away from the star, and there is no special
            # consideration about it's eccentricity or inclination.
            return recomendation['giant']
        elif clase:  # Is the planet still a Super Jupiter?
            raise AssertionError(
                "A super jupiter can't orbit so far away from it's star.")
            # needs an "undo" after this.

        clase = planet.clase in ('Gas Dwarf', 'Gas Giant')
        orbita = 1.2 * star.frost_line.m <= orbit.a.m < star.outer_boundry.m
        if all([clase, orbita]) is True:
            return recomendation['giant']

        clase = planet.clase == 'Gas Giant'
        habitable = any([i.habitable for i in Systems.get_current().planets])
        data = recomendation['giant']
        data.update({'eccentric': True})
        error = f'An eccentric Jupiter must have an orbital eccentricity of 0.1 or greater, up to 0.2 if there is a '
        error += f'habitable world in the system. However, there are {planets_in_system} planets in this system, so '
        error += f'the eccentricity should be {e} which falls ouside of those parameters.'
        assert all([habitable, planets_in_system not in (3, 4),
                    e > 0.1]), error
        if all([clase, habitable]) is True:
            data.update(recomendation['eccentric_2'])
        elif not habitable:
            data.update(recomendation['eccentric_1'])
        return data
Example #7
0
 def show(self):
     system = Systems.get_current()
     if system is not None:
         bodies = [
             body for body in system.astro_bodies if body.hill_sphere != 0
         ]
         if not len(
                 self.listed_objects.get_widgets_from_layer(
                     Systems.get_current_idx())):
             self.populate(bodies)
     super().show()
Example #8
0
 def add_button(self, planet):
     button = CreatedPlanet(self.current, planet, self.curr_x, self.curr_y)
     if planet.system_id is not None:
         layer_number = Systems.get_system_idx_by_id(planet.system_id)
     else:
         layer_number = Systems.get_current_idx()
         planet.system_id = Systems.get_current().id
     self.planet_buttons.add(button, layer=layer_number)
     self.planets.append(planet)
     self.sort_buttons()
     self.properties.add(button, layer=3)
Example #9
0
    def calculate(self):
        data = {'composition': None}
        if self.current is None:
            data['composition'] = {}
        else:
            data['composition'] = self.current.composition

        for item in self.properties.get_widgets_from_layer(2):
            if item.text_area.value:
                data[item.text.lower()] = float(item.text_area.value)

        for item in self.properties.get_widgets_from_layer(3):
            if item.text_area.value:
                data[item.text.lower()] = float(item.text_area.value)

        for material in self.properties.get_widgets_from_layer(4):
            if material.text_area.value:  # not empty
                data['composition'][material.text.lower()] = float(
                    material.text_area.value)

        if self.current is not None:
            data['a axis'] = self.current.a_axis.m
            data['b axis'] = self.current.b_axis.m
            data['c axis'] = self.current.c_axis.m
            data['id'] = self.current.id
            data['system'] = self.current.system_id

        moon = minor_moon_by_composition(data)
        if self.current is None:
            if Systems.get_current().add_astro_obj(moon):
                self.current = moon
                self.parent.button_add.enable()
        else:
            Systems.get_current().remove_astro_obj(self.current)
            if Systems.get_current().add_astro_obj(moon):
                self.current = moon

        if self.current.system_id is None:
            self.current.system_id = Systems.get_current().id

        self.fill()
Example #10
0
    def calculate(self):
        data = {'composition': None}
        if self.current is None:
            data['composition'] = {}
        else:
            data['composition'] = self.current.composition

        for material in self.properties.get_sprites_from_layer(2):
            if material.text_area.value:  # not empty
                text = material.text_area.value.strip(' %')
                data['composition'][material.text.lower()] = float(text)
        for item in self.properties.get_widgets_from_layer(1):
            text = item.text_area.value
            if type(text) is not str:
                data[item.text.lower()] = float(text)
            elif text != '' and not text.isalpha():
                data[item.text.lower()] = float(text)
            else:
                data[item.text.lower()] = text

        if self.current is not None:
            data['radius'] = self.current.radius.m
            data['id'] = self.current.id
            data['system'] = self.current.system_id

        self.has_values = True

        moon = major_moon_by_composition(data)
        if self.current is None:
            if Systems.get_current().add_astro_obj(moon):
                self.current = moon
        else:
            Systems.get_current().remove_astro_obj(self.current)
            if Systems.get_current().add_astro_obj(moon):
                self.current = moon

        if self.current.system_id is None:
            self.current.system_id = Systems.get_current().id

        self.parent.button_add.enable()
        self.fill()
Example #11
0
 def show(self):
     system = Systems.get_current()
     if system is not None:
         pop = [
             planet for planet in system.planets
             if not len(planet.atmosphere) and planet.orbit is not None
         ]
         if not len(
                 self.listed_objects.get_widgets_from_layer(
                     Systems.get_current_idx())):
             self.populate(pop)
     super().show()
Example #12
0
 def add_button(self):
     button = AsteroidButton(self.current, self.current.current,
                             self.curr_x, self.curr_y)
     if self.current.current.system_id is not None:
         layer_number = Systems.get_system_idx_by_id(
             self.current.current.system_id)
     else:
         layer_number = Systems.get_current_idx()
         self.current.current.system_id = Systems.get_current().id
     self.moons.append(self.current.current)
     self.asteroids.add(button, layer=layer_number)
     self.properties.add(button)
     self.sort_buttons()
     self.current.erase()
     self.button_add.disable()
Example #13
0
    def create_button(self, planet=None):
        if planet is None:
            planet = self.current
            system = Systems.get_current()
        else:
            system = Systems.get_system_by_id(planet.system_id)

        if system.add_astro_obj(planet):
            for button in self.properties.get_widgets_from_layer(1):
                button.text_area.clear()
            self.parent.button_add.disable()
            self.parent.add_button(planet)
            self.has_values = False
            self.parent.image.fill(COLOR_BOX, self.hab_rect)
            if self.current is not None and self.current.sprite is not None:
                self.current.sprite.hide()
Example #14
0
    def fill(self, tos=None):
        tos = {
            'mass': 'kg',
            'radius': 'km',
            'luminosity': 'W',
            'lifetime': 'year',
            'temperature': 'kelvin'
        }
        super().fill(tos)
        system = Systems.get_current()
        if system is not None:
            system.update()

        if self.current.sprite is None:
            self.current.sprite = StarSprite(self, self.current, 460, 100)
            self.properties.add(self.current.sprite)
        self.current.sprite.show()
Example #15
0
    def add_objects(self):
        system = Systems.get_current()
        if system is not None:
            for obj in system.satellites + system.asteroids:
                if obj not in self.objects:
                    self.objects.append(obj)
                    btn = ObjectButton(self, obj, self.curr_x, self.curr_y)
                    if obj.orbit is not None:
                        btn.update_text(obj.orbit.a)
                        markers = self._markers[obj.orbit.star.id]
                        marker_idx = [
                            i for i in range(len(markers))
                            if markers[i].obj == obj
                        ][0]
                        marker = markers[marker_idx]
                        btn.link_marker(marker)

                    self.buttons.add(btn, layer=Systems.get_current_idx())
                    self.properties.add(btn)
            self.sort_buttons()
Example #16
0
    def add_new(self, obj):
        if obj not in self.added:
            self.added.append(obj)
        obj_name = obj.cls
        pln_habitable = Systems.get_current().is_habitable(self.current)
        pln_hill = self.current.hill_sphere.m
        obj_type = obj.celestial_type
        roches = self.create_roches_marker(obj)

        text = "A satellite's mass must be less than or equal to the\nmass of the planet."
        text += '\n\nConsider using a less massive satellite for this planet.'
        assert self.current.mass.to('earth_mass').m >= obj.mass.to(
            'earth_mass').m, text

        pos = q(
            round(
                roll(self.current.roches_limit.m,
                     self.current.hill_sphere.m / 2), 3), 'earth_radius')
        orbit = RawOrbit(Systems.get_current_star(), pos)
        obj_marker = Marker(self,
                            obj_name,
                            pos,
                            color=COLOR_SELECTED,
                            lock=False)

        max_value = pln_hill
        if pln_habitable and obj_type != 'asteroid':
            max_value /= 2
        obj_marker.set_max_value(max_value)
        obj_marker.set_min_value(roches.m)
        obj_marker.links(orbit, obj)

        self.markers.append(obj_marker)
        self.properties.add(obj_marker, layer=3)
        self.sort_markers()

        return orbit, obj_marker
Example #17
0
    def check_values(self, composition):
        attrs = {}
        for button in self.properties.get_sprites_from_layer(1):
            attr = ''
            if button in self.relatives:
                idx = self.relatives.widgets().index(button)
                attr = self.relative_args[idx]
            elif button in self.absolutes:
                idx = self.absolutes.widgets().index(button)
                attr = self.absolute_args[idx]
            if button.text_area.value:  # not empty
                string = str(button.text_area.value).split(' ')[0]
                try:
                    setattr(self, attr, float(string))
                    attrs[attr] = float(string)
                except ValueError:
                    setattr(self, attr, button.text_area.value)
                    attrs[attr] = button.text_area.value

        if len(attrs) > 1:
            unit = self.parent.unit.name.lower()
            attrs['unit'] = 'jupiter' if unit == 'gas giant' else 'earth'
            attrs['idx'] = len(
                self.parent.planet_buttons.get_widgets_from_layer(
                    Systems.get_current_idx()))
            if composition is not None:
                attrs['composition'] = composition
            self.current = Planet(attrs)
            self.toggle_habitable()
            if self.current.mass <= Systems.get_current().body_mass:
                self.parent.button_add.enable()
                self.parent.mass_number.mass_color = COLOR_TEXTO
            else:
                self.parent.button_add.disable()
                self.parent.mass_number.mass_color = 200, 0, 0
            self.fill()
Example #18
0
    def on_mousebuttondown(self, event):
        not_enough_mass = 'There is not enough mass in the system to create new bodies of this type.'
        if event.button == 1:
            p = self.parent
            if p.parent.name == 'Planet':
                data = None
                system = Systems.get_current()
                self.active = True
                available_mass = system.get_available_mass()
                if p.parent.unit.name == 'Habitable' and not p.has_values:
                    available_mass = available_mass.to('earth_mass').m
                    m_low, m_high, r_low, r_high = Terrestial
                    if available_mass < m_high:
                        m_high = available_mass
                    assert m_high >= 3.5, not_enough_mass
                    data = graph_loop(mass_lower_limit=m_low,
                                      mass_upper_limit=m_high,
                                      radius_lower_limit=r_low,
                                      radius_upper_limit=r_high)
                elif p.parent.unit.name == 'Terrestial' and not p.has_values:
                    available_mass = available_mass.to('earth_mass').m
                    m_high = 10
                    if available_mass < m_high:
                        m_high = available_mass
                    assert m_high > 0.1, not_enough_mass
                    data = graph_loop(mass_upper_limit=m_high)
                elif p.parent.unit.name == 'Gas Dwarf' and not p.has_values:
                    m_low, m_high, r_low, r_high = GasDwarf
                    if available_mass.to('earth_mass').m < m_high:
                        m_high = available_mass.m
                    assert m_high > 0.2, not_enough_mass
                    data = graph_loop(mass_lower_limit=m_low,
                                      mass_upper_limit=m_high,
                                      radius_lower_limit=r_low,
                                      radius_upper_limit=r_high,
                                      is_gas_drwaf=True)
                elif p.parent.unit.name == 'Gas Giant' and not p.has_values:
                    assert available_mass.m >= 0.03, not_enough_mass
                    data = gasgraph_loop(round(available_mass.m, 2))
                elif p.parent.unit.name == 'Dwarf Planet' and not p.has_values:
                    available_mass = round(
                        available_mass.to('earth_mass').m, 4)
                    assert available_mass > 0.0001, not_enough_mass
                    data = dwarfgraph_loop(
                        available_mass if available_mass < 0.1 else None)

                Renderer.reset()
                if data is not None:
                    for elemento in self.parent.properties.get_sprites_from_layer(
                            1):
                        attr = ''
                        if elemento in self.parent.relatives:
                            idx = self.parent.relatives.widgets().index(
                                elemento)
                            attr = self.parent.relative_args[idx]
                        elif elemento in self.parent.absolutes:
                            idx = self.parent.absolutes.widgets().index(
                                elemento)
                            attr = self.parent.absolute_args[idx]

                        if attr in data:
                            elemento.value = str(data[attr])
                            elemento.text_area.show()
                    self.parent.check_values(data.get('composition', None))

                elif self.text == 'Axial tilt':
                    data = axial_loop()
                    self.parent.update_value(self, data)

            elif p.parent.name == 'Orbit' and p.has_values:
                text = self.text_area
                if text.unit == 'year' and text.value < 0.01:
                    attr = q(text.value, text.unit).to('day')
                    if attr.m < 0.1:
                        attr = attr.to('hour')
                    text.set_value(attr)
                    text.update()

                elif self.editable:
                    self.active = True
                    self.text_area.enable()
            elif p.parent.name == 'Naming' and not p.has_values:
                p.parent.set_current(self)
                self.active = True
                self.text_area.enable()
            else:
                self.active = True
                self.text_area.enable()
            return self.text
Example #19
0
 def destroy_button(self):
     destroyed = Systems.get_current().remove_astro_obj(self.current)
     if destroyed:
         self.parent.del_button(self.current)
         self.erase()