Ejemplo n.º 1
0
    def show(self):
        """Show/hide the journal GUI."""
        if self._is_shown:
            self._main_fr.hide()
            self._close_snd.play()
            if not self._winned and self._read_coordinates:
                self._winned = True

                page = DirectFrame(
                    frameSize=(-0.73, 0.73, -0.9, 0.9),
                    frameTexture="gui/tex/paper1.png",
                    state=DGG.NORMAL,
                )
                page.setDepthTest(False)
                page.setTransparency(TransparencyAttrib.MAlpha)
                page.show()

                DirectLabel(
                    parent=page,
                    text=base.labels.UNTERRIFF_DISCOVERED_TITLE,  # noqa: F821
                    text_font=base.main_font,  # noqa: F821
                    frameSize=(0.6, 0.6, 0.6, 0.6),
                    text_scale=0.043,
                    pos=(0, 0, 0.65),
                )

                DirectLabel(
                    parent=page,
                    text=base.labels.UNTERRIFF_DISCOVERED,  # noqa: F821
                    text_font=base.main_font,  # noqa: F821
                    frameSize=(0.6, 0.6, 0.6, 0.6),
                    text_scale=0.037,
                    pos=(0, 0, 0.55),
                )

                DirectButton(  # Done
                    parent=page,
                    pos=(0, 0, -0.77),
                    text=base.labels.DISTINGUISHED[6],  # noqa: F821
                    text_font=base.main_font,  # noqa: F821
                    text_fg=RUST_COL,
                    text_shadow=(0, 0, 0, 1),
                    frameColor=(0, 0, 0, 0),
                    command=page.destroy,
                    extraArgs=[],
                    scale=(0.05, 0, 0.05),
                    clickSound=base.main_menu.click_snd,  # noqa: F821
                )

            self._read_coordinates = False
        else:
            self._main_fr.show()
            self._open_snd.play()

        self._is_shown = not self._is_shown
Ejemplo n.º 2
0
class Scenario:
    """The game scenario orchestrator.

    Tracks on which part of the scenario the player is, controls
    the next scenario steps and performs choice consequences effects.

    One scenario chapter includes a situation in which the player
    has to make a decision. Decision will have consequences, positive
    or negative, but in any case the player will become one step
    closer to figuring out the way to survive the Stench. After
    every chapter the player will also get a note written in a
    diary fashion. The note will give the player more info about
    the Stench, Captain, the Adjutant and how the cataclysm
    started to destroy the World.

    Args:
        current_chapter (int): The chapter number to start with.
    """
    def __init__(self, current_chapter=None):
        if current_chapter is not None:  # saved game
            self.current_chapter = current_chapter
        else:  # game start
            self.current_chapter = -1

        self._list = DirectFrame(
            frameSize=(-0.73, 0.73, -0.9, 0.9),
            frameTexture=GUI_PIC + "paper1.png",
            state=DGG.NORMAL,
        )
        self._list.setDepthTest(False)
        self._list.setTransparency(TransparencyAttrib.MAlpha)
        self._list.hide()

        self._name = DirectLabel(
            parent=self._list,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.4, 0.4, 0.4, 0.4),
            text_scale=0.05,
            pos=(-0.4, 0, 0.7),
        )
        self._type = DirectLabel(
            parent=self._list,
            text=base.labels.SCENARIO_LABELS[1],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.4, 0.4, 0.4, 0.4),
            text_scale=0.035,
            pos=(-0.13, 0, 0.699),
        )
        self._desc = DirectLabel(
            parent=self._list,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.6, 0.6, 0.6, 0.6),
            text_scale=0.037,
            pos=(0, 0, 0.55),
        )

        self._buts = []
        z_coor = -0.6
        for _ in range(3):
            self._buts.append(
                DirectButton(
                    parent=self._list,
                    text="Text",
                    text_font=base.main_font,  # noqa: F821
                    text_fg=RUST_COL,
                    text_shadow=(0, 0, 0, 1),
                    frameColor=(0, 0, 0, 0),
                    frameSize=(-9, 9, -0.3, 0.7),
                    scale=(0.047, 0, 0.047),
                    clickSound=base.main_menu.click_snd,  # noqa: F821
                    pos=(0, 0, z_coor),
                ))
            z_coor -= 0.08

        self._done_but = DirectButton(
            parent=self._list,
            text=base.labels.DISTINGUISHED[6],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            text_fg=RUST_COL,
            text_shadow=(0, 0, 0, 1),
            frameColor=(0, 0, 0, 0),
            frameSize=(-9, 9, -0.3, 0.7),
            scale=(0.05, 0, 0.05),
            clickSound=base.main_menu.click_snd,  # noqa: F821
            pos=(0, 0, -0.8),
            command=self.hide_chapter,
        )

    def _choose_variant(self, var):
        """Process the player's choice and do consequences.

        Args:
            var (str): Variant id.
        """
        consequences = base.labels.SCENARIO[
            self.current_chapter][  # noqa: F821
                "variants"][var]
        for but in self._buts:
            but.hide()

        self._desc["text"] = consequences["desc"]
        for effect in consequences["effects"]:
            getattr(self, effect[0])(*effect[1])

        base.journal.add_page(self.current_chapter)  # noqa: F821
        self._done_but.show()
        base.res_gui.update_resource(  # noqa: F821
            "places_of_interest",
            str(self.current_chapter + 1) + "/10")

        base.decisions["decision_" + str(self.current_chapter)] = {  # noqa: F821
            "decision": var,
            "goodness": consequences["goodness"],
        }

    def finish_game(self):
        """Completely finish the game."""
        self.hide_chapter()
        taskMgr.doMethodLater(  # noqa: F821
            1,
            base.effects_mgr.fade_out_screen,
            "fade_out"  # noqa: F821
        )
        taskMgr.doMethodLater(  # noqa: F821
            4,
            base.main_menu.show_credits,
            "show_credits",  # noqa: F821
        )
        taskMgr.doMethodLater(  # noqa: F821
            4.5,
            base.effects_mgr.fade_in_screen,
            "fade_in"  # noqa: F821
        )
        taskMgr.doMethodLater(  # noqa: F821
            76,
            base.restart_game,
            "restart_game",
            extraArgs=[]  # noqa: F821
        )
        base.train.ctrl.unset_controls()  # noqa: F821
        base.effects_mgr.stench_effect.stop()  # noqa: F821

        for task in (
                "update_physics",
                "sun_look_at_train",
                "collide_mouse",
                "move_camera_with_mouse",
                "update_speed_indicator",
                "disease",
                "show_teaching_note",
                "calc_cohesion",
                "track_ambient_sounds",
                "stench_step",
                "check_train_contacts",
                "change_sun_color",
        ):
            base.taskMgr.remove(task)  # noqa: F821

        base.sound_mgr.disable()  # noqa: F821
        base.world.drown_ambient_snds()  # noqa: F821

    def do_build_camp_effect(self):
        """Do effects for building a camp for orphans choice."""
        base.helped_children = True  # noqa: F821

    def do_spend_cohesion(self, value):
        """Do effect of decreasing the crew cohesion.

        Args:
            value (int): The amount of the cohesion change.
        """
        base.team.spend_cohesion(value)  # noqa: F821

    def do_get_money(self, money):
        """Get or lose the given amount of money.

        Args:
            money (int): Money amount to get/lose.
        """
        base.dollars += money  # noqa: F821

    def do_plus_resource(self, name, value):
        """Change the given resource amount.

        Args:
            name (str): Resource name.
            value (int): Amount delta.
        """
        base.plus_resource(name, value)  # noqa: F821

    def do_enemy_inc_effect(self):
        """Make enemy stronger effect."""
        base.world.enemy.score += 3  # noqa: F821

    def do_character_effect(self, char, effect):
        """Do choice consequences effect to the given character.

        Args:
            char (units.crew.character.Character):
                The character to do effect to.
            effect (dict): The effect description.
        """
        for key, value in effect.items():
            setattr(char, key, getattr(char, key) + value)

    def do_characters_effect(self, effect, to_one=False):
        """Do choice consequences effects to the crew.

        Args:
            effect (dict): Effect description.
            to_one (bool): Effect targets only one random character.
        """
        if to_one:
            self.do_character_effect(
                random.choice(list(base.team.chars.values())),
                effect  # noqa: F821
            )
            return

        for char in base.team.chars.values():  # noqa: F821
            self.do_character_effect(char, effect)

    def do_locomotive_damage(self, damage):
        """Do some damage to the Adjutant.

        Args:
            damage (int): Amount of damage to do.
        """
        base.train.get_damage(damage)  # noqa: F821

    def do_no_effect(self):
        """No choice consequences method."""
        pass

    def do_stench_moves_effect(self, steps):
        """Move the Stench frontier several miles deeper into the Silewer.

        Args:
            steps (int): Number of miles to cover with the Stench.
        """
        for _ in range(steps):
            base.world.make_stench_step()  # noqa: F821

    def do_transfusion_effect(self):
        """Do blood transfusion effect of Chapter 9."""
        char = None
        chars = list(base.team.chars.values())  # noqa: F821

        if chars:
            char = take_random(chars)
            char.health -= 30

        if chars:
            take_random(chars).health -= 30
        elif char:
            char.health -= 30

    def do_medicine_save(self):
        """Do save with medicines effect of Chapter 9."""
        if base.resource("medicine_boxes"):  # noqa: F821
            base.plus_resource("medicine_boxes", -1)  # noqa: F821
        else:
            chars = list(base.team.chars.values())  # noqa: F821
            if chars:
                take_random(chars).energy -= 40

    def hide_chapter(self):
        """Hide the scenario GUI."""
        self._list.hide()

    def start_chapter(self, task):
        """Start a new scenario chapter."""
        self.current_chapter += 1

        base.train.ctrl.set_controls(base.train)  # noqa: F821
        base.camera_ctrl.enable_ctrl_keys()  # noqa: F821

        base.world.outings_mgr.hide_outing()  # noqa: F821
        base.traits_gui.hide()  # noqa: F821

        if self.current_chapter <= 9:
            self.show_chapter_situation()  # noqa: F821

            base.world.drop_place_of_interest()  # noqa: F821

        return task.done

    def show_chapter_situation(self):
        """Show the situation description and the possible variants."""
        self._done_but.hide()
        self._name[
            "text"] = base.labels.SCENARIO_LABELS[0] + str(  # noqa: F821
                self.current_chapter + 1)
        self._desc["text"] = base.labels.SCENARIO[
            self.current_chapter][  # noqa: F821
                "intro"]

        if (len(base.labels.SCENARIO[self.current_chapter]
                ["variants"])  # noqa: F821
                == 3):
            for index, var in enumerate(base.labels.SCENARIO[
                    self.current_chapter]["variants"]  # noqa: F821
                                        ):
                self._buts[index]["text"] = var
                self._buts[index]["extraArgs"] = [var]
                self._buts[index]["command"] = self._choose_variant
                self._buts[index].show()
        else:
            self._buts[0].hide()
            self._buts[1].hide()

            for var in base.labels.SCENARIO[
                    self.current_chapter][  # noqa: F821
                        "variants"]:
                self._buts[2]["text"] = var
                self._buts[2]["extraArgs"] = [var]
                self._buts[2]["command"] = self._choose_variant
                self._buts[2].show()

            self._done_but["command"] = self.finish_game

        self._list.show()
