예제 #1
0
    def drawSlide(self, surf):
        mainSlideSurf = MenuFunctions.CreateBaseMenuSurf(
            (GC.WINWIDTH + 8, 6 * GC.WINHEIGHT / 10 + 8),
            'ClearMenuBackground')
        surf.blit(mainSlideSurf, (0 - 4, GC.WINHEIGHT / 5))

        if self.state.getState() == 'Config' or (
                self.state.getState() == 'TopMenu'
                and self.currentSelection == 0):
            config_font = GC.FONT['text_blue']
            controls_font = GC.FONT['text_grey']
        else:
            config_font = GC.FONT['text_grey']
            controls_font = GC.FONT['text_blue']

        configSlideSurf = MenuFunctions.CreateBaseMenuSurf(
            (GC.WINWIDTH / 2 - 8, 24), 'ClearMenuBackground')
        surf.blit(configSlideSurf, (4, 4))
        config_position = (4 + configSlideSurf.get_width() / 2 -
                           config_font.size('Config')[0] / 2,
                           16 - config_font.size('Config')[1] / 2)
        config_font.blit(cf.WORDS['Config'], surf, config_position)

        controlsSlideSurf = MenuFunctions.CreateBaseMenuSurf(
            (GC.WINWIDTH / 2 - 8, 24), 'ClearMenuBackground')
        surf.blit(controlsSlideSurf, (GC.WINWIDTH / 2 + 4, 4))
        controls_position = (GC.WINWIDTH / 2 + 4 +
                             controlsSlideSurf.get_width() / 2 -
                             controls_font.size('Controls')[0] / 2,
                             16 - controls_font.size('Controls')[1] / 2)
        controls_font.blit(cf.WORDS['Controls'], surf, controls_position)
예제 #2
0
 def draw(self, gameStateObj, metaDataObj):
     mapSurf = StateMachine.State.draw(self, gameStateObj, metaDataObj)
     mapSurf.blit(GC.IMAGESDICT['DebugBackground'], (0, GC.WINHEIGHT - (5 * 16)))
     for idx, command in enumerate(reversed(commands[-self.num_back:])):
         # GC.FONT['text_blue'].blit(command, mapSurf, (0, GC.WINHEIGHT - idx * 16 - 32))
         MenuFunctions.OutlineFont(GC.BASICFONT, command, mapSurf, GC.COLORDICT['off_white'], GC.COLORDICT['off_black'], (0, GC.WINHEIGHT - idx * 16 - 32))
     # GC.FONT['text_blue'].blit(self.current_command, mapSurf, (0, GC.WINHEIGHT - 16))
     MenuFunctions.OutlineFont(GC.BASICFONT, self.current_command, mapSurf, GC.COLORDICT['off_white'], GC.COLORDICT['off_black'], (0, GC.WINHEIGHT - 16))
     return mapSurf
예제 #3
0
    def create_help_box(self):
        if self.weapon or self.spell:
            font1 = GC.FONT['text_blue']
            font2 = GC.FONT['text_yellow']

            if self.weapon:
                first_line_text = [' ', self.weapon.LVL, ' Mt ', str(self.weapon.MT), ' Hit ', str(self.weapon.HIT)]
                if cf.CONSTANTS['crit']:
                    first_line_text += [' Crit ', str(self.crit) if self.crit else '--']
                if self.weight:
                    first_line_text += [' Wt ', str(self.weight)]
                first_line_text += [' Rng ', self.strRNG]
                first_line_font = [font1, font1, font2, font1, font2, font1]
                if cf.CONSTANTS['crit']:
                    first_line_font += [font2, font1]
                if self.weight:
                    first_line_font += [font2, font1]
                first_line_font += [font2, font1]

            elif self.spell:
                first_line_text = [' ', self.spell.LVL]
                first_line_font = [font1, font1]
                if self.damage is not None:
                    first_line_text += [' Mt ', str(self.damage)]
                    first_line_font += [font2, font1]
                if self.hit is not None:
                    first_line_text += [' Hit ', str(self.hit)]
                    first_line_font += [font2, font1]
                if cf.CONSTANTS['crit'] and self.crit is not None:
                    first_line_text += [' Crit ', str(self.crit)]
                    first_line_font += [font2, font1]
                first_line_text += [' Rng ', self.strRNG]
                first_line_font += [font2, font1]

            first_line_length = max(font1.size(''.join(first_line_text))[0] + 16 * len(self.TYPE) + 4, 112) # 112 was 96
            if self.desc:
                output_desc_lines = MenuFunctions.line_wrap(MenuFunctions.line_chunk(self.desc), first_line_length, GC.FONT['convo_black']) 
            else:
                output_desc_lines = ''
            size_x = first_line_length + 16
            size_y = 24 + len(output_desc_lines)*16
            help_surf = MenuFunctions.CreateBaseMenuSurf((size_x, size_y), 'MessageWindowBackground')  
            self.drawType(help_surf, 4, 4)
            
            # Actually blit first line
            word_index = 4 + 16 * len(self.TYPE)
            for index, word in enumerate(first_line_text):
                first_line_font[index].blit(word, help_surf, (word_index, 4))
                word_index += first_line_font[index].size(word)[0]
            
            for index, line in enumerate(output_desc_lines):
                GC.FONT['convo_black'].blit(''.join(line), help_surf, (4, GC.FONT['convo_black'].height*index + 4 + 16))  

            return help_surf

        else:
            return InfoMenu.create_help_box(self.desc)
