






init python:
    import random
    class Circle(renpy.display.core.Displayable):
        def __init__(self, color, radius, width=0, **properties):
            super(Circle, self).__init__(**properties)
            self.color = renpy.easy.color(color)
            self.radius = radius
            self.width = width
        
        def __hash__(self):
            return hash(self.color)
        
        def __eq__(self, o):
            if not self._equals(o): return False
            return all([
                self.color == o.color,
                self.radius == o.radius,
                self.width == o.width,
            ])
        
        def visit(self):
            return [ ]
        
        def render(self, width, height, st, at):
            rv = renpy.display.render.Render(self.radius * 2., self.radius * 2.)
            canvas = rv.canvas()
            pos = (self.radius, self.radius)
            canvas.circle(self.color, pos, self.radius, self.width)
            return rv

    class EnemyType:
        """Types of enemies.
           Used for the convenience of getting values.
        """
        Low = 0
        Normal = 1
        Heavy = 2

    class Side:
        """Key action control.
        """
        LEFT = 80
        RIGHT = 79
        UP = 82
        DOWN = 81
        SPACE = 44

    class Scaled:
        """Factor scale of game elements.
        """
        Scissors = .4
        Enemy = .6

    class BattleSettings:
        """Settings to make interaction easier.
           :__health_scissors:
               Health for enemy by type.
           :__health_enemy:
               Health for enemy by type.
           :__score:
               Score for an enemy by type.
           :__chances:
               Change for generation enemy.
           :__delay:
               Delay to create an enemy.
           :__attacks_per_second:
               The number of possible attacks per second.
           :__enemy_quantity:
               The maximum possible number of enemies on the screen.
           :__required_points:
               The required number of points to complete the level.
           :__movement_sides:
               Tuple of scissors key actions.
        """
        _m1_logic__health_scissors = {
            1: 4,
            2: 3,
            3: 2,
        }
        _m1_logic__health_enemy = {
            1: {EnemyType.Low: 1, EnemyType.Normal: 1, EnemyType.Heavy: 2},
            2: {EnemyType.Low: 1, EnemyType.Normal: 2, EnemyType.Heavy: 3},
            3: {EnemyType.Low: 1, EnemyType.Normal: 3, EnemyType.Heavy: 4},
        }
        _m1_logic__score = {
            1: {EnemyType.Low: 100, EnemyType.Normal: 250, EnemyType.Heavy: 500},
            2: {EnemyType.Low: 150, EnemyType.Normal: 300, EnemyType.Heavy: 600},
            3: {EnemyType.Low: 300, EnemyType.Normal: 400, EnemyType.Heavy: 700},
        }
        _m1_logic__chances = {
            1: (60, 25, 15),
        }
        _m1_logic__delay = {
            1: 0.3,
            2: 0.2,
            3: 0.1,
        }
        _m1_logic__attacks_per_second = {
            1: 4,
            2: 5,
            3: 6,
        }
        _m1_logic__enemy_quantity = {
            1: 3,
            2: 5,
            3: 6,
        }
        _m1_logic__required_points = {
            1: 3000,
            2: 5000,
            3: 8000,
        }
        _m1_logic__movement_sides = (Side.LEFT, Side.RIGHT, Side.UP, Side.DOWN, Side.SPACE)

    class GameStatus:
        """
        """
        Pause = 0
        Play = 1

    class Audio:
        """Audio control.
           :Attack:
               Call on attack action.
           :DestroyEnemy:
               Call when destroy enemy with none type of `EnemyType.Heavy`.
           :DestroyEnemyHeavy:
               Call when destroy enemy type is `EnemyType.Heavy`.
           :StartGame:
               Call on initialization game.
           :MainTheme:
               Call on after initialization
           :ScissorsDamaged:
               Call when scissors get damage.
           :ScissorsDestroyed:
               Call when scissors is destroyed.
        """
        Attack = "minigames/battle/sounds/attack.ogg"
        DestroyEnemy = "minigames/battle/sounds/enemy_destroyed_normal.ogg"
        DestroyEnemyHeavy = "minigames/battle/sounds/enemy_destroyed_heavy.ogg"
        StartGame = "minigames/battle/sounds/go_start.wav"
        
        MainTheme_lvl_1 = "images/ost/country_theme_4.mp3"
        MainTheme_lvl_2 = "images/ost/map_theme.mp3"
        MainTheme_lvl_3 = "images/ost/country_theme_5.mp3"
        
        ScissorsDamaged = "minigames/battle/sounds/scissors_damage.ogg"
        ScissorsDestroyed = "minigames/battle/sounds/scissors_destroyed.ogg"

    class AnimationDelay:
        """Animation delay control.
           :EnemySwap: (float)
               Delay for swap picture of enemy (1/2)
           :SecondsByAttack: (float)
               For how many seconds the attacks should be calculated.
           :TakedDamage: (float)
               Delay for swap picture after taked damage.
        """
        EnemySwap = .3
        SecondsByAttack = 1.
        TakedDamage = .3

    class Boundaries:
        """Boundaries of game actions.
           Responsible for limiting the flight of elements off the screen.
        """
        LEFT = 350
        RIGHT = 1580
        UP = 0
        DOWN = 1080

    class MovableSpeed:
        """Interaction speed control.
           :ScissorsLEFT/ScissorsRIGHT/ScissorsUP/ScissorsDOWN: (int)
               Responsible for the speed of the scissors in a specific direction.
           :Shot:
               Shot movement speed.
           :Enemy:
               Enemy projectiles speed.
        """
        ScissorsLEFT = {1: 20, 2: 30, 3: 45}
        ScissorsRIGHT = {1: 20, 2: 30, 3: 45}
        ScissorsUP = {1: 15, }
        ScissorsDOWN = {1: 15, }
        Shot = {1: 10, }
        Enemy = {1: 1, }

    class Enemy(renpy.store.object):
        _m1_logic__texture = {EnemyType.Low: ["minigames/battle/images/enemies/low_1.png", "minigames/battle/images/enemies/low_2.png"],
                     EnemyType.Normal: ["minigames/battle/images/enemies/normal_1.png", "minigames/battle/images/enemies/normal_2.png"],
                     EnemyType.Heavy: ["minigames/battle/images/enemies/heavy_1.png", "minigames/battle/images/enemies/heavy_2.png"]}
        _m1_logic__destroyed = ["minigames/battle/images/enemies/destroy_1.png", "minigames/battle/images/enemies/destroy_2.png"]
        _m1_logic__damaged = "minigames/battle/images/enemies/heavy_damage.png"
        def __init__(
            self,
            etype,
            level,
            support_level
        ):
            self.etype = etype
            self.health = BattleSettings._m1_logic__health_enemy.get(level, BattleSettings._m1_logic__health_enemy.get(support_level,
                          {EnemyType.Low: 1, EnemyType.Normal: 1, EnemyType.Heavy: 2})).get(etype, 1)
            self.texture = self._m1_logic__texture[etype]
            self.score = BattleSettings._m1_logic__score.get(level, BattleSettings._m1_logic__score.get(support_level,
                         {EnemyType.Low: 100, EnemyType.Normal: 250, EnemyType.Heavy: 500})).get(etype, 100)
            self.current_frame = self.last_st = 0
            self.quantity_frames = len(self.texture)
            self.damaged = False
            self.size = self.get_image.render(0, 0, 0, 0).get_size()
            self.x, self.y = self.generate_position()
            self.destroy = False
            self.speed = MovableSpeed.Enemy.get(level, MovableSpeed.Enemy.get(support_level, 1))
        
        def generate_position(self):
            return (random.randint(Boundaries.LEFT, Boundaries.RIGHT - self.sizex), random.randint(Boundaries.UP, Boundaries.UP + 200))
        
        @property
        def sizex(self):
            return self.size[0]
        
        @property
        def sizey(self):
            return self.size[1]
        
        @property
        def is_alive(self):
            return 0 < self.health
        
        @property
        def get_image(self):
            if self.damaged: return im.FactorScale(self._m1_logic__damaged, Scaled.Enemy)
            if self.is_alive: return im.FactorScale(self.texture[self.current_frame], Scaled.Enemy)
            return im.FactorScale(self._m1_logic__destroyed[self.current_frame], Scaled.Enemy)
        
        def set_frame(self, frame):
            self.current_frame = frame
        
        def get_damage(self):
            self.health -= 1
        
        def move(self):
            self.y += self.speed
        
        def concerns(self, obj):
            if not self.is_alive: return False
            return (((self.x <= obj.x <= self.x + self.sizex or self.x <= obj.x + obj.sizex <= self.x + self.sizex) or
                     (obj.x <= self.x <= obj.x + obj.sizex or obj.x <= self.x + self.sizex <= obj.x + obj.sizex)) and
                    ((self.y <= obj.y <= self.y + self.sizey or self.y <= obj.y + obj.sizex <= self.y + self.sizey) or
                     (obj.y <= self.y <= obj.y + obj.sizey or obj.y <= self.y + self.sizey <= obj.y + obj.sizey)))

    class Shot(renpy.store.object):
        def __init__(
            self,
            position,
            level,
            support_level
        ):
            self.img = Circle(color="#afc7c1", radius=6)
            self.x, self.y = position
            self.is_hit = False
            self.size = self.img.render(0, 0, 0, 0).get_size()
            self.speed = MovableSpeed.Shot.get(level, MovableSpeed.Shot.get(support_level, 10))
        
        @property
        def sizex(self):
            return self.size[0]
        
        @property
        def sizey(self):
            return self.size[1]
        
        def move(self):
            self.y -= self.speed

    class Scissors(renpy.store.object):
        def __init__(
            self,
            idle,
            movement,
            level,
            support_level,
            damages=[],
            health=3,
        ):
            self.idle = im.FactorScale(idle, Scaled.Scissors)
            self.movement = im.FactorScale(movement, Scaled.Scissors)
            self.damages = [im.FactorScale(img, Scaled.Scissors) for img in damages]
            self.maximal_health = self.health = health
            self.size = self.movement.render(0, 0, 0, 0).get_size()
            self.x, self.y = random.randint(Boundaries.LEFT, Boundaries.RIGHT - self.size[0]), Boundaries.DOWN-self.size[1]
            self.last_attack_time = self.damage_type = 0
            self.last_taked_damage = -1
            self.damaged = False
            self.shots = []
            self.is_attacked = False
            self.level = level
            self.support_level = support_level
        
        def get_damage(self):
            self.health -= 1
            self.damaged = True
            self.damage_type = 1
        
        @property
        def sizex(self):
            return self.size[0]
        
        @property
        def sizey(self):
            return self.size[1]
        
        def movable(self, side):
            if side == Side.LEFT: self.x -= MovableSpeed.ScissorsLEFT.get(self.level, MovableSpeed.ScissorsLEFT.get(self.support_level, 20))
            if side == Side.RIGHT: self.x += MovableSpeed.ScissorsRIGHT.get(self.level, MovableSpeed.ScissorsRIGHT.get(self.support_level, 20))
            if side == Side.UP: self.y -= MovableSpeed.ScissorsUP.get(self.level, MovableSpeed.ScissorsUP.get(self.support_level, 15))
            if side == Side.DOWN: self.y += MovableSpeed.ScissorsDOWN.get(self.level, MovableSpeed.ScissorsDOWN.get(self.support_level, 15))
            self.x = min(max(Boundaries.LEFT, self.x), Boundaries.RIGHT - self.sizex)
            self.y = max(min(Boundaries.DOWN - self.sizey, self.y), 0)

    class BattleAPI(renpy.display.core.Displayable):
        """API for interaction with minigame elements.
        """
        _m1_logic__path_to = "minigames/battle/images/"
        def __init__(
            self,
            level=1,
            support_level=1,
            **kwargs
        ):
            super(self.__class__, self).__init__(**kwargs)
            self.main_scissors = Scissors(idle=self._m1_logic__path_to + "scissors/idle.png", movement=self._m1_logic__path_to + "scissors/movement.png",
                                          damages=[self._m1_logic__path_to + "scissors/damage_1.png", self._m1_logic__path_to + "scissors/damage_2.png"],
                                          health=BattleSettings._m1_logic__health_scissors.get(level, BattleSettings._m1_logic__health_scissors.get(support_level, 3)),
                                          level=level, support_level=support_level)
            self.quantity = BattleSettings._m1_logic__attacks_per_second.get(level,
                            BattleSettings._m1_logic__attacks_per_second.get(support_level, 3))
            self.chances = BattleSettings._m1_logic__chances.get(level,
                           BattleSettings._m1_logic__chances.get(support_level, (60, 35, 15)))
            self.delay_spawn = BattleSettings._m1_logic__delay.get(level,
                               BattleSettings._m1_logic__delay.get(support_level, 1.3))
            self.enemy_quantity = BattleSettings._m1_logic__enemy_quantity.get(level,
                                  BattleSettings._m1_logic__enemy_quantity.get(support_level, 3))
            self.needed = BattleSettings._m1_logic__required_points.get(level,
                          BattleSettings._m1_logic__required_points.get(support_level, 5000))
            self.level = level
            self.support_level = support_level
            self.enemies = []
            self.score = 0
            self.status = GameStatus.Play
            self.st = -1
        
        def take_score(self, score):
            self.score += score
        
        @property
        def get_scissors_texture(self):
            return (self.main_scissors.damages[self.main_scissors.damage_type] if (self.main_scissors.damaged and self.main_scissors.damages)
                    else (self.main_scissors.movement if self.main_scissors.is_attacked else self.main_scissors.idle))
        
        def damage_from(self, enemy):
            if not enemy.is_alive or enemy.damaged:
                return
            self.main_scissors.get_damage()
            self.main_scissors.last_taked_damage = self.st
            enemy.health = 0
            enemy.set_frame(0)
            renpy.play(Audio.ScissorsDestroyed if self.is_game_over else Audio.ScissorsDamaged, channel="sound")
        
        def is_passed_attack_time(self, st):
            return self.main_scissors.last_attack_time + AnimationDelay.SecondsByAttack/self.quantity < st
        
        @property
        def is_passed_damage_time(self):
            return self.main_scissors.last_taked_damage + AnimationDelay.TakedDamage < self.st
        
        def is_passed_swap_time(self, enemy):
            return enemy.last_st + AnimationDelay.EnemySwap < self.st
        
        def render(self, width, height, st, at):
            if self.st > st or self.st == -1:
                for enemy in self.enemies:
                    enemy.last_st = st
                self.main_scissors.last_attack_time = st
            self.st = st
            if self.is_passed_attack_time(st): self.main_scissors.is_attacked = False
            if self.main_scissors.damaged and self.is_passed_damage_time:
                self.main_scissors.damaged = False
                self.main_scissors.damage_type = 0
            rv = renpy.render(renpy.store.Null(), width, height, st, at)
            main_texture = renpy.render(self.get_scissors_texture,
                                        width, height, st, at)
            rv.blit(main_texture, (self.main_scissors.x, self.main_scissors.y))
            for shot in self.main_scissors.shots:
                if shot.is_hit: continue
                rv.blit(renpy.render(shot.img, width, height, st, at), (shot.x, shot.y))
                if self.status is GameStatus.Play: shot.move()
                for enemy in self.enemies:
                    if enemy.concerns(shot):
                        enemy.get_damage()
                        shot.is_hit = True
                        if not enemy.is_alive:
                            self.take_score(enemy.score)
                            
                            if enemy.etype is EnemyType.Low:
                                
                                if miss_nur_shaley_job == True:
                                    rs = renpy.random.randint(0,2)
                                    if rs == 0:
                                        renpy.notify("Well done.")
                                    if rs == 1:
                                        renpy.notify("You really are good at this.")
                                    if rs == 2:
                                        renpy.notify("That's the right cut.")
                                if miss_tavern_job == True:
                                    rs = renpy.random.randint(0,5)
                                    if rs == 0:
                                        renpy.notify("There's one, on the left too!")
                                    if rs == 1:
                                        renpy.notify("Going down, fella!")
                                    if rs == 2:
                                        renpy.notify("Best cut!")
                                    if rs == 3:
                                        renpy.notify("Major cut!")
                                    if rs == 4:
                                        renpy.notify("Clean cut.")
                                    if rs == 5:
                                        renpy.notify("One the right, on the right!")
                            
                            if enemy.etype is EnemyType.Normal:
                                
                                if miss_nur_shaley_job == True:
                                    rs = renpy.random.randint(0,2)
                                    if rs == 0:
                                        renpy.notify("Well done.")
                                    if rs == 1:
                                        renpy.notify("You really are good at this.")
                                    if rs == 2:
                                        renpy.notify("That's the right cut.")
                                if miss_tavern_job == True:
                                    rs = renpy.random.randint(0,5)
                                    if rs == 0:
                                        renpy.notify("There's one, on the left too!")
                                    if rs == 1:
                                        renpy.notify("Going down, fella!")
                                    if rs == 2:
                                        renpy.notify("Best cut!")
                                    if rs == 3:
                                        renpy.notify("Major cut!")
                                    if rs == 4:
                                        renpy.notify("Clean cut.")
                                    if rs == 5:
                                        renpy.notify("One the right, on the right!")
                            
                            if enemy.etype is EnemyType.Heavy:
                                
                                if miss_nur_shaley_job == True:
                                    rs = renpy.random.randint(0,3)
                                    if rs == 0:
                                        renpy.notify("Well done.")
                                    if rs == 1:
                                        renpy.notify("You really are good at this.")
                                    if rs == 2:
                                        renpy.notify("That's the right cut.")
                                    if rs == 3:
                                        renpy.notify("That was a big one?.. ")
                                if miss_tavern_job == True:
                                    rs = renpy.random.randint(0,5)
                                    if rs == 0:
                                        renpy.notify("There's one, on the left too!")
                                    if rs == 1:
                                        renpy.notify("Going down, fella!")
                                    if rs == 2:
                                        renpy.notify("Best cut!")
                                    if rs == 3:
                                        renpy.notify("Major cut!")
                                    if rs == 4:
                                        renpy.notify("Clean cut.")
                                    if rs == 5:
                                        renpy.notify("One the right, on the right!")
                            
                            else: renpy.play(Audio.DestroyEnemy, channel="sound")
                            enemy.set_frame(0)
                        else: enemy.damaged = True
                        break
            self.main_scissors.shots = [shot for shot in self.main_scissors.shots
                                        if (shot.y > Boundaries.UP - shot.sizey or shot.is_hit)]
            for enemy in self.enemies:
                rv.blit(renpy.render(enemy.get_image, width, height, st, at),
                        (enemy.x, enemy.y))
                if self.is_passed_swap_time(enemy):
                    enemy.last_st = st
                    enemy.set_frame(0 if enemy.current_frame == 1 else 1)
                    if all([enemy.current_frame == 1,
                            not enemy.is_alive]): enemy.destroy = True
                    if enemy.damaged: enemy.damaged = False
                if self.status is GameStatus.Play: enemy.move()
                if enemy.concerns(self.main_scissors):
                    if not self.main_scissors.damaged:
                        self.damage_from(enemy)
                elif Boundaries.DOWN - enemy.sizey < enemy.y:
                    self.damage_from(enemy)
            self.enemies = [enemy for enemy in self.enemies if not enemy.destroy]
            if self.is_game_over or self.is_complete: renpy.sound.stop(channel="music", fadeout=2)
            renpy.redraw(self, 0)
            return rv
        
        @property
        def is_complete(self):
            return self.score >= self.needed
        
        @property
        def is_game_over(self):
            return 1 > self.main_scissors.health
        
        def attack(self, st):
            if all([not self.is_passed_attack_time(st), self.main_scissors.is_attacked]): return
            self.main_scissors.last_attack_time = st
            renpy.play(Audio.Attack, channel="sound")
            self.main_scissors.shots.append(
                                            Shot(
                                                position=(int(self.main_scissors.x + 35),
                                                          int(self.main_scissors.y - 20)),
                                                level=self.level,
                                                support_level=self.support_level
                                            )
            )
            self.main_scissors.is_attacked = True
        
        def event(self, event, x, y, st):
            if self.status is GameStatus.Pause: return
            if event.type == 769: return;
            if not hasattr(event, "scancode"): return
            if event.scancode not in BattleSettings._m1_logic__movement_sides: return
            if event.scancode == Side.SPACE:
                if event.repeat == 1: return
                self.attack(st)
                return
            self.main_scissors.movable(event.scancode)
        
        def generate_enemy(self):
            """Generation enemy by pseudo random.
            """
            if len(self.enemies) == self.enemy_quantity: return
            royale = []
            for _ in xrange(self.chances[EnemyType.Low]):
                royale.append(EnemyType.Low)
            for _ in xrange(self.chances[EnemyType.Normal]):
                royale.append(EnemyType.Normal)
            for _ in xrange(self.chances[EnemyType.Heavy]):
                royale.append(EnemyType.Heavy)
            random.shuffle(royale)
            enemy_type = random.choice(royale)
            enemy = Enemy(etype=enemy_type,
                          level=self.level,
                          support_level=self.support_level)
            for _ in self.enemies:
                while _.concerns(enemy):
                    enemy.x, enemy.y = enemy.generate_position()
            self.enemies.append(enemy)
# Decompiled by unrpyc: https://github.com/CensoredUsername/unrpyc
