diff --git a/NS.py b/NS.py index 18f99a8..fa0cfd6 100644 --- a/NS.py +++ b/NS.py @@ -36,7 +36,7 @@ from lib.pgfw.pgfw.Sprite import Sprite, RainbowSprite from lib.pgfw.pgfw.Animation import Animation from lib.pgfw.pgfw.extension import ( get_step, get_step_relative, get_delta, reflect_angle, get_distance, render_box, get_hsla_color, get_hue_shifted_surface, - get_color_swapped_surface, load_frames, fill_colorkey, get_segments + get_color_swapped_surface, load_frames, fill_colorkey, get_segments, get_boxed_surface ) from lib.pgfw.pgfw.gfx_extension import aa_filled_polygon @@ -158,15 +158,15 @@ class NS(Game, Animation): { "time": { - "int": ["timer-max-time", "timer-start-time", "timer-addition", "sword-delay", "attract-gif-length", - "attract-board-length", "attract-reset-countdown", "level-select-reset-countdown", - "level-select-press-length"], + "int": ["timer-max-time", "timer-start-level-1", "timer-start-level-2", "timer-start-level-3", "timer-addition-level-1", + "timer-addition-level-2", "timer-addition-level-3", "sword-delay", "attract-gif-length", "attract-board-length", + "attract-reset-countdown", "level-select-reset-countdown", "level-select-press-length"], "float": "timer-warning-start" }, "boss": { "float": ["damage-per-hit-level-1", "damage-per-hit-level-2", "damage-per-hit-level-3"], - "int": ["cooldown-level-1", "cooldown-level-2", "cooldown-level-3"] + "int": ["cooldown-level-1", "cooldown-level-2", "cooldown-level-3", "first-combo-delay"] }, "input": { @@ -1579,6 +1579,7 @@ class Platform(GameChild): if self.get_edge_pressed() is not None: if self.get_edge_pressed() != self.previously_pressed_edge: self.previously_pressed_edge = self.get_edge_pressed() + self.press_elapsed = 0 else: self.press_elapsed += self.get_game().time_filter.get_last_frame_duration() else: @@ -1723,7 +1724,7 @@ class Chemtrails(Sprite): @param parent PGFW game object that initialized this object """ - Sprite.__init__(self, parent, 42) + Sprite.__init__(self, parent, 125) for directory in sorted(iglob(join(self.get_resource("littleSlimeGoop"), "[0-9]_*/"))): self.add_frameset(switch=True) self.load_from_path(directory, True) @@ -1800,13 +1801,8 @@ class Chemtrails(Sprite): boss = self.get_game().boss queue = boss.queue if self.orientation == queue[self.queue_index]: - self.timer.add_time(self.get_configuration("time", "timer-addition")) - if boss.level_index == 0: - boss.health.decrease(self.get_configuration("boss", "damage-per-hit-level-1")) - elif boss.level_index == 1: - boss.health.decrease(self.get_configuration("boss", "damage-per-hit-level-2")) - elif boss.level_index == 2: - boss.health.decrease(self.get_configuration("boss", "damage-per-hit-level-3")) + self.timer.add_time(self.get_configuration("time", f"timer-addition-level-{boss.level_index + 1}")) + boss.health.decrease(self.get_configuration("boss", f"damage-per-hit-level-{boss.level_index + 1}")) self.queue_index += 1 boss.last_attack = self.orientation boss.sword.block() @@ -1863,7 +1859,17 @@ class Timer(Meter): rect = background.get_rect() rect.bottomright = dsr.right - 6, dsr.bottom - 4 self.setup(background, rect, 53, (0, 0, 255), - self.get_configuration("time", "timer-start-time"), "scrapeIcons/scrapeIcons_07.png") + self.get_configuration("time", "timer-start-level-1"), "scrapeIcons/scrapeIcons_07.png") + + def reset(self): + """ + Account for the differences in time per level by setting a custom amount based on the boss's level + """ + super().reset() + # The difference between level 1 and the current level is how much to remove from the timer + difference = self.get_configuration("time", "timer-start-level-1") - \ + self.get_configuration("time", f"timer-start-level-{self.get_game().boss.level_index + 1}") + self.change(-difference) def add_time(self, amount): self.change(amount) @@ -1944,16 +1950,7 @@ class Boss(Animation): animations that control attacks, effects, and dialog. """ Animation.__init__(self, parent) - hue_shift = 30 - if self.get_configuration("display", "effects"): - self.kool_man = RainbowSprite(self, load(self.get_resource("Kool_man_waah.png")).convert_alpha(), hue_shift) - self.spoopy = RainbowSprite(self, load(self.get_resource("Spoopy.png")).convert_alpha(), hue_shift) - else: - self.kool_man = Sprite(self) - self.kool_man.load_from_path("Kool_man_waah.png", True) - self.spoopy = Sprite(self) - self.spoopy.load_from_path("Spoopy.png", True) - # Set up sprites with boil and hurt animations + # Set up sprites with boil, hit, and intro animations self.boss_sprites = [] self.boss_sprite_arms = [] for path in (pathlib.Path(self.get_resource("koolAnimations")), pathlib.Path(self.get_resource("alienAnimations")), @@ -1964,12 +1961,11 @@ class Boss(Animation): self.boss_sprites[-1].load_from_path(path.joinpath(f"{prefix}Boil"), True) self.boss_sprites[-1].add_frameset(name="hurt", switch=True) self.boss_sprites[-1].load_from_path(path.joinpath(f"{prefix}Hit"), True) - if prefix == "alien": - self.boss_sprites[-1].add_frameset(name="entrance", switch=True) - self.boss_sprites[-1].load_from_path(path.joinpath("alienIntro"), True) + self.boss_sprites[-1].add_frameset(name="entrance", switch=True) + self.boss_sprites[-1].load_from_path(path.joinpath(f"{prefix}Intro"), True) self.boss_sprites[-1].location.topleft = 207, 10 # Set the arm to its own sprite - self.boss_sprite_arms.append(Sprite(self, 42)) + self.boss_sprite_arms.append(Sprite(self, 60)) # Map the strings used to indicate direction in the animations directory to the IDs defined in the script name_map = { "U": NS.N, @@ -2142,7 +2138,9 @@ class Boss(Animation): def activate(self): self.active = True - def combo(self, delay=2500): + def combo(self, delay=None): + if delay is None: + delay = self.get_configuration("boss", f"cooldown-level-{self.level_index + 1}") self.queue = None if self.get_game().serial_enabled(): self.get_game().reset_arduino() @@ -2294,13 +2292,13 @@ class Boss(Animation): platform.get_opposite_of_edge(third)] elif self.level_index == 2: if self.health.amount > 90: - length = 3 - elif self.health.amount > 70: length = 4 - elif self.health.amount > 40: + elif self.health.amount > 70: length = 5 - else: + elif self.health.amount > 40: length = 6 + else: + length = 8 while len(self.queue) < length: while True: orientation = randint(0, 5) @@ -2384,12 +2382,7 @@ class Boss(Animation): def end_dialogue(self): self.get_game().dialogue.deactivate() if not self.battle_finished: - if self.level_index == 0: - self.combo(self.get_configuration("boss", "cooldown-level-1")) - elif self.level_index == 1: - self.combo(self.get_configuration("boss", "cooldown-level-2")) - elif self.level_index == 2: - self.combo(self.get_configuration("boss", "cooldown-level-3")) + self.combo(self.get_configuration("boss", "first-combo-delay")) else: self.get_game().wipe.start(self.transition_after_battle) @@ -2476,10 +2469,7 @@ class Boss(Animation): def enter_boss(self): self.level_sprite().unhide() self.level_sprite().get_current_frameset().reset() - if self.level_index == 1: - self.level_sprite().set_frameset("entrance") - else: - self.level_sprite().set_frameset("normal") + self.level_sprite().set_frameset("entrance") def level_sprite(self, level_index=None): """ @@ -2769,7 +2759,7 @@ class Sword(Animation): self.parent.level_sprite_arm().unhide() self.parent.level_sprite_arm().set_frameset(str(position)) if len(self.parent.unbrandished) > 0: - self.play(self.swab, delay=self.get_configuration("time", "sword-delay") - 42 * 4, play_once=True, position=position) + self.play(self.swab, delay=self.get_configuration("time", "sword-delay") - 60 * 4, play_once=True, position=position) def swab(self, position): """ @@ -2903,7 +2893,8 @@ class Ending(Animation): self.slime_bag.load_from_path(self.get_resource("Introduction_slime_bag.png"), True) self.slime_bag.location.center = self.get_display_surface().get_rect().centerx, 300 self.tony_avatar = load(self.get_resource("Introduction_tony_avatar.png")).convert() - self.font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 64) + self.time_font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 64) + self.rank_font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 18) self.register(self.start, self.start_wipe) def reset(self): @@ -2920,7 +2911,14 @@ class Ending(Animation): self.defeated_level_index = level_index self.active = True self.play(self.start, delay=3000, play_once=True) - foreground = self.font.render(str(self.get_game().most_recent_score), False, (180, 150, 20), (255, 255, 255)).convert_alpha() + foreground = get_boxed_surface( + self.time_font.render(str(self.get_game().most_recent_score), False, (180, 150, 20), (255, 255, 255)).convert_alpha(), + background=(255, 255, 255), padding=(30, 0)) + rank = self.rank_font.render(f"rank {self.rank()}", False, (180, 150, 20), (255, 255, 255)) + rank = pygame.transform.rotate(rank, 270) + rank_rect = rank.get_rect() + rank_rect.midright = foreground.get_rect().midright + foreground.blit(rank, rank_rect) dsr = self.get_display_surface().get_rect() self.text = RainbowSprite(self, foreground, 180, 200) self.text.location.midtop = dsr.centerx, 80 @@ -2933,15 +2931,21 @@ class Ending(Animation): self.play(self.start_wipe, delay=20000, play_once=True) self.get_audio().play_bgm("end") + def rank(self): + """ + Get the rank of the currently displaying score + """ + rank = 0 + for score in sorted([score for score in self.get_game().scores if score.level_index == self.defeated_level_index]): + rank += 1 + if score == self.get_game().most_recent_score: + break + return rank + def start(self): dialogue = self.get_game().dialogue if self.get_configuration("system", "enable-level-select"): - rank = 0 - for score in sorted([score for score in self.get_game().scores if score.level_index == self.defeated_level_index]): - rank += 1 - if score == self.get_game().most_recent_score: - break - text = f"You vanquished my goon and got the #{rank} rank! Well done, slime bag.\n" + text = f"You vanquished my goon and got the #{self.rank()} rank! Well done, slime bag.\n" if self.defeated_level_index == 2: dialogue.set_name("Tony") text += "You made your father proud today. I love you child." diff --git a/config b/config index b3f8739..b9e08ec 100644 --- a/config +++ b/config @@ -38,10 +38,11 @@ lives-level-select-mode = 1 [boss] damage-per-hit-level-1 = 4.0 damage-per-hit-level-2 = 2.5 -damage-per-hit-level-3 = 1.5 -cooldown-level-1 = 1300 -cooldown-level-2 = 1150 -cooldown-level-3 = 700 +damage-per-hit-level-3 = 1.75 +cooldown-level-1 = 2500 +cooldown-level-2 = 2100 +cooldown-level-3 = 1300 +first-combo-delay = 1300 [mouse] visible = no @@ -62,8 +63,12 @@ serial = True [time] timer-max-time = 10000 -timer-start-time = 7000 -timer-addition = 1000 +timer-start-level-1 = 8000 +timer-start-level-2 = 7000 +timer-start-level-3 = 6000 +timer-addition-level-1 = 1000 +timer-addition-level-2 = 700 +timer-addition-level-3 = 700 timer-warning-start = 0.4 sword-delay = 300 attract-gif-length = 10000 diff --git a/resource/scores b/resource/scores index b4d6882..771bf50 100644 --- a/resource/scores +++ b/resource/scores @@ -1,13 +1,10 @@ -52418 0 -57797 0 -70979 0 -78301 0 -79581 0 -66858 1 -98128 1 -100960 1 -95569 2 -96481 2 -113904 2 -120571 2 -122294 2 +10202 0 +10317 0 +10403 0 +16483 0 +24404 0 +59424 0 +71763 1 +75161 2 +86762 2 +96171 2