예제 #4
0
    def begin(self, gameStateObj, metaDataObj):
        if not self.started:
            # Get units to display
            self.units = [unit for unit in gameStateObj.allunits if unit.position and unit.team == 'player']

            self.bg_surf = Image_Modification.flickerImageTranslucent(GC.IMAGESDICT['UnitMenuBackground'], 10)
            self.title_bg = Image_Modification.flickerImageTranslucent(GC.IMAGESDICT['TitleBar'], 10)
            self.background = MenuFunctions.MovingBackground(GC.IMAGESDICT['RuneBackground'])
            self.states = [('Character', ['Class', 'Lv', 'Exp', 'HP', 'Max'], [4, 66, 89, 113, 133]),
                           ('Fighting Skill', ['STR', 'MAG', 'SKL', 'SPD', 'LCK', 'DEF', 'RES'], [4, 26, 48, 71, 94, 119, 142]),
                           ('Equipment', ['Equip', 'Atk', 'Hit', 'Avoid'], [16, 72, 103, 136]),
                           ('Personal Data', ['MOV', 'CON', 'Aid', 'Rat', 'Trv'], [4, 33, 60, 82, 106]),
                           ('Weapon Level', Weapons.TRIANGLE.types, [9 + idx*16 for idx in range(len(Weapons.TRIANGLE.types))])]
            if cf.CONSTANTS['support']:
                self.states.append(('Support Chance', ['Ally'], [0]))
            self.state_index = 0
            self.prev_state_index = 0
            self.unit_index = 1 # 0 means on banner
            self.scroll_index = 1
            self.banner_index = 0
            self.num_per_page = 6

            self.state_scroll = 0
            self.scroll_direction = 0

            self.weapon_icons = [Weapons.Icon(weapon) for weapon in Weapons.TRIANGLE.types]
            self.help_boxes = []
            self.info = False

            self.scroll_bar = GUIObjects.ScrollBar((233, 59))
            self.left_arrow = GUIObjects.ScrollArrow('left', (7, 41))
            self.right_arrow = GUIObjects.ScrollArrow('right', (GC.WINWIDTH - 7 - 8, 41), 0.5)

            # For sort
            self.current_sort = 'Name'
            self.descending = False
            self.sort_surf = MenuFunctions.CreateBaseMenuSurf((64, 24))
            self.sort_surf = Image_Modification.flickerImageTranslucent(self.sort_surf, 10)
            self.sort_arrow_counter = Counters.ArrowCounter()
            self.sort_arrow_counter.arrow_anim = [0, 1, 2]
            self.sort()

            # Transition in:
            gameStateObj.stateMachine.changeState("transition_in")
            return 'repeat'
        else:
            chosen_unit = gameStateObj.info_menu_struct['chosen_unit']
            if chosen_unit and chosen_unit in self.units:
                self.move_to_unit(chosen_unit)
            gameStateObj.info_menu_struct['chosen_unit'] = None