Ejemplo n.º 3
0
class TraitsGUI:
    """GUI to praise/scold characters.

    This GUI gives players an opportunity to
    control their characters' traits.
    """
    def __init__(self):
        self._cur_char = None
        self._ind_chosen = None
        self._new_chosen = False
        self._need_update = False
        self.is_shown = False

        self._cur_traits = []
        self._new_traits = []

        self._open_snd = loader.loadSfx("sounds/GUI/paper1.ogg")  # noqa: F821
        self._close_snd = loader.loadSfx("sounds/GUI/paper2.ogg")  # noqa: F821
        self._scold_snd = loader.loadSfx("sounds/GUI/scold.ogg")  # noqa: F821
        self._praise_snd = loader.loadSfx(
            "sounds/GUI/praise.ogg")  # noqa: F821

        self._list = DirectFrame(
            frameSize=(-0.75, 0.75, -0.77, 0.77),
            frameTexture=GUI_PIC + "paper1.png",
            state=DGG.NORMAL,
        )
        self._list.setDepthTest(False)
        self._list.setTransparency(TransparencyAttrib.MAlpha)
        self._list.hide()

        DirectLabel(  # List of distinguished
            parent=self._list,
            text=base.labels.DISTINGUISHED[0],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.4, 0.4, 0.4, 0.4),
            text_scale=0.045,
            pos=(-0.35, 0, 0.65),
        )
        DirectLabel(  # the praise/scold mechanisms description
            parent=self._list,
            text=base.labels.DISTINGUISHED[1],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.3, 0.3, 0.3, 0.3),
            text_scale=0.035,
            text_bg=(0, 0, 0, 0),
            pos=(0, 0, 0.54),
        )
        self._char_chooser = CharacterChooser(is_shadowed=True)

        DirectLabel(  # Cohesion points:
            parent=self._list,
            text=base.labels.DISTINGUISHED[2],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.035,
            text_bg=(0, 0, 0, 0),
            pos=(0.3, 0, 0.065),
        )
        self._cohesion_pts = DirectLabel(
            parent=self._list,
            text="",
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.035,
            text_bg=(0, 0, 0, 0),
            pos=(0.47, 0, 0.065),
        )
        self._cur_traits_num = DirectLabel(  # Current traits
            parent=self._list,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.032,
            text_bg=(0, 0, 0, 0),
            pos=(0.3, 0, -0.08),
        )
        DirectLabel(  # New traits:
            parent=self._list,
            text=base.labels.DISTINGUISHED[3],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.032,
            text_bg=(0, 0, 0, 0),
            pos=(-0.35, 0, -0.08),
        )
        traits_fr = DirectFrame(
            parent=self._list,
            frameSize=(-0.65, 0.6, -0.18, 0.2),
            pos=(0, 0, -0.32),
            frameColor=(0, 0, 0, 0.3),
        )

        shift = 0.15
        for index in range(3):
            self._cur_traits.append((
                DirectButton(
                    pos=(0.3, 0, shift),
                    text="",
                    text_fg=SILVER_COL,
                    text_scale=0.032,
                    text_font=base.main_font,  # noqa: F821
                    parent=traits_fr,
                    frameSize=(-0.2, 0.2, -0.05, 0.05),
                    relief=None,
                    command=self._choose_trait,
                    extraArgs=[self._cur_traits, self._new_traits, index],
                ),
                DirectButton(
                    pos=(0.3, 0, shift - 0.045),
                    text="",
                    text_fg=SILVER_COL,
                    text_scale=0.027,
                    text_font=base.main_font,  # noqa: F821
                    parent=traits_fr,
                    frameSize=(-0.2, 0.2, -0.05, 0.05),
                    relief=None,
                    command=self._choose_trait,
                    extraArgs=[self._cur_traits, self._new_traits, index],
                ),
            ))
            self._new_traits.append((
                DirectButton(
                    pos=(-0.35, 0, shift),
                    text="",
                    text_fg=SILVER_COL,
                    text_scale=0.032,
                    text_font=base.main_font,  # noqa: F821
                    parent=traits_fr,
                    frameSize=(-0.2, 0.2, -0.05, 0.05),
                    relief=None,
                    command=self._choose_trait,
                    extraArgs=[self._new_traits, self._cur_traits, index],
                ),
                DirectButton(
                    pos=(-0.35, 0, shift - 0.045),
                    text="",
                    text_fg=SILVER_COL,
                    text_scale=0.027,
                    text_font=base.main_font,  # noqa: F821
                    parent=traits_fr,
                    frameSize=(-0.2, 0.2, -0.05, 0.05),
                    relief=None,
                    command=self._choose_trait,
                    extraArgs=[self._new_traits, self._cur_traits, index],
                ),
            ))
            shift -= 0.12

        self._add_but = DirectButton(
            pos=(0, 0, 0),
            text=">",
            text_fg=SILVER_COL,
            parent=traits_fr,
            frameColor=(0, 0, 0, 0),
            relief=None,
            scale=(0.06, 0, 0.07),
            clickSound=base.main_menu.click_snd,  # noqa: F821
        )
        self._praise_but = DirectButton(
            pos=(-0.35, 0, -0.57),
            text=base.labels.DISTINGUISHED[4],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            text_fg=RUST_COL,
            text_shadow=(0, 0, 0, 1),
            frameColor=(0, 0, 0, 0),
            parent=self._list,
            command=self._gen_new_traits,
            scale=(0.04, 0, 0.04),
            clickSound=base.main_menu.click_snd,  # noqa: F821
        )
        self._scold_but = DirectButton(
            pos=(0.3, 0, -0.57),
            text=base.labels.DISTINGUISHED[5],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            text_fg=SILVER_COL,
            text_shadow=(0, 0, 0, 1),
            frameColor=(0, 0, 0, 0),
            parent=self._list,
            scale=(0.04, 0, 0.04),
            clickSound=base.main_menu.click_snd,  # noqa: F821
        )
        DirectButton(
            pos=(-0.02, 0, -0.7),
            text=base.labels.DISTINGUISHED[6],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            text_fg=RUST_COL,
            text_shadow=(0, 0, 0, 1),
            frameColor=(0, 0, 0, 0),
            parent=self._list,
            scale=(0.04, 0, 0.04),
            clickSound=base.main_menu.click_snd,  # noqa: F821
            command=self.hide,
        )

    def _add_trait(self):
        """Add the chosen new trait to character's traits."""
        if not self._new_chosen or self._ind_chosen is None:
            return

        char = self._char_chooser.chosen_item
        if len(char.traits) == 3:
            return

        self._praise_snd.play()
        char.traits.append(self._new_traits[self._ind_chosen][0]["text"])

        for but_pair in self._new_traits:
            but_pair[0]["text"] = ""
            but_pair[1]["text"] = ""

        self._add_but["text_fg"] = SILVER_COL
        self._add_but["command"] = None

        self._need_update = True
        self._ind_chosen = None
        base.char_gui.move_status_label(-1)  # noqa: F821

    def _choose_trait(self, traits, clear_traits, ch_index):
        """Highlight the trait on which the player clicked.

        Args:
            traits (list): List of traits, one of which was chosen.
            clear_traits (list):
                List of traits, which highlight must be dropped.
            ch_index (int): Index of the chosen trait.
        """
        self._ind_chosen = ch_index
        self._new_chosen = traits == self._new_traits

        if self._new_chosen:
            self._add_but["text_fg"] = RUST_COL
            self._add_but["command"] = self._add_trait

            self._scold_but["text_fg"] = SILVER_COL
            self._scold_but["command"] = None
        else:
            self._scold_but["text_fg"] = RUST_COL
            self._scold_but["command"] = self._scold

            self._add_but["text_fg"] = SILVER_COL
            self._add_but["command"] = None

        for index in range(len(traits)):
            clear_traits[index][0]["text_fg"] = SILVER_COL
            clear_traits[index][1]["text_fg"] = SILVER_COL

            if index == ch_index:
                traits[index][0]["text_fg"] = RUST_COL
                traits[index][1]["text_fg"] = RUST_COL
            else:
                traits[index][0]["text_fg"] = SILVER_COL
                traits[index][1]["text_fg"] = SILVER_COL

    def _gen_new_traits(self):
        """Generate new traits on praise.

        One of these traits player can choose
        to add to the character's traits list.
        """
        if base.team.cohesion < 5:  # noqa: F821
            return

        char = self._char_chooser.chosen_item

        pos_traits = list(base.labels.TRAIT_DESC.keys())  # noqa: F821
        for trait in char.traits + char.disabled_traits:
            pos_traits.remove(trait)

        for index in range(3):
            new_trait = take_random(pos_traits)
            self._new_traits[index][0]["text"] = new_trait
            self._new_traits[index][0]["text_fg"] = SILVER_COL
            self._new_traits[index][1][
                "text"] = base.labels.TRAIT_DESC[  # noqa: F821
                    new_trait]
            self._new_traits[index][1]["text_fg"] = SILVER_COL

        base.team.spend_cohesion(4)  # noqa: F821

    def _scold(self):
        """Erase the chosen character's trait."""
        if self._new_chosen or base.team.cohesion < 4:  # noqa: F821
            return

        self._scold_snd.play()
        trait = self._cur_traits[self._ind_chosen][0]["text"]
        char = self._char_chooser.chosen_item
        if trait in char.traits:
            char.traits.remove(trait)
        if trait in char.disabled_traits:
            char.disabled_traits.remove(trait)

        self._ind_chosen = None
        self._need_update = True
        base.char_gui.move_status_label(1)  # noqa: F821

        self._scold_but["text_fg"] = SILVER_COL
        self._scold_but["command"] = None

        base.team.spend_cohesion(4)  # noqa: F821

    def _update_traits(self, task):
        """Update the list of the character's traits."""
        self._cohesion_pts["text"] = str(int(base.team.cohesion))  # noqa: F821

        if self._char_chooser.chosen_item == self._cur_char and not self._need_update:
            return task.again

        self._need_update = False
        self._cur_char = self._char_chooser.chosen_item

        self._scold_but["text_fg"] = SILVER_COL
        self._scold_but["command"] = None

        traits = self._cur_char.traits + self._cur_char.disabled_traits
        self._cur_traits_num["text"] = "{label} ({num}/3):".format(
            label=base.labels.DISTINGUISHED[7],
            num=str(len(traits))  # noqa: F821
        )

        if len(traits) == 3:
            self._praise_but["text_fg"] = SILVER_COL
            self._praise_but["command"] = None
        else:
            self._praise_but["text_fg"] = RUST_COL
            self._praise_but["command"] = self._gen_new_traits

        for index in range(3):
            if index + 1 <= len(traits):
                trait = traits[index]
                self._cur_traits[index][0]["text"] = trait
                self._cur_traits[index][0]["text_fg"] = SILVER_COL
                self._cur_traits[index][1][
                    "text"] = base.labels.TRAIT_DESC[  # noqa: F821
                        trait]
                self._cur_traits[index][1]["text_fg"] = SILVER_COL
            else:
                self._cur_traits[index][0]["text"] = ""
                self._cur_traits[index][0]["text_fg"] = SILVER_COL
                self._cur_traits[index][1]["text"] = ""
                self._cur_traits[index][1]["text_fg"] = SILVER_COL

        return task.again

    def hide(self):
        """Hide the GUI."""
        if self.is_shown:
            taskMgr.remove("update_traits_ctrl")  # noqa: F821
            base.char_gui.clear_char_info()  # noqa: F821
            self._list.hide()
            self.is_shown = False
            taskMgr.doMethodLater(  # noqa: F821
                0.07,
                self._close_snd.play,
                "play_close_snd",
                extraArgs=[])

    def show(self):
        """Show the GUI."""
        if (self.is_shown or base.world.outings_mgr.gui_is_shown  # noqa: F821
                or base.world.rails_scheme.is_shown  # noqa: F821
            ):
            return

        self._open_snd.play()
        self.is_shown = True

        char_id = base.char_gui.char.id  # noqa: F821
        base.common_ctrl.deselect()  # noqa: F821

        self._char_chooser.prepare(
            self._list,
            (-0.25, 0, 0.08),
            base.team.chars,  # noqa: F821
            list(base.team.chars.keys()).index(char_id),  # noqa: F821
        )
        self._list.show()
        taskMgr.doMethodLater(  # noqa: F821
            0.25, self._update_traits, "update_traits_ctrl")
