import pygame from engine.plants import RARITY_COLORS from engine.relics import RELIC_POOL from ui.relics_overview import RelicsOverview from ui.scaling import make_window, request_quit, to_logical WIN_W, WIN_H = 1040, 720 BG = (24, 30, 24) TEXT = (230, 235, 230) MUTED = (150, 155, 150) HINT = (255, 220, 120) CARD = (36, 44, 36) BORDER = (90, 120, 90) SKIP = (60, 60, 60) class RelicChoiceScreen: """Pick one of the offered roguelike blessings (or skip).""" def __init__(self, relics, stage, owned=()): pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) pygame.display.set_caption("Plants — Blessing") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 36) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) self.small = pygame.font.SysFont("segoeui", 16) self.tiny = pygame.font.SysFont("segoeui", 13) self.relics = relics self.stage = stage self.owned = list(owned) self.overview = None self.cards = [] cw, ch = 250, 300 gap = 26 total = len(relics) * cw + (len(relics) - 1) * gap x0 = (WIN_W - total) // 2 y = 190 for i, r in enumerate(relics): self.cards.append((r, pygame.Rect(x0 + i * (cw + gap), y, cw, ch))) self.skip_rect = pygame.Rect(WIN_W // 2 - 80, WIN_H - 70, 160, 40) self.all_btn = pygame.Rect(24, WIN_H - 70, 160, 40) def run(self): running = True result = None while running: self.clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: request_quit() running = False elif event.type == pygame.MOUSEWHEEL: if self.overview is not None: self.overview.handle_wheel(event.y) elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: pos = to_logical(event.pos, self.scale) if self.overview is not None: if self.overview.handle_click(pos) == "close": self.overview = None continue for r, rect in self.cards: if rect.collidepoint(pos): result = r running = False break else: if self.skip_rect.collidepoint(pos): result = None running = False elif self.all_btn.collidepoint(pos): self.overview = RelicsOverview( self.screen, self.bold, self.small, self.tiny, RELIC_POOL, self.owned) self._draw() pygame.transform.smoothscale(self.screen, self.window.get_size(), self.window) pygame.display.flip() return result def _wrap(self, text, font, width): words = text.split() lines = [] cur = "" for w in words: if font.size(cur + " " + w)[0] > width and cur: lines.append(cur) cur = w else: cur = (cur + " " + w).strip() if cur: lines.append(cur) return lines def _draw(self): self.screen.fill(BG) if self.overview is not None: self.overview.draw(pygame.mouse.get_pos()) return t = self.font.render("Choose a blessing", True, HINT) self.screen.blit(t, t.get_rect(center=(WIN_W // 2, 60))) st = self.small.render( f"Stage {self.stage} defeated — pick a relic for the rest of the tower.", True, MUTED) self.screen.blit(st, st.get_rect(center=(WIN_W // 2, 110))) mouse = pygame.mouse.get_pos() for r, rect in self.cards: hover = rect.collidepoint(mouse) pygame.draw.rect(self.screen, CARD, rect, border_radius=10) pygame.draw.rect(self.screen, HINT if hover else BORDER, rect, 2, border_radius=10) name = self.bold.render(r.name, True, HINT) self.screen.blit(name, name.get_rect(midtop=(rect.centerx, rect.y + 16))) rar = self.small.render(r.rarity.capitalize(), True, RARITY_COLORS.get(r.rarity, MUTED)) self.screen.blit(rar, rar.get_rect(midtop=(rect.centerx, rect.y + 50))) y = rect.y + 92 for ln in self._wrap(r.desc, self.small, rect.w - 24)[:7]: lr = self.small.render(ln, True, TEXT) self.screen.blit(lr, lr.get_rect(midtop=(rect.centerx, y))) y += 24 pygame.draw.rect(self.screen, SKIP, self.skip_rect, border_radius=8) pygame.draw.rect(self.screen, (150, 150, 150), self.skip_rect, 2, border_radius=8) sk = self.small.render("Skip", True, TEXT) self.screen.blit(sk, sk.get_rect(center=self.skip_rect.center)) pygame.draw.rect(self.screen, (70, 90, 70), self.all_btn, border_radius=8) pygame.draw.rect(self.screen, BORDER, self.all_btn, 2, border_radius=8) ab = self.small.render("All blessings", True, TEXT) self.screen.blit(ab, ab.get_rect(center=self.all_btn.center)) hint = self.tiny.render("Blessings persist for the rest of this tower run", True, MUTED) self.screen.blit(hint, hint.get_rect(center=(WIN_W // 2, WIN_H - 20)))