##################################################################### # -*- coding: iso-8859-1 -*- # # # # Frets on Fire # # Copyright (C) 2006 Sami Kyöstilä # # # # This program is free software; you can redistribute it and/or # # modify it under the terms of the GNU General Public License # # as published by the Free Software Foundation; either version 2 # # of the License, or (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program; if not, write to the Free Software # # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # # MA 02110-1301, USA. # ##################################################################### from Scene import SceneServer, SceneClient from Menu import Menu import Player import Dialogs import Song import Data import Theme from Audio import Sound from Language import _ import pygame import math import random from OpenGL.GL import * class GameResultsScene: pass class GameResultsSceneServer(GameResultsScene, SceneServer): pass class GameResultsSceneClient(GameResultsScene, SceneClient): def createClient(self, libraryName, songName): self.libraryName = libraryName self.songName = songName self.stars = 0 self.accuracy = 0 self.counter = 0 self.showHighscores = False self.highscoreIndex = None self.taunt = None self.uploadingScores = False self.nextScene = None items = [ (_("Replay"), self.replay), (_("Change Song"), self.changeSong), (_("Quit to Main Menu"), self.quit), ] self.menu = Menu(self.engine, items, onCancel = self.quit, pos = (.2, .5)) self.engine.resource.load(self, "song", lambda: Song.loadSong(self.engine, songName, library = self.libraryName, notesOnly = True), onLoad = self.songLoaded) self.engine.loadSvgDrawing(self, "background", "keyboard.svg") Dialogs.showLoadingScreen(self.engine, lambda: self.song, text = _("Chilling...")) def keyPressed(self, key, unicode): ret = SceneClient.keyPressed(self, key, unicode) c = self.controls.keyPressed(key) if self.song and (c in [Player.KEY1, Player.KEY2, Player.CANCEL, Player.ACTION1, Player.ACTION2] or key == pygame.K_RETURN): scores = self.song.info.getHighscores(self.player.difficulty) if not scores or self.player.score > scores[-1][0] or len(scores) < 5: if self.player.cheating: Dialogs.showMessage(self.engine, _("No highscores for cheaters!")) else: name = Dialogs.getText(self.engine, _("%d points is a new high score! Please enter your name:") % self.player.score, self.player.name) if name: self.player.name = name self.highscoreIndex = self.song.info.addHighscore(self.player.difficulty, self.player.score, self.stars, self.player.name) self.song.info.save() if self.engine.config.get("game", "uploadscores"): self.uploadingScores = True fn = lambda: self.song.info.uploadHighscores(self.engine.config.get("game", "uploadurl"), self.song.getHash()) self.engine.resource.load(self, "uploadResult", fn) self.showHighscores = True self.engine.view.pushLayer(self.menu) return True return ret def hidden(self): SceneClient.hidden(self) if self.nextScene: self.nextScene() def quit(self): self.engine.view.popLayer(self.menu) self.session.world.finishGame() def replay(self): self.engine.view.popLayer(self.menu) self.session.world.deleteScene(self) self.nextScene = lambda: self.session.world.createScene("GuitarScene", libraryName = self.libraryName, songName = self.songName) def changeSong(self): self.engine.view.popLayer(self.menu) self.session.world.deleteScene(self) self.nextScene = lambda: self.session.world.createScene("SongChoosingScene") def songLoaded(self, song): song.difficulty = self.player.difficulty notes = len([1 for time, event in song.track.getAllEvents() if isinstance(event, Song.Note)]) if notes: # 5 stars at 95%, 4 stars at 75% f = float(self.player.notesHit) / notes self.stars = int(5.0 * (f + .05)) self.accuracy = int(100.0 * f) taunt = None if self.player.score == 0: taunt = "jurgen1.ogg" elif self.accuracy >= 99.0: taunt = "myhero.ogg" elif self.stars in [0, 1]: taunt = random.choice(["jurgen2.ogg", "jurgen3.ogg", "jurgen4.ogg", "jurgen5.ogg"]) elif self.stars == 5: taunt = random.choice(["perfect1.ogg", "perfect2.ogg", "perfect3.ogg"]) if taunt: self.engine.resource.load(self, "taunt", lambda: Sound(self.engine.resource.fileName(taunt))) def run(self, ticks): SceneClient.run(self, ticks) self.time += ticks / 50.0 self.counter += ticks if self.counter > 5000 and self.taunt: self.taunt.setVolume(self.engine.config.get("audio", "guitarvol")) self.taunt.play() self.taunt = None def anim(self, start, ticks): return min(1.0, float(max(start, self.counter)) / ticks) def render(self, visibility, topMost): SceneClient.render(self, visibility, topMost) bigFont = self.engine.data.bigFont font = self.engine.data.font v = ((1 - visibility) ** 2) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_COLOR_MATERIAL) self.engine.view.setOrthogonalProjection(normalize = True) try: t = self.time / 100 w, h, = self.engine.view.geometry[2:4] r = .5 self.background.transform.reset() self.background.transform.translate(v * 2 * w + w / 2 + math.cos(t / 2) * w / 2 * r, h / 2 + math.sin(t) * h / 2 * r) self.background.transform.rotate(-t) self.background.transform.scale(math.sin(t / 8) + 2, math.sin(t / 8) + 2) self.background.draw() if self.showHighscores: scale = 0.0017 d = self.player.difficulty text = _("Highest Scores (%s)") % d w, h = font.getStringSize(text) Theme.setBaseColor(1 - v) font.render(text, (.5 - w / 2, .05 - v)) x = .1 y = .15 + v for i, scores in enumerate(self.song.info.getHighscores(d)): score, stars, name = scores if i == self.highscoreIndex and (self.time % 10.0) < 5.0: Theme.setSelectedColor(1 - v) else: Theme.setBaseColor(1 - v) font.render("%d." % (i + 1), (x, y), scale = scale) font.render(unicode(score), (x + .05, y), scale = scale) font.render(unicode(Data.STAR2 * stars + Data.STAR1 * (5 - stars)), (x + .25, y), scale = scale * .9) font.render(name, (x + .5, y), scale = scale) y += h if self.uploadingScores and self.uploadResult is None: Theme.setBaseColor(1 - v) font.render(_("Uploading Scores..."), (.05, .7 + v), scale = 0.001) return Theme.setBaseColor(1 - v) text = _("Song Finished!") w, h = font.getStringSize(text) font.render(text, (.5 - w / 2, .05 - v)) text = "%d" % (self.player.score * self.anim(1000, 2000)) w, h = bigFont.getStringSize(text) bigFont.render(text, (.5 - w / 2, .11 + v + (1.0 - self.anim(0, 1000) ** 3)), scale = 0.0025) if self.counter > 1000: scale = 0.0017 text = (Data.STAR2 * self.stars + Data.STAR1 * (5 - self.stars)) w, h = bigFont.getStringSize(Data.STAR1, scale = scale) x = .5 - w * len(text) / 2 for i, ch in enumerate(text): bigFont.render(ch, (x + 100 * (1.0 - self.anim(1000 + i * 200, 1000 + (i + 1) * 200)) ** 2, .35 + v), scale = scale) x += w if self.counter > 2500: text = _("Accuracy: %d%%") % self.accuracy w, h = font.getStringSize(text) font.render(text, (.5 - w / 2, .55 + v)) text = _("Longest note streak: %d") % self.player.longestStreak w, h = font.getStringSize(text) font.render(text, (.5 - w / 2, .55 + h + v)) finally: self.engine.view.resetProjection()