Ejemplo n.º 4
0
class GuiUnitInfo:
    def __init__(self, offset, parent, unit_type, default_hp, hp, default_ap, ap):
            
        self.offset = offset
        self.frame = DirectFrame(   relief = DGG.FLAT
                                  , scale = 1
                                  , frameSize = (-0.5, 0.5, 0, -0.5)
                                  , parent = parent )
        self.frame.setBillboardPointEye()
        self.frame.setLightOff()
        self.frame.setBin("fixed", 40)
        self.frame.setDepthTest(False)
        self.frame.setDepthWrite(False)
        
        fixedWidthFont = loader.loadFont(GUI_FONT)#@UndefinedVariable        
        #fixedWidthFont.setPixelsPerUnit(60)
        #fixedWidthFont.setRenderMode(fontt.RMSolid)
        if not fixedWidthFont.isValid():
            print "pandaInteractiveConsole.py :: could not load the defined font %s" % str(self.font)
            fixedWidthFont = DGG.getDefaultFont()
        
        self.label = OnscreenText( parent = self.frame
                              , text = ""
                              , pos = (offset.getX(),offset.getZ()+0.1)
                              , align=TextNode.ACenter
                              , mayChange=True
                              , scale=0.1
                              , fg = (1,0,0,1)
                              #, shadow = (0, 0, 0, 1)
                              #, frame = (200,0,0,1) 
                              )
        self.label.setFont( fixedWidthFont )
        #self.label.setLightOff()

        self.all_icons = {}
        self.visible_icons = {}
        self.addIcon("overwatch")
        self.addIcon("set_up")
        
        self.ap_bar = DirectWaitBar(parent = self.frame
                                  , text = ""
                                  , range = default_ap
                                  , value = ap
                                  , pos = (offset.getX()+0.08,0,offset.getZ()-0.27)
                                  , barColor = (0,0,1,1)
                                  , frameColor = (0,0,0.5,0.2)
                                  , scale = (0.3,0.5,0.3))
        
        self.hp_bar = DirectWaitBar(parent = self.frame
                                  , text = ""
                                  , range = default_hp
                                  , value = hp
                                  , pos = (offset.getX()+0.08,0,offset.getZ()-0.2)
                                  , barColor = (0,1,0,1)
                                  , frameColor = (1,0,0,0.9)
                                  , scale = (0.3,0.5,0.3))
        
        self.insignia = OnscreenImage(parent = self.frame
                                            ,image = "unit_" + unit_type + "_big_transparent_32.png"
                                            #,pos = (offset.getX(),0,offset.getZ()+0.14)
                                            , pos = (offset.getX() - 0.31,0,offset.getZ()-0.23)
                                            ,scale = 0.09)
        self.insignia.setTransparency(TransparencyAttrib.MAlpha)

    def addIcon(self, name):
        self.all_icons[name] = OnscreenImage(parent = self.frame
                                            ,image = name + "_icon.png"
                                           #,pos = offset + (0,0,-0.1)
                                            ,scale = 0.08)
        
        self.all_icons[name].setTransparency(TransparencyAttrib.MAlpha)
        self.all_icons[name].hide()
        
    def write(self, text):
        text = ""
        self.label.setText(text)
        
    def redraw(self):
        return

    def remove(self):
        self.frame.remove()
        
    def reparentTo(self, parent):
        self.frame.reparentTo(parent)
        
    def hide(self):
        self.label.hide()
        
    def show(self):
        self.label.show()
    
    def refreshBars(self, hp, ap):
        self.ap_bar['value'] = ap
        self.hp_bar['value'] = hp
        self.ap_bar.setValue()
        self.hp_bar.setValue()
        
    def refreshIcons(self):
        count = len(self.visible_icons)
        start_pos =  (1 - count) * 0.25 / 2
        for icon in self.all_icons:
            if icon in self.visible_icons:
                self.visible_icons[icon].setPos(self.offset + (start_pos, 0, -0.08))
                self.visible_icons[icon].show()
                start_pos += 0.21
            else:
                self.all_icons[icon].hide()
            
    def hideOverwatch(self):
        if "overwatch" in self.visible_icons:
            self.visible_icons.pop("overwatch")
        self.refreshIcons()

    def showOverwatch(self):
        self.visible_icons["overwatch"] = self.all_icons["overwatch"]
        self.refreshIcons()
    
    def hideSetUp(self):
        if "set_up" in self.visible_icons:
            self.visible_icons.pop("set_up")
        self.refreshIcons()

    def showSetUp(self):
        self.visible_icons["set_up"] = self.all_icons["set_up"]
        self.refreshIcons()
