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
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()
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")
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()
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()
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
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, )