예제 #5
0
    def draw(self, surf, gameStateObj):
        self.write_index = 6
        if not self.surf:
            bg_surf = MenuFunctions.CreateBaseMenuSurf(
                self.size, 'BaseMenuBackgroundOpaque')
            self.surf = Engine.create_surface(
                (self.size[0] + 2, self.size[1] + 4),
                convert=True,
                transparent=True)
            self.surf.blit(bg_surf, (2, 4))
            self.surf.blit(GC.IMAGESDICT['SmallGem'], (0, 0))
            Image_Modification.flickerImageTranslucent(self.surf, 10)
        BGSurf = self.surf.copy()

        # Center it
        pos = surf.get_width() // 2 - self.size[0] // 2 - 2, surf.get_height(
        ) // 2 - self.size[1] // 2 - 4
        # Blit words
        for index, word in enumerate(self.banner):
            word_width = GC.FONT[self.banner_font[index]].size(word)[0]
            GC.FONT[self.banner_font[index]].blit(
                word, BGSurf, (self.write_index,
                               self.size[1] // 2 - self.font_height // 2 + 4))
            self.write_index += word_width
        # Blit item icon
        if self.item:
            self.item.draw(BGSurf, (self.size[0] - 6 - 16 - 2, 4 + 4),
                           cooldown=False)
        surf.blit(BGSurf, pos)
예제 #6
0
    def draw(self, gameStateObj):
        text_lines = self.split_string(self.eval_string(self.display_name_string, gameStateObj))

        longest_surf_width = self.get_size(text_lines)

        if longest_surf_width != self.surf_width or len(text_lines) != self.num_lines:
            self.num_lines = len(text_lines)
            self.surf_width = longest_surf_width
            surf_height = 16 * self.num_lines + 8

            # Blit background
            BGSurf = MenuFunctions.CreateBaseMenuSurf((self.surf_width + 16, surf_height), 'BaseMenuBackgroundOpaque')
            if self.num_lines == 1:
                BGSurf.blit(GC.IMAGESDICT['Shimmer1'], (BGSurf.get_width() - 1 - GC.IMAGESDICT['Shimmer1'].get_width(), 4))
            elif self.num_lines == 2:
                BGSurf.blit(GC.IMAGESDICT['Shimmer2'], (BGSurf.get_width() - 1 - GC.IMAGESDICT['Shimmer2'].get_width(), 4))
            self.BGSurf = Engine.create_surface((BGSurf.get_width(), BGSurf.get_height() + 3), transparent=True, convert=True)
            self.BGSurf.blit(BGSurf, (0, 3))
            gem = GC.IMAGESDICT['BlueCombatGem']
            self.BGSurf.blit(gem, (BGSurf.get_width()//2 - gem.get_width()//2, 0))
            # Now make translucent
            self.BGSurf = Image_Modification.flickerImageTranslucent(self.BGSurf, 20)

        temp_surf = self.BGSurf.copy()
        for index, line in enumerate(text_lines):
            position = temp_surf.get_width()//2 - GC.FONT['text_white'].size(line)[0]//2, 16 * index + 6
            GC.FONT['text_white'].blit(line, temp_surf, position)

        return temp_surf
예제 #7
0
    def get_help_box(self):
        if self.weapon or self.spell:
            font1 = FONT['text_blue']
            font2 = FONT['text_yellow']

            if self.weapon:
                first_line_text = [' ', self.weapon.LVL, ' Mt ', str(self.weapon.MT), ' Hit ', str(self.weapon.HIT)]
                if self.WT:
                    first_line_text += [' Wt ', str(self.WT)]
                first_line_text += [' Rng ', self.strRNG]
                first_line_font = [font1, font1, font2, font1, font2, font1]
                if self.WT:
                    first_line_font += [font2, font1]
                first_line_font += [font2, font1]

            elif self.spell:
                first_line_text = [' ', self.spell.LVL]
                first_line_font = [font1, font1]
                if self.damage is not None:
                    first_line_text += [' Mt ', str(self.damage)]
                    first_line_font += [font2, font1]
                if self.hit is not None:
                    first_line_text += [' Hit ', str(self.hit)]
                    first_line_font += [font2, font1]
                first_line_text += [' Rng ', self.strRNG]
                first_line_font += [font2, font1]

            first_line_length = max(font1.size(''.join(first_line_text))[0] + 16 * len(self.TYPE) + 4, 96)
            output_desc_lines = MenuFunctions.line_wrap(MenuFunctions.line_chunk(self.desc), first_line_length, FONT['convo_black']) 
            size_x = first_line_length + 16
            size_y = 24 + len(output_desc_lines)*16
            help_surf = MenuFunctions.CreateBaseMenuSurf((size_x, size_y), 'MessageWindowBackground')
            self.drawType(help_surf, 4, 4)
            
            # Actually blit first line
            word_index = 4 + 16 * len(self.TYPE)
            for index, word in enumerate(first_line_text):
                first_line_font[index].blit(word, help_surf, (word_index, 4))
                word_index += first_line_font[index].size(word)[0]
            
            for index, line in enumerate(output_desc_lines):
                FONT['convo_black'].blit(''.join(line), help_surf, (4, FONT['convo_black'].height*index + 4 + 16))

            return help_surf

        else:
            return InfoMenu.create_help_box(self.desc)
예제 #8
0
 def drawInvalid(self, surf):
     size_of_text = GC.FONT['text_white'].size("Invalid Choice!")
     width = size_of_text[0]
     height = size_of_text[1]
     pop_up_surf = MenuFunctions.CreateBaseMenuSurf((width + 16 - width%8, height + 16 - height%8))
     surf.blit(Image_Modification.flickerImageTranslucent(GC.IMAGESDICT['BlackBackground'].copy(), 60), (0, 0))
     topleft = (GC.WINWIDTH//2 - pop_up_surf.get_width()//2, GC.WINHEIGHT//2 - pop_up_surf.get_height()//2)
     surf.blit(pop_up_surf, topleft)
     position = (GC.WINWIDTH//2 - width//2, GC.WINHEIGHT//2 - height//2)
     GC.FONT['text_white'].blit(cf.WORDS["Invalid Choice"], surf, position)
예제 #9
0
    def begin(self, gameStateObj, metaDataObj):
        if not self.started:
            self.config = [('Animation', ['Always', 'Your Turn', 'Combat Only', 'Never'], cf.WORDS['Animation_desc'], 0),
                           ('temp_Screen Size', ['1', '2', '3', '4', '5'], cf.WORDS['temp_Screen Size_desc'], 18),
                           ('Unit Speed', list(reversed(range(15, 180, 15))), cf.WORDS['Unit Speed_desc'], 1),
                           ('Text Speed', cf.text_speed_options, cf.WORDS['Text Speed_desc'], 2),
                           ('Cursor Speed', list(reversed(range(0, 220, 20))), cf.WORDS['Cursor Speed_desc'], 8),
                           ('Show Terrain', ['ON', 'OFF'], cf.WORDS['Show Terrain_desc'], 7),
                           ('Show Objective', ['ON', 'OFF'], cf.WORDS['Show Objective_desc'], 6),
                           ('Autocursor', ['ON', 'OFF'], cf.WORDS['Autocursor_desc'], 13),
                           ('HP Map Team', ['All', 'Ally', 'Enemy'], cf.WORDS['HP Map Team_desc'], 10),
                           ('HP Map Cull', ['None', 'Wounded', 'All'], cf.WORDS['HP Map Cull_desc'], 10),
                           ('Music Volume', [x/10.0 for x in range(0, 11, 1)], cf.WORDS['Music Volume_desc'], 15),
                           ('Sound Volume', [x/10.0 for x in range(0, 11, 1)], cf.WORDS['Sound Volume_desc'], 16),
                           ('Autoend Turn', ['ON', 'OFF'], cf.WORDS['Autoend Turn_desc'], 14),
                           ('Confirm End', ['ON', 'OFF'], cf.WORDS['Confirm End_desc'], 14),
                           ('Display Hints', ['ON', 'OFF'], cf.WORDS['Display Hints_desc'], 3)]

            self.controls = {'key_SELECT': Engine.subsurface(GC.IMAGESDICT['Buttons'], (0, 66, 14, 13)),
                             'key_BACK': Engine.subsurface(GC.IMAGESDICT['Buttons'], (0, 82, 14, 13)),
                             'key_INFO': Engine.subsurface(GC.IMAGESDICT['Buttons'], (1, 149, 16, 9)),
                             'key_AUX': Engine.subsurface(GC.IMAGESDICT['Buttons'], (1, 133, 16, 9)),
                             'key_START': Engine.subsurface(GC.IMAGESDICT['Buttons'], (0, 165, 33, 9)),
                             'key_LEFT': Engine.subsurface(GC.IMAGESDICT['Buttons'], (1, 4, 13, 12)),
                             'key_RIGHT': Engine.subsurface(GC.IMAGESDICT['Buttons'], (1, 19, 13, 12)),
                             'key_DOWN': Engine.subsurface(GC.IMAGESDICT['Buttons'], (1, 34, 12, 13)),
                             'key_UP': Engine.subsurface(GC.IMAGESDICT['Buttons'], (1, 50, 12, 13))}

            self.currentSelection = 0
            self.start_offset = 32
            self.top_of_menu = 0

            self.control_order = ['key_SELECT', 'key_BACK', 'key_INFO', 'key_AUX', 'key_LEFT', 'key_RIGHT', 'key_UP', 'key_DOWN', 'key_START']

            self.background = MenuFunctions.MovingBackground(GC.IMAGESDICT['StatusBackground'])

            self.state = CustomObjects.StateMachine('TopMenu')

            Counters.CursorControl.__init__(self)
            self.up_arrow = GUIObjects.ScrollArrow('up', (GC.WINWIDTH//2 - 7, self.start_offset - 4), 0)
            self.down_arrow = GUIObjects.ScrollArrow('down', (GC.WINWIDTH//2 - 7, self.start_offset + 6*16 - 1), 0.5)
            self.left_arrow = GUIObjects.ScrollArrow('left', (0, 0), 0)
            self.right_arrow = GUIObjects.ScrollArrow('right', (0, 0), 0.5)

            self.backSurf = gameStateObj.generic_surf

            # Transition in:
            gameStateObj.stateMachine.changeState("transition_in")
            return 'repeat'
    def __init__(self, item):
        self.last_time = self.start_time = 0
        self.transition_in = self.transition_out = False
        self.item = item
        font1 = GC.FONT['text_blue']
        font2 = GC.FONT['text_yellow']

        if self.item.weapon:
            self.first_line_text = [' ', self.item.weapon.LVL, ' Mt ', str(self.item.weapon.MT), ' Hit ', str(self.item.weapon.HIT)]
            if cf.CONSTANTS['crit']:
                self.first_line_text += [' Crit ', str(self.item.crit) if self.item.crit is not None else '--']
            if self.item.weight:
                self.first_line_text += [' Wt ', str(self.item.weight)]
            self.first_line_text += [' Rng ', self.item.strRNG]
            self.first_line_font = [font1, font1, font2, font1, font2, font1]
            if cf.CONSTANTS['crit']:
                self.first_line_font += [font2, font1]
            if self.item.weight:
                self.first_line_font += [font2, font1]
            self.first_line_font += [font2, font1]

        elif self.item.spell:
            self.first_line_text = [' ', self.item.spell.LVL]
            self.first_line_font = [font1, font1]
            if self.item.damage is not None:
                self.first_line_text += [' Mt ', str(self.item.damage)]
                self.first_line_font += [font2, font1]
            if self.item.hit is not None:
                self.first_line_text += [' Hit ', str(self.item.hit)]
                self.first_line_font += [font2, font1]
            if cf.CONSTANTS['crit'] and self.item.crit is not None:
                self.first_line_text += [' Crit ', str(self.item.crit)]
                self.first_line_font += [font2, font1]
            self.first_line_text += [' Rng ', self.item.strRNG]
            self.first_line_font += [font2, font1]

        first_line_length = max(font1.size(''.join(self.first_line_text))[0] + (16 if self.item.icon else 0) + 4, 112) # 112 was 96
        if self.item.desc:
            self.output_desc_lines = TextChunk.line_wrap(TextChunk.line_chunk(self.item.desc), first_line_length, GC.FONT['convo_black']) 
            self.output_desc_lines = [''.join(line) for line in self.output_desc_lines]
        else:
            self.output_desc_lines = []
        size_x = first_line_length + 24
        size_y = 32 + len(self.output_desc_lines)*16
        self.help_surf = MenuFunctions.CreateBaseMenuSurf((size_x, size_y), 'MessageWindowBackground')  
        self.h_surf = Engine.create_surface((size_x, size_y + 3), transparent=True)
예제 #11
0
    def drawInfo(self, surf):
        mainInfoSurf = MenuFunctions.CreateBaseMenuSurf((GC.WINWIDTH - 32, 24), 'BaseMenuBackground')
        surf.blit(mainInfoSurf, (16, GC.WINHEIGHT - 24))

        if self.state.getState() == "Config":
            info_text = self.config[self.currentSelection][2]
        elif self.state.getState() == "Controls":
            info_text = cf.WORDS['Controls_desc']
        elif self.state.getState() == "Get_Input":
            info_text = cf.WORDS['Get_Input_desc']
        elif self.state.getState() == "TopMenu":
            if self.currentSelection == 0:
                info_text = cf.WORDS['Config_desc']
            else:
                info_text = cf.WORDS['Controls_desc']
        else:
            return
        GC.FONT['text_white'].blit(info_text, surf, (32, GC.WINHEIGHT - 20))
예제 #12
0
    def clean_up(self, gameStateObj, metaDataObj):
        # Remove combat state
        gameStateObj.stateMachine.back()
        # Reset states if you're not using a solo skill
        if self.skill_used and self.skill_used.active and self.skill_used.active.mode == 'Solo':
            self.attacker.hasTraded = True # Can still attack, can't move
            self.attacker.hasAttacked = False
        else:
            self.attacker.hasAttacked = True
            if not self.attacker.has_canto_plus() and not self.event_combat:
                gameStateObj.stateMachine.changeState('wait') # Event combats do not cause unit to wait

        # Handle items that were used
        a_broke_item, d_broke_item = False, False
        if self.item.uses and self.item.uses.uses <= 0:
            a_broke_item = True
        if self.defender and self.defender.getMainWeapon() and self.defender.getMainWeapon().uses and self.defender.getMainWeapon().uses.uses <= 0:
            d_broke_item = True

        # Handle skills that were used
        if self.skill_used:
            self.skill_used.active.current_charge = 0
            self.skill_used.active.reverse_mod()

        # Create all_units list
        all_units = [unit for unit in self.splash] + [self.attacker]
        if self.defender: all_units += [self.defender]

        # Handle death
        for unit in all_units:
            if unit.currenthp <= 0:
                unit.isDying = True

        # === HANDLE STATE STACK ==
        # Handle where we go at very end
        if self.event_combat:
            gameStateObj.message[-1].current_state = "Processing"
        else:
            if self.attacker.team == 'player':
                if not self.attacker.hasAttacked:
                    gameStateObj.stateMachine.changeState('menu')
                elif self.attacker.has_canto_plus() and not self.attacker.isDying:
                    gameStateObj.stateMachine.changeState('move')
                else:
                    #self.attacker.wait()
                    gameStateObj.stateMachine.clear()
                    gameStateObj.stateMachine.changeState('free')
                    gameStateObj.stateMachine.changeState('wait')
            #else:
                #gameStateObj.stateMachine.changeState('ai')

        ### Handle interact_script
        interact_script = Dialogue.Dialogue_Scene('Data/Level' + str(gameStateObj.currentLevelIndex) + '/interactScript.txt', self.attacker, event_flag=False)
        gameStateObj.message.append(interact_script)
        gameStateObj.stateMachine.changeState('dialogue')

        # Handle miracle
        for unit in all_units:
            if unit.isDying:
                if any(status.miracle and (not status.count or status.count.count > 0) for status in unit.status_effects):
                    unit.handle_miracle(gameStateObj)

        ### Handle item gain
        for unit in all_units:
            if unit.isDying and isinstance(unit, UnitObject.UnitObject):
                for item in unit.items:
                    if item.droppable:
                        item.droppable = False
                        if unit in self.splash or unit is self.defender:
                            self.attacker.add_item(item)
                            gameStateObj.banners.append(MenuFunctions.acquiredItemBanner(self.attacker, item))
                            gameStateObj.stateMachine.changeState('itemgain')
                        elif self.defender:
                            self.defender.add_item(item)
                            gameStateObj.banners.append(MenuFunctions.acquiredItemBanner(self.defender, item))
                            gameStateObj.stateMachine.changeState('itemgain')

        ### Handle item loss
        if a_broke_item and self.attacker.team == 'player' and not self.attacker.isDying:
            gameStateObj.banners.append(MenuFunctions.brokenItemBanner(self.attacker, self.item))
            gameStateObj.stateMachine.changeState('itemgain')
        if d_broke_item and self.defender.team == 'player' and not self.defender.isDying:
            gameStateObj.banners.append(MenuFunctions.brokenItemBanner(self.defender, self.defender.getMainWeapon()))
            gameStateObj.stateMachine.changeState('itemgain')

        ### Handle exp and stat gain
        if not self.event_combat and (self.item.weapon or self.item.spell):
            if self.attacker.team == 'player' and not self.attacker.isDying and not 'Mindless' in self.attacker.tags and not self.attacker.isSummon():
                if any(result.attacker is self.attacker and result.outcome for result in self.old_results):
                    self.attacker.increase_wexp(self.item, gameStateObj)

                my_exp = 0
                for other_unit in self.splash + [self.defender]:
                    if any(result.attacker is self.attacker and result.defender is other_unit and result.outcome for result in self.old_results):
                        if self.item.exp:
                            normal_exp = self.item.exp
                        elif self.item.weapon or not self.attacker.checkIfAlly(self.defender):
                            level_diff = max(0, other_unit.level - self.attacker.level + 20)
                            normal_exp = int(CONSTANTS['exp_magnitude']*level_diff**CONSTANTS['exp_curve'])
                        elif self.item.spell:
                            normal_exp = 15
                        else:
                            normal_exp = 0
                        if other_unit.isDying:
                            self.attacker.total_kills += 1
                            my_exp += int(CONSTANTS['kill_multiplier']*normal_exp) + (40 if 'Boss' in other_unit.tags else 0)
                        else:
                            my_exp += normal_exp
                        logger.debug('Attacker gained %s exp', my_exp)

                # No free exp for affecting myself or being affected by allies
                if self.attacker.checkIfAlly(self.defender):
                    my_exp = Utility.clamp(my_exp, 0, 100)
                else:
                    my_exp = Utility.clamp(my_exp, 1, 100)

                gameStateObj.levelUpScreen.append(LevelUp.levelUpScreen(gameStateObj, unit=self.attacker, exp=my_exp)) #Also handles actually adding the exp to the unit
                gameStateObj.stateMachine.changeState('expgain')

            if self.defender.team == 'player' and not self.defender.isDying and not self.defender is self.attacker and not 'Mindless' in self.defender.tags and not self.defender.isSummon():
                if any(result.attacker is self.defender and result.outcome for result in self.old_results):
                    self.defender.increase_wexp(self.defender.getMainWeapon(), gameStateObj)

                my_exp = 0
                if any(result.attacker is self.defender and result.outcome for result in self.old_results):
                    level_diff = max(0, self.attacker.level - self.defender.level + 20)
                    normal_exp = max(0, int(CONSTANTS['exp_magnitude']*level_diff**CONSTANTS['exp_curve']))
                    if self.attacker.isDying:
                        self.defender.total_kills += 1
                        my_exp += int(CONSTANTS['kill_multiplier']*normal_exp) + (40 if 'Boss' in self.attacker.tags else 0)
                    else:
                        my_exp += normal_exp 

                # No free exp for affecting myself or being affected by allies
                if self.attacker.checkIfAlly(self.defender):
                    my_exp = Utility.clamp(my_exp, 0, 100)
                else:
                    my_exp = Utility.clamp(my_exp, 1, 100)

                gameStateObj.levelUpScreen.append(LevelUp.levelUpScreen(gameStateObj, unit=self.defender, exp=my_exp)) #Also handles actually adding the exp to the unit
                gameStateObj.stateMachine.changeState('expgain')

        # Handle after battle statuses
        for status in self.attacker.status_effects:
            if status.status_after_battle and not self.attacker.isDying:
                for unit in [self.defender] + self.splash:
                    if isinstance(unit, UnitObject.UnitObject) and self.attacker.checkIfEnemy(unit) and not unit.isDying:
                        applied_status = StatusObject.statusparser(status.status_after_battle)
                        StatusObject.HandleStatusAddition(applied_status, unit)
            if status.lost_on_attack and not self.attacker.isDying and (self.item.weapon or self.item.detrimental):
                StatusObject.HandleStatusRemoval(status, self.attacker)
        if self.defender:
            for status in self.defender.status_effects:
                if status.status_after_battle and self.defender.checkIfEnemy(self.attacker) and not self.defender.isDying and not self.attacker.isDying:
                    applied_status = StatusObject.statusparser(status.status_after_battle)
                    StatusObject.HandleStatusAddition(applied_status, self.attacker)

        # Handle death
        for unit in all_units:
            if unit.isDying:
                logger.debug('%s is dying.', unit.name)
                if isinstance(unit, TileObject.TileObject):
                    gameStateObj.map.destroy(unit, gameStateObj)
                else:
                    gameStateObj.stateMachine.changeState('dying')
                    gameStateObj.message.append(Dialogue.Dialogue_Scene(metaDataObj['death_quotes'], unit, event_flag=False))
                    gameStateObj.stateMachine.changeState('dialogue')

        ### Actually remove items
        if a_broke_item:
            self.attacker.remove_item(self.item)
        if d_broke_item:
            self.defender.remove_item(self.defender.getMainWeapon())
예제 #13
0
    def update(self, gameStateObj, metaDataObj):
        # Don't do this if there is no exp change
        if not self.force_level and self.expNew == 0 or (self.unit.level%CONSTANTS['max_level'] == 0 and metaDataObj['class_dict'][self.unit.klass]['turns_into'] is None):
            return True # We're done here

        if self.instantiationTime is None: # First time update is called.
            self.instantiationTime = pygame.time.get_ticks()
            SOUNDDICT['Experience Gain'].play(-1)
            
        #print self.state.getState()
        #print self.expSet, self.expOld, self.expNew
        currentTime = pygame.time.get_ticks()

        if self.state.getState() == 'exp0':
            self.expSet = self.expOld + (currentTime - self.instantiationTime)/float(self.EXPTIME/100) # 100 is total exp
            self.expSet = int(min(self.expNew + self.expOld, self.expSet))
            if self.expNew + self.expOld <= self.expSet:
                SOUNDDICT['Experience Gain'].stop() 
            if self.expSet >= 100:
                if self.unit.level%CONSTANTS['max_level'] == 0: # If I would promote because I am level 20
                    SOUNDDICT['Experience Gain'].stop()
                    if metaDataObj['class_dict'][self.unit.klass]['turns_into']: # If has at least one class to turn into
                        self.expSet = 0
                        class_options = metaDataObj['class_dict'][self.unit.klass]['turns_into']
                        if len(class_options) > 1:
                            gameStateObj.activeMenu = MenuFunctions.ChoiceMenu(self.unit, class_options, 'auto', gameStateObj)
                            gameStateObj.stateMachine.changeState('levelpromote')
                        elif len(class_options) == 1:
                            self.unit.klass = class_options[0]
                            self.state.changeState('promote')
                        else:
                            return True
                    else: # Unit is at the highest point it can be. No more.
                        self.unit.exp = 99
                        return True
                else:
                    self.expSet = 0
                    self.unit.level += 1
                    self.levelup_list = self.unit.level_up(metaDataObj['class_dict'][self.unit.klass])
                    self.state.changeState('exp100')
            elif currentTime - self.instantiationTime >= self.EXPTIME:
                SOUNDDICT['Experience Gain'].stop()
                self.unit.exp += self.expNew
                return True

        elif self.state.getState() == 'exp100':
            # Problem... It is not counting time needed to get to this state. Should minus away that time - Time taken to get to this point in (100 - self.expOld)*float(self.EXPTIME/100)
            self.expSet = (currentTime - self.instantiationTime - (100 - self.expOld)*float(self.EXPTIME/100))/float(self.EXPTIME/100)
            self.expSet = int(min(self.expNew + self.expOld - 100, self.expSet))
            if self.expNew + self.expOld - 100 <= self.expSet:
                SOUNDDICT['Experience Gain'].stop() 
            if currentTime - self.instantiationTime >= self.EXPTIME:
                SOUNDDICT['Experience Gain'].stop()
                #MUSICTHREAD.pause()
                SOUNDDICT['Level Up'].play()
                self.state.changeState('levelUp')

        elif self.state.getState() == 'levelUp':
            if currentTime - self.instantiationTime >= self.LEVELANIMATIONTIME + self.EXPTIME:
                self.state.changeState('levelUpWait')
            else:
                time = currentTime - self.instantiationTime - self.EXPTIME
                marker1 = min(4, int(time/(self.LEVELANIMATIONTIME/5)))
                marker2 = min(4, int((time%(self.LEVELANIMATIONTIME/5))/(self.LEVELANIMATIONTIME/25)))
                self.animationMarker = (marker1, marker2)

        elif self.state.getState() == 'levelUpWait':
            if currentTime - self.instantiationTime >= self.LEVELANIMATIONTIME + self.WAITTIME + self.EXPTIME:
                self.state.changeState('levelScreen')
                #MUSICTHREAD.resume()
            else:
                self.animationMarker = (4, 4) # Set to last frame

        elif self.state.getState() == 'levelScreen':
            # Am i Done displaying?
            if currentTime - self.instantiationTime >= self.LEVELUPWAIT + self.get_num_sparks()*self.SPARKTIME + self.LEVELANIMATIONTIME + self.WAITTIME + self.EXPTIME:
                # Handle EXP when the user levels up
                self.unit.exp += self.expNew
                if self.unit.exp >= 100:
                    self.unit.exp = self.expNew - (100 - self.expOld)
                # Remove animations
                self.animations = []
                # check for skill gain
                for level_needed, class_skill in metaDataObj['class_dict'][self.unit.klass]['skills']:
                    if self.unit.level%CONSTANTS['max_level'] == level_needed:
                        if class_skill == 'Feat':
                            gameStateObj.cursor.currentSelectedUnit = self.unit
                            gameStateObj.stateMachine.changeState('feat_choice')
                        else:
                            skill = StatusObject.statusparser(class_skill)
                            StatusObject.HandleStatusAddition(skill, self.unit)
                            gameStateObj.banners.append(MenuFunctions.gainedSkillBanner(self.unit, skill))
                            gameStateObj.stateMachine.changeState('itemgain')
                
                return True

        elif self.state.getState() == 'promote':
            # Class should already have been changed by now in the levelpromote state
            # Here's where I change all the important information
            new_class = metaDataObj['class_dict'][self.unit.klass]
            self.unit.removeSprites()
            self.unit.loadSprites()
            # Reset Level - Don't!
            self.unit.level += 1
            # Actually change class
            # Reset movement speed
            self.unit.stats['MOV'].base_stat = new_class['movement']
            # Reset movement group
            self.unit.movement_group = new_class['movement_group']
            # Add weapon exp gains from that class.
            self.unit.increase_wexp(new_class['wexp_gain'], gameStateObj)
            # Add any extra tags
            if new_class['tags']: # Add any necessary tags. Does not currently take away tags, although it may have to later
                self.unit.tags.append(new_class['tags'].split(','))
                self.unit.tags = list(set(self.unit.tags)) # Remove duplicates
            # Give promotion
            self.levelup_list = self.unit.level_up(new_class, apply_level=False) # Level up once, then promote.
            self.levelup_list = [x + y for x, y in zip(self.levelup_list, new_class['promotion'])] # Add lists together
            current_stats = [self.unit.stats['HP'], self.unit.stats['STR'], self.unit.stats['MAG'], self.unit.stats['SKL'], self.unit.stats['SPD'], self.unit.stats['LCK'], self.unit.stats['DEF'], self.unit.stats['RES'], self.unit.stats['CON']]
            assert len(self.levelup_list) == len(new_class['max']) == len(current_stats), "%s %s %s"%(self.levelup_list, new_class['max'], current_stats)
            for index, stat in enumerate(self.levelup_list):
                self.levelup_list[index] = min(stat, new_class['max'][index] - current_stats[index])
            self.unit.apply_levelup(self.levelup_list)

            self.state.changeState('levelScreen')
            self.instantiationTime = currentTime # Reset time so that it doesn't skip right over LevelScreen
        
        return False