Ejemplo n.º 5
0
class CityGUI:
    """City GUI.

    Includes several services: healing and regaining energy of the
    player characters, recruiting new characters, repairing the
    locomotive, buying the locomotive upgrades.
    """
    def __init__(self):
        self._temp_wids = []
        self._recruits = []
        self._reward_fr = None
        self.visit_num = 1

        self._amb_snd = loader.loadSfx(
            "sounds/hangar_ambient.ogg")  # noqa: F821
        self._amb_snd.setVolume(0)
        self._amb_snd.setLoop(True)

        self._coins_s_snd = loader.loadSfx(
            "sounds/GUI/coins_short.ogg")  # noqa: F821
        self._coins_l_snd = loader.loadSfx(
            "sounds/GUI/coins_long.ogg")  # noqa: F821
        self._toot_snd = loader.loadSfx("sounds/train/toot1.ogg")  # noqa: F821
        self._add_upgrade_snd = loader.loadSfx(  # noqa: F821
            "sounds/GUI/install_upgrade.ogg")
        self.write_snd = loader.loadSfx("sounds/GUI/write.ogg")  # noqa: F821

        self._fr = DirectFrame(
            parent=base.a2dTopLeft,  # noqa: F821
            frameSize=(-0.35, 0.35, -0.4, 0.7),
            pos=(0.85, 0, -0.82),
            frameTexture=GUI_PIC + "metal1.png",
            state=DGG.NORMAL,
        )
        self._fr.setTransparency(TransparencyAttrib.MAlpha)
        self._fr.hide()

        DirectLabel(  # Services
            parent=self._fr,
            text=base.labels.CITY[0],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.045,
            text_fg=RUST_COL,
            pos=(0, 0, 0.62),
        )
        self._party_but = DirectButton(  # Party
            parent=self._fr,
            text_scale=0.035,
            text_fg=SILVER_COL,
            text=base.labels.CITY[1],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            relief=None,
            command=self._show_party,
            extraArgs=[0.56],
            pos=(-0.1, 0, 0.56),
            clickSound=base.main_menu.click_snd,  # noqa: F821
        )
        base.main_menu.bind_button(self._party_but)  # noqa: F821

        self._train_but = DirectButton(  # Train
            parent=self._fr,
            text_scale=0.035,
            text_fg=RUST_COL,
            text=base.labels.CITY[2],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            relief=None,
            command=self._show_train,
            extraArgs=[0.56],
            pos=(0.1, 0, 0.56),
            clickSound=base.main_menu.click_snd,  # noqa: F821
        )
        base.main_menu.bind_button(self._train_but)  # noqa: F821

        base.main_menu.bind_button(  # noqa: F821
            DirectButton(  # Exit city
                parent=self._fr,
                pos=(-0.205, 0, -0.35),
                text_fg=RUST_COL,
                text=base.labels.CITY[3],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                relief=None,
                text_scale=0.035,
                command=self._exit_city,
            ))
        base.main_menu.bind_button(  # noqa: F821
            DirectButton(  # Turn around and exit
                parent=self._fr,
                pos=(0.1, 0, -0.35),
                text_fg=RUST_COL,
                text=base.labels.CITY[4],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                relief=None,
                text_scale=0.035,
                command=self._exit_city,
                extraArgs=[True],
            ))

    def _show_train(self, z_coor):
        """Show the locomotive management GUI tab.

        Args:
            z_coor (float): Z-coordinate for widgets.
        """
        clear_wids(self._temp_wids)

        self._party_but["text_fg"] = RUST_COL
        self._train_but["text_fg"] = SILVER_COL

        z_coor -= 0.07
        self._temp_wids.append(
            DirectLabel(  # Locomotive
                parent=self._fr,
                text=base.labels.CITY[5],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                frameSize=(0.1, 0.1, 0.1, 0.1),
                text_scale=0.035,
                text_align=TextNode.ALeft,
                text_fg=RUST_COL,
                pos=(-0.3, 0, z_coor),
            ))
        z_coor -= 0.08
        self._temp_wids.append(
            DirectLabel(  # Repair
                parent=self._fr,
                frameColor=(0, 0, 0, 0.3),
                text_fg=SILVER_COL,
                text=base.labels.CITY[6],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_align=TextNode.ALeft,
                text_scale=0.03,
                pos=(-0.25, 0, z_coor),
            ))
        self._temp_wids.append(
            DirectButton(
                parent=self._fr,
                pos=(-0.05, 0, z_coor + 0.015),
                text_fg=SILVER_COL,
                text="+50\n10$",
                scale=(0.075, 0, 0.075),
                relief=None,
                text_scale=0.45,
                command=self._repair,
                extraArgs=[50],
            ))
        self._temp_wids.append(
            DirectButton(
                parent=self._fr,
                pos=(0.07, 0, z_coor + 0.015),
                text_fg=SILVER_COL,
                text="+200\n40$",
                scale=(0.075, 0, 0.075),
                relief=None,
                text_scale=0.45,
                command=self._repair,
                extraArgs=[200],
            ))

        z_coor -= 0.09
        self._temp_wids.append(
            DirectLabel(  # Upgrade
                parent=self._fr,
                text=base.labels.CITY[7],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_align=TextNode.ALeft,
                frameSize=(0.1, 0.1, 0.1, 0.1),
                text_scale=0.035,
                text_fg=RUST_COL,
                pos=(-0.3, 0, z_coor),
            ))
        up_desc = DirectLabel(
            parent=self._fr,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.03,
            text_fg=SILVER_COL,
            pos=(-0.1, 0, z_coor - 0.14),
        )
        self._temp_wids.append(up_desc)

        up_cost = DirectLabel(
            parent=self._fr,
            text="",
            frameSize=(0.1, 0.1, 0.1, 0.1),
            text_scale=0.035,
            text_fg=SILVER_COL,
            pos=(0.23, 0, z_coor - 0.17),
        )
        self._temp_wids.append(up_cost)

        but = DirectButton(  # Purchase
            parent=self._fr,
            pos=(0.2, 0, z_coor - 0.3),
            text_fg=RUST_COL,
            text=base.labels.CITY[8],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            relief=None,
            text_scale=0.035,
            command=self._purchase_upgrade,
        )
        self._temp_wids.append(but)
        base.main_menu.bind_button(but)  # noqa: F821

        z_coor -= 0.05
        self._up_chooser = UpgradeChooser(up_desc, up_cost)
        self._up_chooser.prepare(
            self._fr,
            (0, 0, z_coor),
            base.train.possible_upgrades(self.visit_num),  # noqa: F821
        )
        self._temp_wids.append(self._up_chooser)

    def _purchase_upgrade(self):
        """Buy the chosen upgrade and install it on to the locomotive."""
        upgrade = self._up_chooser.chosen_item
        if upgrade is None or not base.res_gui.check_enough_money(  # noqa: F821
                int(upgrade["cost"][:-1])):
            return

        base.main_menu.click_snd.play()  # noqa: F821
        self._add_upgrade_snd.play()
        base.dollars -= int(upgrade["cost"][:-1])  # noqa: F821

        base.train.install_upgrade(upgrade)  # noqa: F821
        self._up_chooser.pop_upgrade(upgrade["name"])

    def _show_party(self, shift):
        """Show units management tab.

        Args:
            shift (float): Z-coordinate.
        """
        clear_wids(self._temp_wids)

        self._party_but["text_fg"] = SILVER_COL
        self._train_but["text_fg"] = RUST_COL

        shift -= 0.07
        # the crew GUI
        self._temp_wids.append(
            DirectLabel(  # Crew
                parent=self._fr,
                text=base.labels.CITY[9],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_align=TextNode.ALeft,
                frameSize=(0.1, 0.1, 0.1, 0.1),
                text_scale=0.035,
                text_fg=RUST_COL,
                pos=(-0.3, 0, shift),
            ))

        self._char_chooser = CharacterChooser()
        self._char_chooser.prepare(
            self._fr,
            (0, 0, 0.45),
            base.team.chars  # noqa: F821
        )
        self._temp_wids.append(self._char_chooser)

        shift -= 0.14
        self._temp_wids.append(
            DirectLabel(  # Health
                parent=self._fr,
                frameColor=(0, 0, 0, 0.3),
                text_fg=SILVER_COL,
                text=base.labels.CHARACTERS[2],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_scale=0.03,
                pos=(-0.2, 0, shift),
            ))
        self._temp_wids.append(
            DirectButton(
                parent=self._fr,
                pos=(-0.05, 0, shift + 0.02),
                text_fg=SILVER_COL,
                text="+10\n10$",
                scale=(0.075, 0, 0.075),
                relief=None,
                text_scale=0.45,
                command=self._heal,
                extraArgs=[10],
            ))
        self._temp_wids.append(
            DirectButton(
                parent=self._fr,
                pos=(0.07, 0, shift + 0.02),
                text_fg=SILVER_COL,
                text="+50\n50$",
                scale=(0.075, 0, 0.075),
                relief=None,
                text_scale=0.45,
                command=self._heal,
                extraArgs=[50],
            ))
        shift -= 0.1
        self._temp_wids.append(
            DirectLabel(  # Energy
                parent=self._fr,
                frameColor=(0, 0, 0, 0.3),
                text_fg=SILVER_COL,
                text=base.labels.CHARACTERS[3],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_scale=0.03,
                pos=(-0.2, 0, shift),
            ))
        self._temp_wids.append(
            DirectButton(
                parent=self._fr,
                pos=(-0.05, 0, shift + 0.02),
                text_fg=SILVER_COL,
                text="+10\n5$",
                scale=(0.075, 0, 0.075),
                relief=None,
                text_scale=0.45,
                command=self._rest,
                extraArgs=[10],
            ))
        self._temp_wids.append(
            DirectButton(
                parent=self._fr,
                pos=(0.07, 0, shift + 0.02),
                text_fg=SILVER_COL,
                text="+50\n25$",
                scale=(0.075, 0, 0.075),
                relief=None,
                text_scale=0.45,
                command=self._rest,
                extraArgs=[50],
            ))
        shift -= 0.08
        self._temp_wids.append(
            DirectButton(  # Leave unit
                parent=self._fr,
                pos=(0.2, 0, shift),
                text_fg=SILVER_COL,
                text=base.labels.CITY[12],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                scale=(0.075, 0, 0.075),
                relief=None,
                text_scale=0.45,
                command=self._send_away,
            ))
        shift -= 0.08
        # recruits gui
        self._temp_wids.append(
            DirectLabel(  # Recruits
                parent=self._fr,
                text=base.labels.CITY[10],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_align=TextNode.ALeft,
                frameSize=(0.1, 0.1, 0.1, 0.1),
                text_scale=0.035,
                text_fg=RUST_COL,
                pos=(-0.3, 0, shift),
            ))

        shift -= 0.13
        hire_but = DirectButton(  # Hire unit
            parent=self._fr,
            pos=(0.2, 0, shift),
            text_fg=SILVER_COL,
            text=base.labels.CITY[13],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            scale=(0.075, 0, 0.075),
            relief=None,
            text_scale=0.45,
            command=self._hire,
        )
        self._temp_wids.append(hire_but)

        self._recruit_chooser = RecruitChooser(hire_but)
        self._recruit_chooser.prepare(self._fr, (0, 0, 0.05), self._recruits)
        self._temp_wids.append(self._recruit_chooser)

        shift -= 0.08
        # expendable resources
        self._temp_wids.append(
            DirectLabel(  # Resources
                parent=self._fr,
                text=base.labels.CITY[11],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_align=TextNode.ALeft,
                frameSize=(0.1, 0.1, 0.1, 0.1),
                text_scale=0.035,
                text_fg=RUST_COL,
                pos=(-0.3, 0, shift),
            ))
        shift -= 0.12
        buy_res_but = DirectButton(  # Buy
            parent=self._fr,
            pos=(0.08, 0, shift),
            text_fg=SILVER_COL,
            text=base.labels.CITY[15],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            scale=(0.075, 0, 0.075),
            relief=None,
            text_scale=0.45,
            command=self._buy_supply,
        )
        self._temp_wids.append(buy_res_but)

        sell_res_but = DirectButton(  # Sell
            parent=self._fr,
            pos=(-0.08, 0, shift),
            text_fg=SILVER_COL,
            text=base.labels.CITY[14],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            scale=(0.075, 0, 0.075),
            relief=None,
            text_scale=0.45,
            command=self._sell_supply,
        )
        self._temp_wids.append(sell_res_but)

        self._res_chooser = ResourceChooser(buy_res_but, sell_res_but)
        self._res_chooser.prepare(
            self._fr,
            (0, 0, -0.165),
            {
                base.labels.RESOURCES[1]: "medicine_boxes",  # noqa: F821
                base.labels.RESOURCES[5]: "stimulators",  # noqa: F821
                base.labels.RESOURCES[3]: "smoke_filters",  # noqa: F821
            },
        )
        self._temp_wids.append(self._res_chooser)

    def _buy_supply(self):
        """Buy the chosen resource."""
        if not base.res_gui.check_enough_money(  # noqa: F821
                self._res_chooser.chosen_resource_cost):
            return

        random.choice((self._coins_s_snd, self._coins_l_snd)).play()

        base.dollars -= self._res_chooser.chosen_resource_cost  # noqa: F821
        base.plus_resource(self._res_chooser.chosen_item, 1)  # noqa: F821

    def _clear(self, turn_around):
        """Remove hangar scene and hide city GUI.

        Args:
            turn_around (bool): True, if the Train should be turned around.
        """
        self._fr.hide()
        base.char_gui.clear_char_info()  # noqa: F821
        base.world.unload_hangar_scene(turn_around)  # noqa: F821

    def _sell_supply(self):
        """Sell the chosen resource."""
        if not base.resource(self._res_chooser.chosen_item):  # noqa: F821
            return

        random.choice((self._coins_s_snd, self._coins_l_snd)).play()

        base.dollars += self._res_chooser.chosen_resource_cost  # noqa: F821
        base.plus_resource(self._res_chooser.chosen_item, -1)  # noqa: F821

    def _exit_city(self, turn_around=False):
        """Exit the current city.

        Hide city GUI, remove the hangar scene,
        return the Train back on railway.

        Args:
            turn_around (bool): True, if the Train should be turned around.
        """
        self._toot_snd.play()
        self.visit_num += 1
        taskMgr.remove("increase_city_snd")  # noqa: F821
        base.train.clear_upgrade_preview()  # noqa: F821

        taskMgr.doMethodLater(0.3, self._dec_amb_snd,
                              "decrease_city_snd")  # noqa: F821
        taskMgr.doMethodLater(  # noqa: F821
            0.1,
            base.effects_mgr.fade_out_screen,
            "fade_out_screen"  # noqa: F821
        )
        taskMgr.doMethodLater(  # noqa: F821
            3.1,
            self._clear,
            "clear_city_gui",
            extraArgs=[turn_around])
        taskMgr.doMethodLater(  # noqa: F821
            2,
            base.train.resume_smoke,
            "resume_train_smoke"  # noqa: F821
        )

    def _send_away(self):
        """Send the chosen unit away.

        The unit will leave the crew and can never be restored.
        """
        if len(base.team.chars) == 1:  # noqa: F821
            return

        self.write_snd.play()
        char = self._char_chooser.chosen_item
        char.leave()
        taskMgr.doMethodLater(  # noqa: F821
            0.1,
            self._char_chooser.leave_unit,
            char.id + "_leave",
            extraArgs=[char.id])

    def _hire(self):
        """Hire the chosen unit."""
        cost = self._recruit_chooser.chosen_recruit_cost
        if not base.res_gui.check_enough_money(cost):  # noqa: F821
            return

        char = self._recruit_chooser.chosen_item
        if char is None:
            return

        if not base.res_gui.check_has_cell():  # noqa: F821
            return

        self.write_snd.play()
        base.dollars -= cost  # noqa: F821

        base.team.chars[char.id] = char  # noqa: F821
        self._recruit_chooser.leave_unit(char.id)

        char.prepare()
        base.train.place_recruit(char)  # noqa: F821
        base.res_gui.update_chars()  # noqa: F821
        if not char.current_part.name == "part_rest":
            char.rest()

    def _repair(self, value):
        """Repair the locomotive.

        Spends money.

        Args:
            value (int):
                Points of the Train durability to repair.
        """
        spent = 10 if value == 50 else 40
        if not base.res_gui.check_enough_money(spent):  # noqa: F821
            return

        random.choice((self._coins_s_snd, self._coins_l_snd)).play()

        base.train.get_damage(-value)  # noqa: F821
        base.dollars -= spent  # noqa: F821

    def _heal(self, value):
        """Heal the chosen character.

        Spends money.

        Args:
            value (int): Points to heal.
        """
        if not base.res_gui.check_enough_money(value):  # noqa: F821
            return

        random.choice((self._coins_s_snd, self._coins_l_snd)).play()

        self._char_chooser.chosen_item.health += value
        base.dollars -= value  # noqa: F821

    def _rest(self, value):
        """Regain energy of the chosen character.

        Spends money.

        Args:
            value (int): Points to regain.
        """
        spent = 5 if value == 10 else 25
        if not base.res_gui.check_enough_money(spent):  # noqa: F821
            return

        random.choice((self._coins_s_snd, self._coins_l_snd)).play()

        self._char_chooser.chosen_item.energy += value
        base.dollars -= spent  # noqa: F821

    def _inc_amb_snd(self, task):
        """Increase hangar ambient sound."""
        cur_vol = round(self._amb_snd.getVolume(), 2)
        if cur_vol == 1:
            return task.done

        self._amb_snd.setVolume(cur_vol + 0.05)
        return task.again

    def _dec_amb_snd(self, task):
        """Decrease hangar ambient sound."""
        cur_vol = round(self._amb_snd.getVolume(), 2)
        if cur_vol == 0:
            self._amb_snd.stop()
            return task.done

        self._amb_snd.setVolume(cur_vol - 0.05)
        return task.again

    def _show_headhunting_reward(self):
        """Show a reward GUI.

        When getting into a city, player gains money as a reward
        for destroying enemies. Money amount depends on what
        enemies were destroyed.
        """
        heads_cost = {
            "MotoShooter": 5,
            "BrakeThrower": 5,
            "StunBombThrower": 10,
            "DodgeShooter": 25,
            "Kamikaze": 15,
        }
        if not base.heads:  # noqa: F821
            return

        self._reward_fr = DirectFrame(
            frameSize=(-0.3, 0.3, -0.45, 0.45),
            frameTexture="gui/tex/paper1.png",
            state=DGG.NORMAL,
            pos=(0.9, 0, -0.15),
        )
        self._reward_fr.setDepthTest(False)
        self._reward_fr.setTransparency(TransparencyAttrib.MAlpha)

        heads_list = ""
        costs_list = ""
        total = 0
        for head, num in base.heads.items():  # noqa: F821
            heads_list += head + " x" + str(num) + "\n"
            costs_list += str(num * heads_cost[head]) + "$\n"
            total += num * heads_cost[head]

        reward_desc = DirectLabel(
            parent=self._reward_fr,
            frameColor=(0, 0, 0, 0),
            frameSize=(-0.3, 0.3, -0.1, 0.1),
            text=base.labels.CITY[16]  # noqa: F821
            + "\n" * 13 + base.labels.CITY[17]  # noqa: F821
            + str(total) + "$",
            text_font=base.main_font,  # noqa: F821
            text_scale=0.03,
            pos=(0, 0, 0.35),
        )
        heads_list = DirectLabel(
            parent=self._reward_fr,
            frameColor=(0, 0, 0, 0),
            frameSize=(-0.3, 0.3, -0.1, 0.1),
            text=heads_list,
            text_scale=0.03,
            text_align=TextNode.ALeft,
            pos=(-0.21, 0, 0.08),
        )
        costs_list = DirectLabel(
            parent=self._reward_fr,
            frameColor=(0, 0, 0, 0),
            frameSize=(-0.3, 0.3, -0.1, 0.1),
            text=costs_list,
            text_scale=0.03,
            text_align=TextNode.ALeft,
            pos=(0.16, 0, 0.08),
        )
        DirectButton(
            parent=self._reward_fr,
            pos=(0, 0, -0.38),
            text="Acquire",
            text_fg=RUST_COL,
            text_shadow=(0, 0, 0, 1),
            frameColor=(0, 0, 0, 0),
            command=self._acquire_reward,
            extraArgs=[total, reward_desc, heads_list, costs_list],
            scale=(0.04, 0, 0.04),
        )

    def _acquire_reward(self, dollars, reward_desc, heads_list, costs_list):
        """Claim a reward, given by a city for destroying enemies.

        Args:
            dollars (int): Gained dollars amount.
            reward_desc (direct.gui.DirectGui.DirectLabel):
                Reward description widget.
            heads_list (direct.gui.DirectGui.DirectLabel):
                List of taken heads widget.
            costs_list (direct.gui.DirectGui.DirectLabel):
                Money got for the heads list widget.
        """
        self._coins_l_snd.play()
        base.dollars += dollars  # noqa: F821

        if base.helped_children:  # noqa: F821
            reward_desc["text"] = base.labels.CITY[18]  # noqa: F821
            base.train.get_damage(-250)  # noqa: F821
            heads_list.destroy()
            costs_list.destroy()
            base.helped_children = False  # noqa: F821
            return

        self._reward_fr.destroy()
        self._reward_fr = None
        base.clear_heads()  # noqa: F821

    def show(self):
        """Show city GUI."""
        self._amb_snd.play()
        taskMgr.doMethodLater(0.3, self._inc_amb_snd,
                              "increase_city_snd")  # noqa: F821
        self._recruits = base.team.gen_recruits()  # noqa: F821
        self._fr.show()
        self._show_train(0.56)

        self._show_headhunting_reward()
Ejemplo n.º 6
0
class RailsScheme:
    """Rails scheme GUI.

    Represents the railways map, which can be used by
    players to choose the right way across the game world.

    Args:
        world_map (list): All the world blocks.
    """
    def __init__(self, world_map):
        self.is_shown = False
        self._temp_wids = []

        self._open_snd = loader.loadSfx("sounds/GUI/paper1.ogg")  # noqa: F821
        self._close_snd = loader.loadSfx("sounds/GUI/paper2.ogg")  # noqa: F821
        self._world_map = world_map

        self._list = DirectFrame(
            frameSize=(-1.2, 1.2, -0.6, 0.6),
            frameTexture="gui/tex/paper2.png",
            state=DGG.NORMAL,
        )
        self._list.setDepthTest(False)
        self._list.setTransparency(TransparencyAttrib.MAlpha)
        self._list.hide()

        DirectLabel(  # Silewer Railways Scheme
            parent=self._list,
            text=base.labels.SCHEME[0],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.2, 0.2, 0.2, 0.2),
            text_scale=0.035,
            pos=(0, 0, 0.5),
        )
        self._scheme = DirectFrame(
            parent=self._list,
            frameSize=(-1.1, 1.1, -0.3, 0.3),
            frameTexture="gui/tex/world_scheme.png",
        )
        self._scheme.setTransparency(TransparencyAttrib.MAlpha)

        self._arrow = DirectFrame(
            parent=self._scheme,
            frameSize=(-0.02, 0.02, -0.02, 0.02),
            frameTexture="gui/tex/train_dir.png",
            pos=(-0.96, 0, 0.07),
        )
        self._build_legend()

    def _build_legend(self):
        """Build the scheme legend GUI."""
        lab_opts = {
            "parent": self._list,
            "text_scale": 0.033,
            "frameColor": (0, 0, 0, 0),
            "frameSize": (-0.1, 0.1, -0.1, 0.1),
        }
        DirectLabel(  # Legend
            text=base.labels.SCHEME[1],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            text_align=TextNode.ALeft,
            pos=(-1, 0, -0.35),
            **lab_opts,
        )
        DirectFrame(
            parent=self._scheme,
            frameTexture="gui/tex/city.png",
            frameSize=(-0.04, 0.04, -0.04, 0.04),
            pos=(-0.39, 0, -0.41),
        )
        DirectLabel(  # city
            text=base.labels.SCHEME[2],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            pos=(-0.3, 0, -0.42),
            **lab_opts,
        )
        DirectFrame(
            parent=self._scheme,
            frameTexture="gui/tex/dash.png",
            frameSize=(-0.004, 0.004, -0.06, 0.06),
            frameColor=(0, 0, 0, 0.2),
            pos=(0.09, 0, -0.37),
        ).setR(90)

        DirectLabel(
            text=base.labels.SCHEME[3],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            pos=(0.29, 0, -0.38),
            **lab_opts,
        )
        DirectFrame(
            parent=self._scheme,
            frameColor=(0.71, 0.25, 0.05, 0.2),
            frameSize=(-0.06, 0.06, -0.02, 0.02),
            pos=(0.09, 0, -0.45),
        )
        DirectLabel(
            text=base.labels.SCHEME[4],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            pos=(0.26, 0, -0.46),
            **lab_opts,
        )

    def _fill_branches(self):
        """Paint railway branches on the railways scheme."""
        for branch in base.world.branches:  # noqa: F821
            start = -0.96 + self._world_map[branch["start"]].id * 0.0032
            self._temp_wids.append(
                DirectFrame(
                    parent=self._scheme,
                    frameTexture="gui/tex/dash.png",
                    frameSize=(-0.004, 0.004, -0.1, 0.1),
                    frameColor=(0, 0, 0, 0.2),
                    pos=(start, 0, 0.1 if branch["side"] == "l" else -0.1),
                ))
            end = -0.96 + self._world_map[branch["end"]].id * 0.0032
            self._temp_wids.append(
                DirectFrame(
                    parent=self._scheme,
                    frameTexture="gui/tex/dash.png",
                    frameSize=(-0.004, 0.004, -0.1, 0.1),
                    frameColor=(0, 0, 0, 0.2),
                    pos=(end, 0, 0.1 if branch["side"] == "l" else -0.1),
                ))

            x_coor = (start + end) / 2

            horiz = DirectFrame(
                parent=self._scheme,
                frameTexture="gui/tex/dash.png",
                frameSize=(-0.004, 0.004, -(x_coor - start), end - x_coor),
                frameColor=(0, 0, 0, 0.2),
                pos=(x_coor, 0, 0.2 if branch["side"] == "l" else -0.2),
            )
            horiz.setR(90)
            self._temp_wids.append(horiz)

            outs = ""
            for block in branch["blocks"][1:-1]:
                if block.outing_available:
                    outs += block.outing_available[0]

                if block.is_station:
                    outs += "i"

            if outs:
                outs = outs.lower()
                self._temp_wids.append(
                    DirectLabel(
                        parent=self._scheme,
                        text=outs,
                        text_scale=0.035,
                        text_bg=(0, 0, 0, 0),
                        text_fg=(0, 0, 0, 0.5),
                        frameColor=(0, 0, 0, 0),
                        pos=(x_coor, 0,
                             0.25 if branch["side"] == "l" else -0.27),
                    ))

    def _fill_scheme(self):
        """Fill the railways scheme with the world data.

        Shows cities, outings and railway branches on the scheme.
        """
        self._fill_branches()

        outs = None
        cities = 0
        for block in self._world_map[:601]:
            if block.id % 100 == 0:
                if outs:
                    self._temp_wids.append(
                        DirectLabel(
                            parent=self._scheme,
                            text=outs,
                            text_scale=0.035,
                            text_bg=(0, 0, 0, 0),
                            frameColor=(0, 0, 0, 0),
                            pos=(-0.96 + (block.id - 50) * 0.0032, 0, -0.1),
                        ))
                outs = ""

            if block.outing_available:
                outs += block.outing_available[0].lower()

            if block.is_station:
                outs += "i"

            if block.is_city:
                self._temp_wids.append(
                    DirectFrame(
                        parent=self._scheme,
                        frameTexture="gui/tex/city.png",
                        frameSize=(-0.04, 0.04, -0.04, 0.04),
                        pos=(-0.96 + block.id * 0.0032, 0, 0),
                    ))
                self._temp_wids.append(
                    DirectLabel(
                        parent=self._scheme,
                        text=base.labels.CITY_NAMES[cities],  # noqa: F821
                        text_font=base.main_font,  # noqa: F821
                        text_scale=0.032,
                        text_bg=(0, 0, 0, 0),
                        frameColor=(0, 0, 0, 0),
                        pos=(-0.96 + block.id * 0.0032, 0, 0.1),
                    ))
                cities += 1

        self._temp_wids.append(
            DirectFrame(
                parent=self._scheme,
                frameColor=(0.71, 0.25, 0.05, 0.2),
                frameSize=(
                    0,
                    base.world.stench_step * 0.0032,  # noqa: F821
                    -0.22,
                    0.22,
                ),
                pos=(-0.96, 0, 0),
            ))

    def _update_arrow(self, task):
        """Update the Train position on the scheme."""
        blocks = base.world.current_blocks  # noqa: F821
        if blocks and blocks[0] != -1:

            z_shift = 0
            if not base.world.is_near_fork:  # noqa: F821
                if base.world.current_block.branch == "l":  # noqa: F821
                    z_shift = 0.155
                elif base.world.current_block.branch == "r":  # noqa: F821
                    z_shift = -0.295

            if blocks[0] < 600:
                x = -0.96 + blocks[0] * 0.0032
            else:
                x = self._arrow.getX()

            self._arrow.setPos(x, 0, 0.07 + z_shift)

            if blocks[0] < blocks[1]:
                self._arrow["frameTexture"] = "gui/tex/train_dir.png"
            else:
                self._arrow["frameTexture"] = "gui/tex/train_dir_op.png"

        task.delayTime = 5
        return task.again

    def show(self):
        """Show/hide railways scheme GUI."""
        if (self.is_shown or base.world.outings_mgr.gui_is_shown  # noqa: F821
                or base.traits_gui.is_shown  # noqa: F821
            ):
            self._close_snd.play()
            self._list.hide()
            taskMgr.remove("update_scheme_arrow")  # noqa: F821

            clear_wids(self._temp_wids)
        else:
            if base.world.is_on_et:  # noqa: F821
                return

            self._open_snd.play()
            taskMgr.doMethodLater(  # noqa: F821
                0.2, self._update_arrow, "update_scheme_arrow")
            self._fill_scheme()
            self._list.show()
            base.char_gui.clear_char_info(True)  # noqa: F821

        self.is_shown = not self.is_shown
Ejemplo n.º 7
0
class OutingsGUI:
    """Outing dialogs GUI."""
    def __init__(self):
        self.is_shown = False
        self._char_chooser = None
        self._outing_widgets = []
        self._assignees = []
        self._char_buttons = {}
        self._blink_step = 0

        self._outing_snd = loader.loadSfx(
            "sounds/outing_event.ogg")  # noqa: F821

        self._upcome_ico = DirectFrame(
            frameSize=(-0.1, 0.1, -0.1, 0.1),
            pos=(0, 0, 0.8),
            frameTexture="gui/tex/looting.png",
        )
        self._upcome_ico.setTransparency(TransparencyAttrib.MAlpha)
        self._upcome_ico.hide()

        self._upcome_text = DirectLabel(
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.4, 0.4, 0.4, 0.4),
            text_scale=0.04,
            text_fg=SILVER_COL,
            text_bg=(0, 0, 0, 0.5),
            pos=(0, 0, 0.65),
        )
        self._upcome_text.hide()

        self._list = DirectFrame(
            frameSize=(-0.73, 0.73, -0.9, 0.9),
            frameTexture="gui/tex/paper1.png",
            state=DGG.NORMAL,
        )
        self._list.setDepthTest(False)
        self._list.setTransparency(TransparencyAttrib.MAlpha)
        self._list.hide()

        self._name = DirectLabel(
            parent=self._list,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.4, 0.4, 0.4, 0.4),
            text_scale=0.047,
            pos=(-0.4, 0, 0.7),
        )
        self._type = DirectLabel(
            parent=self._list,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.4, 0.4, 0.4, 0.4),
            text_scale=0.032,
            pos=(-0.13, 0, 0.699),
        )
        self._desc = DirectLabel(
            parent=self._list,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.6, 0.6, 0.6, 0.6),
            text_scale=0.037,
            pos=(0, 0, 0.55),
        )

    def _assign_for_outing(self, to_send_wid, assignees):
        """Assign the chosen character for the outing.

        Args:
            to_send_wid (direct.gui.DirectLabel.DirectLabel):
                Widget with number of assigned characters.
            assignees (int): Assignees limit.
        """
        char = base.common_ctrl.chosen_char  # noqa: F821
        if char is None or char in self._assignees or len(
                self._assignees) == assignees:
            return

        self._assignees.append(char)
        self._char_buttons[char.id].setX(0.35)

        to_send_wid["text"] = base.labels.OUTINGS_GUI[0].format(  # noqa: F821
            cur_as=str(len(self._assignees)),
            max_as=str(assignees))

    def _unassign_for_outing(self, to_send_wid, assignees):
        """Exclude the chosen character from the outing.

        Args:
            to_send_wid (direct.gui.DirectLabel.DirectLabel):
                Widget with number of assigned characters.
            assignees (int): Assignees limit.
        """
        char = base.common_ctrl.chosen_char  # noqa: F821
        if char not in self._assignees:
            return

        self._assignees.remove(char)
        self._char_buttons[char.id].setX(-0.35)

        to_send_wid["text"] = base.labels.OUTINGS_GUI[0].format(  # noqa: F821
            cur_as=str(len(self._assignees)),
            max_as=str(assignees))

    def _blink_upcome_icon(self, task):
        """Blink upcoming outing icon to attract attention."""
        self._blink_step += 1
        if self._blink_step in (2, 4, 6):
            self._upcome_ico.show()
            if self._blink_step == 6:
                self._blink_step = 0
                return task.done

            return task.again

        self._upcome_ico.hide()
        return task.again

    def _animate_bars(self, bars, score, selected_effect, recruit_effect,
                      cohesion_inc, task):
        """Animate filling the bars.

        Args:
            bars (list): Widget to fill.
            score (int): Total outing score.
            selected_effect (dict):
                Effect which requires to choose a target.
            recruit_effect (int): Cost of a possible recruit
            cohesion_inc (float): Cohesion increase value.
        """
        all_filled = True
        for bar in bars:
            bar_wid = bar[0]
            if bar_wid["value"] >= bar[1]:
                continue

            bar_wid["value"] = bar_wid["value"] + bar_wid["range"] / 100
            all_filled = False

        if all_filled:
            shift = -0.07

            for num in range(4):
                self._outing_widgets.append(
                    DirectLabel(
                        parent=self._list,
                        text=str(bars[num][1]) + "/" + str(bars[num][2]),
                        frameSize=(0.6, 0.6, 0.6, 0.6),
                        text_scale=0.035,
                        pos=(0.168, 0, shift),
                    ))
                shift -= 0.12

            self._outing_widgets.append(
                DirectLabel(  # Total outing score:
                    parent=self._list,
                    text=base.labels.OUTINGS_GUI[1] + str(score) +
                    "/100",  # noqa: F821
                    text_font=base.main_font,  # noqa: F821
                    frameSize=(0.6, 0.6, 0.6, 0.6),
                    text_scale=0.042,
                    pos=(0, 0, -0.57),
                ))
            if round(cohesion_inc, 2) > 0.05:
                self._outing_widgets.append(
                    DirectLabel(  # Cohesion increased:
                        parent=self._list,
                        text=base.labels.OUTINGS_GUI[15].format(  # noqa: F821
                            value=round(cohesion_inc, 2)),
                        text_font=base.main_font,  # noqa: F821
                        frameSize=(0.6, 0.6, 0.6, 0.6),
                        text_scale=0.035,
                        pos=(0, 0, -0.69),
                    ))
            self._outing_widgets.append(
                DirectButton(  # Done
                    pos=(0, 0, -0.77),
                    text=base.labels.DISTINGUISHED[6],  # noqa: F821
                    text_font=base.main_font,  # noqa: F821
                    text_fg=RUST_COL,
                    text_shadow=(0, 0, 0, 1),
                    frameColor=(0, 0, 0, 0),
                    command=self._finish_outing,
                    extraArgs=[selected_effect, recruit_effect],
                    scale=(0.05, 0, 0.05),
                    clickSound=base.main_menu.click_snd,  # noqa: F821
                ))
            return task.done

        return task.again

    def _dont_hire_unit(self):
        """Finish an outing without recruiting."""
        self.hide_outing()
        base.common_ctrl.deselect()  # noqa: F821

    def _hire_unit(self, char, cost):
        """Hire unit from the outing.

        Args:
            char (units.crew.character.Character):
                Character to recruit.
            cost (int): Cost of the recruitement.
        """
        if not base.res_gui.check_enough_money(cost):  # noqa: F821
            return

        if not base.res_gui.check_has_cell():  # noqa: F821
            return

        base.dollars -= cost  # noqa: F821

        base.world.city_gui.write_snd.play()  # noqa: F821
        base.team.chars[char.id] = char  # noqa: F821

        char.prepare()
        base.train.place_recruit(char)  # noqa: F821
        base.res_gui.update_chars()  # noqa: F821

        self.hide_outing()
        base.common_ctrl.deselect()  # noqa: F821

    def _finish_outing(self, selected_effect, recruit_effect):
        """Show effect selector if needed and finish the outing.

        Args:
            selected_effect (dict):
                Effect which requires to choose a target.
            recruit_effect (int):
                Cost of a possible recruit.
        """
        clear_wids(self._outing_widgets)

        if not (selected_effect or recruit_effect):
            self.hide_outing()
            return

        if recruit_effect:
            char = base.team.generate_recruit()  # noqa: F821
            base.char_gui.show_char_info(char)  # noqa: F821

            self._outing_widgets.append(
                DirectLabel(  # You can recruit <name> for <cost>$
                    parent=self._list,
                    pos=(0, 0, 0),
                    text=base.labels.OUTINGS_GUI[12].format(  # noqa: F821
                        name=char.name, cost=recruit_effect),
                    text_font=base.main_font,  # noqa: F821
                    frameSize=(0.6, 0.6, 0.6, 0.6),
                    text_scale=0.045,
                ))
            self._outing_widgets.append(
                DirectButton(  # Recruit
                    pos=(-0.2, 0, -0.75),
                    text=base.labels.OUTINGS_GUI[10],  # noqa: F821
                    text_font=base.main_font,  # noqa: F821
                    text_fg=RUST_COL,
                    text_shadow=(0, 0, 0, 1),
                    frameColor=(0, 0, 0, 0),
                    command=self._hire_unit,
                    extraArgs=[char, recruit_effect],
                    scale=(0.05, 0, 0.05),
                    clickSound=base.main_menu.click_snd,  # noqa: F821
                ))
            self._outing_widgets.append(
                DirectButton(  # Don't recruit
                    pos=(0.2, 0, -0.75),
                    text=base.labels.OUTINGS_GUI[11],  # noqa: F821
                    text_font=base.main_font,  # noqa: F821
                    text_fg=RUST_COL,
                    text_shadow=(0, 0, 0, 1),
                    frameColor=(0, 0, 0, 0),
                    command=self._dont_hire_unit,
                    scale=(0.05, 0, 0.05),
                    clickSound=base.main_menu.click_snd,  # noqa: F821
                ))
            return

        # there are effects to select a target for
        effect_str = ""
        for key, value in selected_effect.items():
            if key == "add_trait":
                ind1, ind2 = value
                value = base.labels.TRAITS[ind1][ind2]  # noqa: F821
                effect_str = base.labels.OUTINGS_GUI[13].format(  # noqa: F821
                    trait=value,
                    desc=base.labels.TRAIT_DESC[value]  # noqa: F821
                )
            else:
                effect_str += (key + " " + ("+" if value > 0 else "-") +
                               str(value) + "\n")

        self._outing_widgets.append(
            DirectLabel(  # Select one character as a target for the effect:
                parent=self._list,
                text=base.labels.OUTINGS_GUI[14]  # noqa: F821
                + "\n{effect}".format(effect=effect_str),
                text_font=base.main_font,  # noqa: F821
                frameSize=(0.6, 0.6, 0.6, 0.6),
                text_scale=0.045,
            ))
        self._char_chooser = CharacterChooser(is_shadowed=True)
        self._char_chooser.prepare(
            self._list,
            (0, 0, -0.15),
            base.team.chars  # noqa: F821
        )
        self._outing_widgets.append(
            DirectButton(  # Done
                pos=(0, 0, -0.75),
                text=base.labels.DISTINGUISHED[6],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_fg=RUST_COL,
                text_shadow=(0, 0, 0, 1),
                frameColor=(0, 0, 0, 0),
                command=self._do_effect_and_finish,  # noqa: F821
                extraArgs=[selected_effect],
                scale=(0.05, 0, 0.05),
                clickSound=base.main_menu.click_snd,  # noqa: F821
            ))

    def _do_effect_and_finish(self, effect):
        """
        Do effects for the selected character
        and finish the outing.

        Args:
            effect (dict): The effect to do.
        """
        self._char_chooser.chosen_item.do_effects(effect)
        self._char_chooser.destroy()
        self.hide_outing()

    def show_upcoming(self, text, icon):
        """Show the upcoming event notification.

        Args:
            text (str): Event text.
            icon (str): Event icon.
        """
        self._upcome_text["text"] = text
        self._upcome_ico["frameTexture"] = icon

        self._upcome_text.show()
        self._upcome_ico.show()

        taskMgr.doMethodLater(  # noqa: F821
            0.3, self._blink_upcome_icon, "blink_outing_icon")

    def show_place_of_interest(self):
        """Show icon for a place of interest."""
        self.show_upcoming(
            base.labels.NOTIFIERS[0],
            OUTINGS_ICONS["Place Of Interest"],  # noqa: F821
        )

    def show_upcoming_outing(self, type_orig, type_):
        """Show upcoming outing notification.

        Args:
            type_orig (str): Original outing type.
            type_ (str): Translated outing type.
        """
        self._outing_snd.play()
        self.show_upcoming(
            base.labels.NOTIFIERS[1].format(type_.capitalize()),  # noqa: F821
            OUTINGS_ICONS[type_orig],
        )

    def show_city(self):
        """Show upcoming city notification."""
        self.show_upcoming(base.labels.TIPS[2],
                           "gui/tex/city.png")  # noqa: F821

    def show_upcoming_closer(self):
        """Show that 1 mile left until available outing."""
        self._upcome_text["text"] = self._upcome_text["text"].replace(
            base.labels.NOTIFIERS[2],  # noqa: F821
            base.labels.NOTIFIERS[3],  # noqa: F821
        )

    def show_can_start(self):
        """Show that outing can be started."""
        self._upcome_text["text"] = base.labels.NOTIFIERS[4]  # noqa: F821

    def hide_outing(self):
        """Hide all the outings gui."""
        self._upcome_text.hide()
        self._upcome_ico.hide()

        if self.is_shown:
            self._assignees.clear()

            self._list.hide()
            self.is_shown = False
            clear_wids(self._outing_widgets)

    def start(self, outing):
        """Start the outing scenario.

        Draw an interface with outing description.

        Args:
            outing (dict): Outing description.
        """
        self.hide_outing()
        base.traits_gui.hide()  # noqa: F821
        self.is_shown = True
        self._list.show()

        out_labels = base.labels.OUTINGS[outing["index"]]  # noqa: F821
        self._name["text"] = out_labels["name"]
        self._type["text"] = base.labels.OUTING_TYPES[
            outing["type"]]  # noqa: F821
        self._desc["text"] = out_labels["desc"]

        self._outing_widgets.append(
            DirectLabel(  # Crew:
                parent=self._list,
                text=base.labels.OUTINGS_GUI[9],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                frameSize=(0.6, 0.6, 0.6, 0.6),
                text_scale=0.035,
                pos=(-0.35, 0, 0),
            ))
        shift = -0.07
        for id_, char in base.team.chars.items():  # noqa: F821
            but = DirectButton(
                pos=(-0.35, 0, shift),
                text=char.name,
                text_fg=SILVER_COL,
                frameColor=(0, 0, 0, 0.3),
                command=base.common_ctrl.choose_char,  # noqa: F821
                extraArgs=[char.id],
                scale=(0.04, 0, 0.03),
            )
            self._char_buttons[id_] = but
            self._outing_widgets.append(but)

            shift -= 0.04

        to_send = DirectLabel(  # People to send
            parent=self._list,
            text=base.labels.OUTINGS_GUI[0].format(  # noqa: F821
                cur_as="0", max_as=outing["assignees"]),
            text_scale=0.035,
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.6, 0.6, 0.6, 0.6),
            pos=(0.35, 0, 0),
        )
        self._outing_widgets.append(to_send)

        self._outing_widgets.append(
            DirectButton(
                pos=(0, 0, -0.15),
                text=">",
                text_fg=SILVER_COL,
                frameColor=(0, 0, 0, 0.3),
                command=self._assign_for_outing,
                extraArgs=[to_send, outing["assignees"]],
                scale=(0.075, 0, 0.075),
            ))
        self._outing_widgets.append(
            DirectButton(
                pos=(0, 0, -0.21),
                text="<",
                text_fg=SILVER_COL,
                frameColor=(0, 0, 0, 0.3),
                command=self._unassign_for_outing,
                extraArgs=[to_send, outing["assignees"]],
                scale=(0.075, 0, 0.075),
            ))
        self._outing_widgets.append(
            DirectButton(  # Don't send
                pos=(-0.15, 0, -0.75),
                text=base.labels.OUTINGS_GUI[2],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_fg=RUST_COL,
                text_shadow=(0, 0, 0, 1),
                frameColor=(0, 0, 0, 0),
                command=self.hide_outing,
                scale=(0.05, 0, 0.05),
                clickSound=base.main_menu.click_snd,  # noqa: F821
            ))
        self._outing_widgets.append(
            DirectButton(  # Send
                pos=(0.15, 0, -0.75),
                text=base.labels.OUTINGS_GUI[3],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_fg=RUST_COL,
                text_shadow=(0, 0, 0, 1),
                frameColor=(0, 0, 0, 0),
                command=base.world.outings_mgr.go_for_outing,  # noqa: F821
                extraArgs=[outing, self._assignees],
                clickSound=base.main_menu.click_snd,  # noqa: F821
                scale=(0.05, 0, 0.05),
            ))

    def show_result(
        self,
        desc,
        score,
        cond_score,
        class_score,
        cohesion_score,
        day_part_score,
        selected_effect,
        recruit_effect,
        cohesion_inc,
    ):
        """Show outing results GUI.

        Args:
            desc (str): Result description.
            score (int): Total outing score.
            cond_score (float): Score from characters condition.
            class_score (int): Score from characters classes.
            cohesion_score (float): Characters cohesion score.
            day_part_score (int): Day part bonus and special skills score.
            selected_effect (dict): Effect which requires to choose a target.
            recruit_effect (int): Cost of a possible recruit.
            cohesion_inc (float): Cohesion increase value.
        """
        clear_wids(self._outing_widgets)

        self._desc["text"] = desc

        self._outing_widgets.append(
            DirectLabel(  # Outing score:
                parent=self._list,
                text=base.labels.OUTINGS_GUI[4],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                frameSize=(0.6, 0.6, 0.6, 0.6),
                text_scale=0.042,
            ))
        bars = []
        shift = -0.07
        for name, maximum, col, value in (
            (  # Character classes fit:
                base.labels.OUTINGS_GUI[5],  # noqa: F821
                40,
                (0.36, 0.6, 0.42, 1),
                class_score,
            ),
            (  # Characters condition:
                base.labels.OUTINGS_GUI[6],  # noqa: F821
                25,
                (0.65, 0.2, 0.2, 1),
                cond_score,
            ),
            (  # Characters cohesion:
                base.labels.OUTINGS_GUI[7],  # noqa: F821
                25,
                SILVER_COL,
                cohesion_score,
            ),
            (  # Day part:
                base.labels.OUTINGS_GUI[8],  # noqa: F821
                10,
                (0.42, 0.42, 0.8, 1),
                day_part_score,
            ),
        ):
            self._outing_widgets.append(
                DirectLabel(
                    parent=self._list,
                    text=name,
                    text_font=base.main_font,  # noqa: F821
                    frameSize=(0.6, 0.6, 0.6, 0.6),
                    text_scale=0.035,
                    pos=(-0.08, 0, shift),
                ))
            shift -= 0.04
            bar = DirectWaitBar(
                parent=self._list,
                frameSize=(-0.17, 0.17, -0.005, 0.005),
                frameColor=(0.3, 0.3, 0.3, 0.5),
                value=0,
                range=maximum,
                barColor=col,
                pos=(0, 0, shift),
            )
            bars.append((bar, value, maximum))
            self._outing_widgets.append(bar)

            shift -= 0.08

        taskMgr.doMethodLater(  # noqa: F821
            0.035,
            self._animate_bars,
            "animate_outing_bars",
            extraArgs=[
                bars, score, selected_effect, recruit_effect, cohesion_inc
            ],
            appendTask=True,
        )