diff --git a/data/themes/MegaLight GH3/menu/maintext.png b/data/themes/MegaLight GH3/menu/maintext.png index c76a06177..8c7ee16b0 100644 Binary files a/data/themes/MegaLight GH3/menu/maintext.png and b/data/themes/MegaLight GH3/menu/maintext.png differ diff --git a/data/themes/MegaLight GH3/menu/maintext_gh3.png b/data/themes/MegaLight GH3/menu/maintext_gh3.png deleted file mode 100644 index 8c7ee16b0..000000000 Binary files a/data/themes/MegaLight GH3/menu/maintext_gh3.png and /dev/null differ diff --git a/data/themes/MegaLight GH3/theme.ini b/data/themes/MegaLight GH3/theme.ini index 6ca6ad35c..49133b8a0 100644 --- a/data/themes/MegaLight GH3/theme.ini +++ b/data/themes/MegaLight GH3/theme.ini @@ -8,6 +8,8 @@ song_name_text_color = #FFFFFF song_info_display_scale = 0.0012 loading_phrase = Keepin' in clean +use_solo_submenu = False + #copy these values to the theme.ini if you want it to have GH3 coloration flames_color = #BF5C05 fretS_color = #4CB2E5 diff --git a/data/themes/MegaLight V4/rockmeter.ini b/data/themes/MegaLight V4/rockmeter.ini index 64fecb0cf..65c218c27 100644 --- a/data/themes/MegaLight V4/rockmeter.ini +++ b/data/themes/MegaLight V4/rockmeter.ini @@ -171,3 +171,17 @@ alignment = center color = #FFFFFF00 fadeTo = #FFFFFFFF transitionTime = 1000.0 + +[layer19:Text] +text = "%i Note Streak" % (50*int(streak/50)) +ypos = .7 +xpos = .5 +shadow = True +alignment = center + +[layer19:fx0:Fade] +color = #FFFF0000 +fadeTo = #FFFF00FF +transitionTime = 1.0 +transitionTimeOut = 1000.0 +condition = streak % 50 == 0 and streak > 0 and self.triggerPick() diff --git a/data/themes/Uberlight/CustomTheme.py b/data/themes/Uberlight/CustomTheme.py deleted file mode 100644 index 478e44ac6..000000000 --- a/data/themes/Uberlight/CustomTheme.py +++ /dev/null @@ -1,7 +0,0 @@ -from Theme import Theme -class CustomTheme(Theme): - def __init__(self, path, name, iniFile = False): - Theme.__init__(self, path, name) - self.songListDisplay = 3 - self.doNecksRender = False - self.loadingPhrase = ["Loading"] \ No newline at end of file diff --git a/data/themes/Uberlight/frets/fretbuttons.png b/data/themes/Uberlight/frets/fretbuttons.png index e1572a524..6cea1d470 100644 Binary files a/data/themes/Uberlight/frets/fretbuttons.png and b/data/themes/Uberlight/frets/fretbuttons.png differ diff --git a/data/themes/Uberlight/menu/maintext.png b/data/themes/Uberlight/menu/maintext.png deleted file mode 100644 index 075541a94..000000000 Binary files a/data/themes/Uberlight/menu/maintext.png and /dev/null differ diff --git a/data/themes/Uberlight/notes/drum/notes.png b/data/themes/Uberlight/notes/drum/notes.png index 71f581632..1f4fc7c11 100644 Binary files a/data/themes/Uberlight/notes/drum/notes.png and b/data/themes/Uberlight/notes/drum/notes.png differ diff --git a/data/themes/Uberlight/notes/notes.png b/data/themes/Uberlight/notes/notes.png index 268e88561..c497334dd 100644 Binary files a/data/themes/Uberlight/notes/notes.png and b/data/themes/Uberlight/notes/notes.png differ diff --git a/data/themes/Uberlight/rockmeter.ini b/data/themes/Uberlight/rockmeter.ini index f7d71dab7..94ccfbe4b 100644 --- a/data/themes/Uberlight/rockmeter.ini +++ b/data/themes/Uberlight/rockmeter.ini @@ -1,30 +1,10 @@ -[layer0:Image] -texture = base.png -xpos = .07 -ypos = .26 -xscale = 10 -yscale = 220 -valignment = bottom -rect = (0,1,0,rock) - -[layer1:Image] -texture = base.png -xscale = 250 -yscale = 10 +[layer0:Text] +text = "Rock:%03i%s Power:%03i%s Part:%s %ix" %(rock*100, "%", power*100, "%", part, multiplier) xpos = .5 -ypos = .08 +ypos = .06 alignment = center -rect = (0,power,0,1) - -[layer2:Text] -text = score -font = scoreFont -xpos = .9 -ypos =.88 -[layer3:Text] -text = "%dx" % multiplier -font = scoreFont -xpos = .5 -ypos = .04 -alignment = center \ No newline at end of file +[layer1:Text] +text = "Score:%07i" %score +xpos = .62 +ypos = .8 diff --git a/data/themes/Uberlight/rockmeter/base.png b/data/themes/Uberlight/rockmeter/base.png deleted file mode 100644 index b2eb48a29..000000000 Binary files a/data/themes/Uberlight/rockmeter/base.png and /dev/null differ diff --git a/data/themes/Uberlight/tails/bigtail1.png b/data/themes/Uberlight/tails/bigtail1.png index 997dfe6ab..619a7dcc0 100644 Binary files a/data/themes/Uberlight/tails/bigtail1.png and b/data/themes/Uberlight/tails/bigtail1.png differ diff --git a/data/themes/Uberlight/tails/kill1.png b/data/themes/Uberlight/tails/kill1.png index 9b5b50ae0..101533242 100644 Binary files a/data/themes/Uberlight/tails/kill1.png and b/data/themes/Uberlight/tails/kill1.png differ diff --git a/data/themes/Uberlight/tails/tail1.png b/data/themes/Uberlight/tails/tail1.png index 997dfe6ab..619a7dcc0 100644 Binary files a/data/themes/Uberlight/tails/tail1.png and b/data/themes/Uberlight/tails/tail1.png differ diff --git a/data/themes/Uberlight/theme.ini b/data/themes/Uberlight/theme.ini new file mode 100644 index 000000000..463014630 --- /dev/null +++ b/data/themes/Uberlight/theme.ini @@ -0,0 +1,4 @@ +[theme] +render_necks = False +song_list_display = 3 +loading_phrase = _ diff --git a/src/Dialogs.py b/src/Dialogs.py index c508eb211..eb1abd3ef 100644 --- a/src/Dialogs.py +++ b/src/Dialogs.py @@ -2087,12 +2087,58 @@ def render(self, visibility, topMost): else: wrapCenteredText(font, (x,y), self.text, scale = self.fScale, rightMargin = self.rMargin, linespace = self.lspacing) +#nhydock - expanding on LoadingSplashScreen so there can be overlay and song dependant backgrounds +class SongLoadingSplashScreen(LoadingSplashScreen): + def __init__(self, engine, text, songName, libraryName): + super(SongLoadingSplashScreen, self).__init__(engine, text) + + self.engine.loadImgDrawing(self, "songBack", os.path.join(libraryName, songName, "loading.png")) + if self.songBack: + self.engine.loadImgDrawing(self, "loadingImg", os.path.join("themes", self.engine.data.themeLabel, "loading_overlay.png")) + + def render(self, visibility, topMost): + self.engine.view.setViewport(1,0) + font = self.engine.data.loadingFont #MFH - new font support + + if not font: + return + + with self.engine.view.orthogonalProjection(normalize = True): + v = (1 - visibility) ** 2 + fadeScreen(v) + w, h = self.engine.view.geometry[2:4] + + self.engine.theme.setBaseColor(1 - v) + self.engine.drawImage(self.songBack, scale = (1.0,-1.0), coord = (w/2,h/2), stretched = 3) + self.engine.drawImage(self.loadingImg, scale = (1.0,-1.0), coord = (w/2,h/2), stretched = 3) + w, h = font.getStringSize(self.text, scale=self.fScale) + + x = self.loadingx + y = self.loadingy - h / 2 + v * .5 + + #akedrou - support for Loading Text Color + c1,c2,c3 = self.textColor + glColor3f(c1,c2,c3) + + # evilynux - Made text about 2 times smaller (as requested by worldrave) + if self.allowtext: + if self.theme == 1: + wrapCenteredText(font, (x,y), self.text, scale = self.fScale, rightMargin = self.rMargin, linespace = self.lspacing, allowshadowoffset = True, shadowoffset = (self.engine.theme.shadowoffsetx, self.engine.theme.shadowoffsety)) + else: + wrapCenteredText(font, (x,y), self.text, scale = self.fScale, rightMargin = self.rMargin, linespace = self.lspacing) + def showLoadingSplashScreen(engine, text = _("Loading...")): splash = LoadingSplashScreen(engine, text) engine.view.pushLayer(splash) engine.run() return splash +def showSongLoadingSplashScreen(engine, songName, libraryName, text = _("Loading...")): + splash = SongLoadingSplashScreen(engine, text, songName, libraryName) + engine.view.pushLayer(splash) + engine.run() + return splash + def changeLoadingSplashScreenText(engine, splash, text=_("Loading...")): splash.text = text engine.run() diff --git a/src/Drum.py b/src/Drum.py index a92fc2560..ca16f3891 100644 --- a/src/Drum.py +++ b/src/Drum.py @@ -155,6 +155,31 @@ def loadNotes(self): engine.loadImgDrawing(self, "noteOpenAnimatedPower", get("animated_open_power.png")) engine.loadImgDrawing(self, "noteOpenAnimated", get("animated_open.png")) + size = (self.boardWidth/1.9, (self.boardWidth/self.strings)/3.0) + self.openVtx = np.array([[-size[0], .27, size[1]], + [size[0], .27, size[1]], + [-size[0], -.27, -size[1]], + [size[0], -.27, -size[1]]], + dtype=np.float32) + + self.noteTexCoord = [[np.array([[i/float(self.strings), s/6.0], + [(i+1)/float(self.strings), s/6.0], + [i/float(self.strings), (s+1)/6.0], + [(i+1)/float(self.strings), (s+1)/6.0]], + dtype=np.float32) + for i in range(self.strings)] for s in range(0,5,2)] + self.openTexCoord = [np.array([[0.0, s/6.0], + [1.0, s/6.0], + [0.0, (s+1)/6.0], + [1.0, (s+1)/6.0]], dtype=np.float32) for s in range(1,6,2)] + + self.animatedOpenTexCoord = [[np.array([[0.0, s/float(self.noteSpinFrames)], + [1.0, s/float(self.noteSpinFrames)], + [0.0, (s+1)/float(self.noteSpinFrames)], + [1.0, (s+1)/float(self.noteSpinFrames)]], + dtype=np.float32) + for i in range(self.strings)] for s in range(self.noteSpinFrames)] + else: defaultOpenNote = False @@ -202,6 +227,123 @@ def loadFrets(self): else: engine.loadImgDrawing(self, "keytexopen", get("keytex_open.png")) + def renderNote(self, length, sustain, color, tailOnly = False, isTappable = False, fret = 0, spNote = False, isOpen = False, spAct = False): + + if tailOnly: + return + + if self.twoDnote == True: + tailOnly = True + + y = 0 + if spNote: + y += 1 + elif self.starPowerActive: + y += 2 + + if isOpen: + vtx = self.openVtx + if self.noteSpin: + texCoord = self.animatedOpenTexCoord[self.noteSpinFrameIndex] + if spNote == True: + noteImage = self.noteOpenAnimatedPower + elif self.starPowerActive == True: #death_au: drum sp active notes. + noteImage = self.noteOpenAnimatedPowerActive + else: + noteImage = self.noteOpenAnimated + if not noteImage: + noteImage = self.noteButtons + texCoord = self.openTexCoord[y] + else: + if not noteImage: + noteImage = self.noteButtons + texCoord = self.noteTexCoord[y] + else: + fret -= 1 + vtx = self.noteVtx + if self.noteSpin: + texCoord = self.animatedNoteTexCoord[self.noteSpinFrameIndex][fret] + if spNote: + noteImage = self.noteAnimatedPower + elif self.starPowerActive: + noteImage = self.noteAnimatedPowerActive + else: + noteImage = self.noteAnimatedNormal + if not noteImage: + noteImage = self.noteButtons + texCoord = self.noteTexCoord[y][fret] + else: + noteImage = self.noteButtons + texCoord = self.noteTexCoord[y][fret] + + self.engine.draw3Dtex(noteImage, vertex = vtx, texcoord = texCoord, + scale = (1,1,0), rot = (30,1,0,0), multiples = False, color = color) + + else: #3d Notes + shaders.setVar("Material",color,"notes") + + self.notepos = self.engine.theme.drumnotepos + self.noterot = self.engine.theme.drumnoterot + + if fret == 0: + fret = 4 #fret 4 is angled, get fret 2 :) + #fret = 2 #compensating for this in drum. + elif fret == 4: + fret = 0 + + if isOpen and self.openMesh is not None: + meshObj = self.openMesh + elif spNote and self.starMesh is not None: + meshObj = self.starMesh + else: + meshObj = self.noteMesh + + glPushMatrix() + glEnable(GL_DEPTH_TEST) + glDepthMask(1) + glShadeModel(GL_SMOOTH) + + if not isOpen: + if spNote and self.threeDspin: + glRotate(90 + self.time/3, 0, 1, 0) + elif not spNote and self.noterotate: + glRotatef(90, 0, 1, 0) + glRotatef(-90, 1, 0, 0) + + if fret >= 0 and fret <= 4: + glRotate(self.noterot[fret], 0, 0, 1) + glTranslatef(0, self.notepos[fret], 0) + + texture = None + if self.notetex: + + if isOpen: + if self.opentexture_star: + texture = self.opentexture_star + elif self.opentexture_stara and self.starPowerActive: + texture = self.opentexture_stara + elif self.opentexture: + texture = self.opentexture + + elif self.startex and spNote: + texture = getattr(self,"startex"+chr(97+fret)) + + elif self.spActTex and spAct: + texture = self.spActTex + + elif self.staratex and self.starPowerActive: + texture = getattr(self,"staratex"+chr(97+fret)) + + else: + texture = getattr(self,"notetex"+chr(97+fret)) + + self.render3DNote(texture, meshObj, color, isTappable) + + glDepthMask(0) + glPopMatrix() + glDisable(GL_DEPTH_TEST) + + def renderFrets(self, visibility, song, controls): w = self.boardWidth / self.strings size = (.22, .22) diff --git a/src/Font.py b/src/Font.py index c79fd9388..cc31d076b 100644 --- a/src/Font.py +++ b/src/Font.py @@ -145,7 +145,7 @@ def setCustomGlyph(self, character, texture): """ pass - def render(self, text, pos = (0, 0), rotate = 0, scale = DEFAULT_SCALE, shadowoffset = (.0022, .0005), align = LEFT, new = False, shadow = False, outline = False): + def render(self, text, pos = (0, 0), rotate = 0, scale = DEFAULT_SCALE, shadowoffset = (.0022, .0005), align = LEFT, new = False, shadow = False, outline = False, shadowOpacity = 1.0): """ Draw some text. @@ -211,7 +211,7 @@ def drawSquare(w,h,tw,th): if self.shadow or shadow: with cmgl.PushedAttrib(GL_CURRENT_BIT): - glColor4f(0, 0, 0, glGetDoublev(GL_CURRENT_COLOR)[3]) + glColor4f(0, 0, 0, glGetDoublev(GL_CURRENT_COLOR)[3]*shadowOpacity) with cmgl.PushedMatrix(): glTranslatef(shadowoffset[0], shadowoffset[1], 0) drawSquare(w,h,tw,th) diff --git a/src/GameEngine.py b/src/GameEngine.py index 167802b70..92db97f0a 100644 --- a/src/GameEngine.py +++ b/src/GameEngine.py @@ -279,24 +279,16 @@ def sortOptionsByKey(dict): Config.define("game", "script_lyric_pos", int, 0, text = _("Script Lyric Position"), options = {0: _("Bottom"), 1: _("Top")}, tipText = _("Display script lyrics at either the bottom or top of the screen.")) #MFH - script.txt lyric display position Config.define("game", "hopo_indicator", bool, False, text = _("Show HO/PO Indicator"), options = {False: _("No"), True: _("Yes")}, tipText = _("If enabled, 'HOPO' will appear in game. When there are HOPO notes active, it will turn white.")) Config.define("performance", "star_score_updates", int, 1, text = _("Star Updates"), options = {0: _("On Hit"), 1: _("Score Change")}, tipText = _("If set to 'On Hit', your star score will only be checked when you hit a note. If set to 'Score Change', your star score will constantly update. (This is affected by the 'Performance' quickset)")) -Config.define("performance", "star_continuous_fillup", bool, True, text = _("Partial Star Continuous Fillup"), options = {False: _("No"), True: _("Yes")}, tipText = _("Sets whether your partial stars will fill up gradually ('Yes') or in chunks. (This is affected by the 'Performance' quickset)")) #stump Config.define("game", "kill_debug", bool, False, text = _("Effects Debug"), options = {False: _("Off"), True: _("On")}, tipText = _("If enabled, will show on-screen the raw data of your killswitch/whammy.")) Config.define("game", "show_unused_text_events", bool, False, text = _("Show Unused Events"), options = {False: _("No"), True: _("Yes")}, tipText = _("If enabled, various MIDI events not used by the game will be shown on-screen.")) Config.define("game", "rb_midi_lyrics", int, 1, text = _("Show Lyrics in All Modes"), options = {0: _("No"), 1: _("Single Player"), 2: _("Always")}, tipText = _("Sets whether or not MIDI lyrics will be displayed in modes without a vocalist. 'Single Player' will only show lyrics when in Solo modes.")) Config.define("game", "rb_midi_sections", int, 0, text = _("Show MIDI Sections"), options = {0: _("No"), 1: _("Single Player"), 2: _("Always")}, tipText = _("Sets whether or not to scroll the names of sections as marked in the MIDI files.")) -Config.define("performance", "in_game_stats", int, 0, text = _("Show In-Game Stats"), options = {0: _("Off"), 1: _("By Theme"), 2: _("On")}, tipText = _("Sets whether or not to show detailed stats as you play. 'By Theme' leaves it to the theme creator.")) -Config.define("game", "in_game_stars", int, 1, text = _("Show Stars In-Game"), options = {0: _("Off"), 1: _("By Theme"), 2: _("On")}, tipText = _("Sets whether or not to show your star score as you play. 'By Theme' leaves it to the theme creator.")) -Config.define("game", "partial_stars", int, 1, text = _("Show Partial Stars"), options = {0: _("Off"), 1: _("On")}, tipText = _("Sets whether or not to show partial stars, if available")) Config.define("game", "hopo_debug_disp", int, 0, text = _("HO/PO Debug"), options = {0: _("Off"), 1: _("On")}, tipText = _("If enabled, various log messages will be recorded regarding the HO/PO system. Please leave this disabled if submitting logs for bug reports unless you are certain it is necessary.")) Config.define("game", "gsolo_accuracy_disp", int, 1, text = _("Show Solo Stats"), options = {0: _("Off"), 1: _("Percent"), 2: _("Detail")}, tipText = _("Sets whether to show your solo results when you finish a solo. 'Percent' will only show the percentage, while 'Detail' includes additional information.")) Config.define("game", "decimal_places", int, 1, text = _("Stat Decimal Places"), options = dict([(n, n) for n in range(0, 3)]), tipText = _("Determines how many decimal places will be noted in displaying stats.")) Config.define("game", "star_scoring", int, 3, text = _("Star Scoring Style"), options = sortOptionsByKey({0: _("Accuracy"), 1: _("GH"), 2: _("RB"), 3: _("RB+GH"), 4: _("RB2")}), tipText = _("Sets which system to use to calculate your star score."))#MFH Config.define("game", "gsolo_acc_pos", int, 3, text = _("Solo Stat Positioning"), options = sortOptionsByKey({0: _("Right"), 1: _("Center"), 2: _("Left"), 3: _("Rock Band")}), tipText = _("Sets where your solo result stats will be displayed."))#MFH,(racer: added RB) -Config.define("game", "game_time", int, 1, text = _("Time Display Format"), options = {0: _("Off"), 1: _("Countdown"), 2: _("Elapsed")}, tipText = _("Sets whether the song time is displayed as time elapsed, time remaining, or not at all")) #MFH -Config.define("game", "in_game_font_shadowing", bool, False, text = _("In-Game Font Shadow"), options = {False: _("Off"), True: _("On")}, tipText = _("Sets whether or not a shadowed font will be used, if available.")) Config.define("game", "solo_frame", int, 1, text = _("Show Solo Frame"), options = {0: _("Off"), 1: _("On")}, tipText = _("Sets whether to show a frame around the solo stats, if available.")) -Config.define("game", "starfx", bool, True, text = _("GH SP Lights"), options = {True: _("On"), False: _("Off")}, tipText = _("Sets whether to fade images over the starpower bulbs in GH themes when fully lit."))#blazingamer -Config.define("game", "small_rb_mult", int, 1, text = _("RB Small 1x Multiplier"), options = {0: _("Off"), 1: _("By Theme"), 2: _("On")}, tipText = _("When enabled, RB-type themes will have a smaller mult image when the multiplier is at 1x. 'By Theme' leaves it to the theme creator."))#blazingamer Config.define("game", "midi_lyric_mode", int, 2, text = _("Lyric Display Mode"), options = {0: _("Scrolling"), 1: _("Simple Lines"), 2: _("2-Line")}, tipText = _("Sets the display mode for MIDI lyrics. Both 'Simple Lines' and '2-Line' will show as single phrases when playing the vocal part.")) Config.define("game", "vocal_scroll", int, 2, text = _("Lyric Speed Mode"), options = sortOptionsByKey({0: _("BPM"), 1: _("Difficulty"), 2: _("BPM & Diff")}), tipText = _("Sets what determines the speed of the scrolling lyrics.")) Config.define("game", "vocal_speed", int, 100, text = _("Lyric Speed Percent"), options = dict([(n, n) for n in range(10, 410, 10)]), tipText = _("Sets how quickly lyrics will scroll.")) @@ -957,19 +949,21 @@ def draw3Dtex(self, image, vertex, texcoord, coord = None, scale = None, rot = N if depth == True: glDepthMask(1) - triangVtx = np.array( + if not isinstance(vertex, np.ndarray): + vertex = np.array( [[ vertex[0], vertscale, vertex[1]], [ vertex[2], vertscale, vertex[1]], [ vertex[0], -vertscale, vertex[3]], [ vertex[2], -vertscale, vertex[3]]], dtype=np.float32) - - textriangVtx = np.array( + + if not isinstance(texcoord, np.ndarray): + texcoord = np.array( [[texcoord[0], texcoord[1]], [texcoord[2], texcoord[1]], [texcoord[0], texcoord[3]], [texcoord[2], texcoord[3]]], dtype=np.float32) - - cmgl.drawArrays(GL_TRIANGLE_STRIP, vertices=triangVtx, colors=col_array, texcoords=textriangVtx) + + cmgl.drawArrays(GL_TRIANGLE_STRIP, vertices=vertex, colors=col_array, texcoords=texcoord) if depth == True: glDepthMask(0) diff --git a/src/GuitarScene.py b/src/GuitarScene.py index 01a76bc2e..e3652ff5e 100644 --- a/src/GuitarScene.py +++ b/src/GuitarScene.py @@ -88,7 +88,8 @@ def __init__(self, engine, libraryName, songName): phrase = self.sinfo.loadingPhrase if phrase == "": phrase = random.choice(self.engine.theme.loadingPhrase) - splash = Dialogs.showLoadingSplashScreen(self.engine, phrase + " \n " + _("Initializing...")) + #splash = Dialogs.showLoadingSplashScreen(self.engine, phrase + " \n " + _("Initializing...")) + splash = Dialogs.showSongLoadingSplashScreen(self.engine, songName, libraryName, phrase + " \n " + _("Initializing...")) Dialogs.changeLoadingSplashScreenText(self.engine, splash, phrase + " \n " + _("Initializing...")) @@ -108,7 +109,8 @@ def __init__(self, engine, libraryName, songName): # self.gameMode2p = 6 # self.gamePlayers = 2 - + if self.gameMode1p == 1: + self.practiceMode = True #MFH - check for party mode (akedrou TODO - fix/remove party mode!) # if self.gameMode2p == 2: @@ -2226,6 +2228,7 @@ def resetVariablesToDefaults(self): for player in self.playerList: player.reset() self.stage.reset() + self.stage.rockmeter.reset() self.enteredCode = [] self.jurgPlayer = [False for i in self.playerList] #Jurgen hasn't played the restarted song =P @@ -3071,12 +3074,7 @@ def handleJurgen(self, pos): def rockmeterDecrease(self, playerNum, vScore = 0): i = playerNum - if self.instruments[i].isVocal: - rockMinusAmount = 500 * (3 - vScore) - self.rock[i] -= rockMinusAmount - if (not self.coOpRB) and (self.rock[i]/self.rockMax <= 0.667) and ((self.rock[i]+rockMinusAmount)/self.rockMax > 0.667): #akedrou - self.playersInGreen -= 1 - return + rockMinusAmount = 0 #akedrou - simplify the various incarnations of minusRock. if self.instruments[i].isDrum: self.drumStart = True @@ -3090,6 +3088,13 @@ def rockmeterDecrease(self, playerNum, vScore = 0): if not self.failingEnabled or (self.gameMode == PRACTICE): return + if self.instruments[i].isVocal: + rockMinusAmount = 500 * (3 - vScore) + self.rock[i] -= rockMinusAmount + if (not self.coOpRB) and (self.rock[i]/self.rockMax <= 0.667) and ((self.rock[i]+rockMinusAmount)/self.rockMax > 0.667): #akedrou + self.playersInGreen -= 1 + return + if self.battle and self.numOfPlayers > 1: #battle mode if self.notesMissed[i]: self.minusRock[i] += self.minGain/self.multi[i] diff --git a/src/Instrument.py b/src/Instrument.py index 293582111..0af24e8e2 100644 --- a/src/Instrument.py +++ b/src/Instrument.py @@ -434,6 +434,25 @@ def loadNotes(self): else: engine.loadImgDrawing(self, "noteButtons", get("notes.png")) + size = (self.boardWidth/self.strings/2, self.boardWidth/self.strings/2) + self.noteVtx = np.array([[-size[0], .27, size[1]], + [size[0], .27, size[1]], + [-size[0], -.27, -size[1]], + [size[0], -.27, -size[1]]], + dtype=np.float32) + + self.noteTexCoord = [[np.array([[i/float(self.strings), s/6.0], + [(i+1)/float(self.strings), s/6.0], + [i/float(self.strings), (s+1)/6.0], + [(i+1)/float(self.strings), (s+1)/6.0]], + dtype=np.float32) + for i in range(self.strings)] for s in range(6)] + self.animatedNoteTexCoord = [[np.array([[i/float(self.strings), s/float(self.noteSpinFrames)], + [(i+1)/float(self.strings), s/float(self.noteSpinFrames)], + [i/float(self.strings), (s+1)/float(self.noteSpinFrames)], + [(i+1)/float(self.strings), (s+1)/float(self.noteSpinFrames)]], + dtype=np.float32) + for i in range(self.strings)] for s in range(self.noteSpinFrames)] else: defaultNote = False @@ -928,6 +947,59 @@ def renderFlames(self, song, pos, controls): if self.hitflamesAnim and self.HCount2 > self.HFrameLimit2: self.HCount2 = 0 + #group rendering of 2D notes into method + def render3DNote(self, texture, model, color, isTappable): + if texture: + glColor3f(1,1,1) + glEnable(GL_TEXTURE_2D) + texture.texture.bind() + glMatrixMode(GL_TEXTURE) + glScalef(1, -1, 1) + glMatrixMode(GL_MODELVIEW) + glScalef(self.boardScaleX, self.boardScaleY, 1) + + if isTappable: + mesh = "Mesh_001" + else: + mesh = "Mesh" + + model.render(mesh) + + if shaders.enable("notes"): + shaders.setVar("isTextured",True) + model.render(mesh) + shaders.disable() + + glMatrixMode(GL_TEXTURE) + glLoadIdentity() + glMatrixMode(GL_MODELVIEW) + glDisable(GL_TEXTURE_2D) + + else: + #mesh = outer ring (black) + #mesh_001 = main note (key color) + #mesh_002 = top (spot or hopo if no mesh_003) + #mesh_003 = hopo bump (hopo color) + + #death_au: fixed 3D note colours + glColor4f(*color) + if shaders.enable("notes"): + shaders.setVar("isTextured",False) + model.render("Mesh_001") + shaders.disable() + glColor3f(self.spotColor[0], self.spotColor[1], self.spotColor[2]) + if isTappable: + if self.hopoColor[0] == -2: + glColor4f(*color) + else: + glColor3f(self.hopoColor[0], self.hopoColor[1], self.hopoColor[2]) + if(model.find("Mesh_003")) == True: + model.render("Mesh_003") + glColor3f(self.spotColor[0], self.spotColor[1], self.spotColor[2]) + model.render("Mesh_002") + glColor3f(self.meshColor[0], self.meshColor[1], self.meshColor[2]) + model.render("Mesh") + def renderNote(self, length, sustain, color, tailOnly = False, isTappable = False, fret = 0, spNote = False, isOpen = False, spAct = False): if tailOnly: @@ -940,107 +1012,49 @@ def renderNote(self, length, sustain, color, tailOnly = False, isTappable = Fals noteImage = self.noteButtons tailOnly = True - - if isOpen: - size = (self.boardWidth/1.9, (self.boardWidth/self.strings)/3.0) - texSize = (0,1) - if spNote == True: - if self.noteOpenAnimatedPower: - noteImage = self.noteDrumOpenAnimatedPower - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) - else: - texY = (3.0*0.166667,4.0*0.166667) - - elif self.starPowerActive == True: #death_au: drum sp active notes. - if self.noteOpenAnimatedPowerActive: - noteImage = self.noteDrumOpenAnimatedPowerActive - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) + + y = 0 + if spNote: + y += 2 + elif self.starPowerActive: + y += 4 + if isTappable: + y += 1 + + if self.noteSpin: + texCoord = self.animatedNoteTexCoord[self.noteSpinFrameIndex][fret] + if isTappable: + if spNote: + noteImage = self.noteAnimatedPowerHOPO + elif self.starPowerActive: + noteImage = self.noteAnimatedPowerActiveHOPO else: - texY = (5.0*0.166667,1.0) - + noteImage = self.noteAnimatedHOPO else: - if self.noteOpenAnimated: - noteImage = self.noteDrumOpenAnimated - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) + if spNote: + noteImage = self.noteAnimatedPower + elif self.starPowerActive: + noteImage = self.noteAnimatedPowerActive else: - texY = (1.0*0.166667,2.0*0.166667) - + noteImage = self.noteAnimatedNormal + if not noteImage: + noteImage = self.noteButtons + texCoord = self.noteTexCoord[y][fret] else: - size = (self.boardWidth/self.strings/2, self.boardWidth/self.strings/2) - if self.isDrum: - fret -= 1 - texSize = (fret/self.lanenumber,fret/self.lanenumber+1/self.lanenumber) - if spNote == True: - if isTappable: - if self.noteAnimatedPowerHOPO: - noteImage = self.noteAnimatedPowerHOPO - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) - else: - texY = (3*0.166667, 4*0.166667) - else: - if self.noteAnimatedPower: - noteImage = self.noteAnimatedPower - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) - else: - texY = (2*0.166667, 3*0.166667) - - elif self.starPowerActive: - if isTappable: - if self.noteAnimatedPowerActiveHOPO: - noteImage = self.noteAnimatedPowerActiveHOPO - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) - else: - texY = (5*0.166667, 1) - else: - if self.noteAnimatedPowerActive: - noteImage = self.noteAnimatedPowerActive - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) - else: - texY = (4*0.166667, 5*0.166667) - - else: - if isTappable: - if self.noteAnimatedHOPO: - noteImage = self.noteAnimatedHOPO - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) - else: - texY = (1*0.166667, 2*0.166667) - else: - if self.noteAnimatedNormal: - noteImage = self.noteAnimatedNormal - texY = (self.noteSpinFrameIndex*.066667, (self.noteSpinFrameIndex - 1)*.066667) - else: - texY = (0, 1*0.166667) - - self.engine.draw3Dtex(noteImage, vertex = (-size[0],size[1],size[0],-size[1]), texcoord = (texSize[0],texY[0],texSize[1],texY[1]), - scale = (1,1,0), rot = (30,1,0,0), multiples = False, color = color, vertscale = .27) + noteImage = self.noteButtons + texCoord = self.noteTexCoord[y][fret] + + self.engine.draw3Dtex(noteImage, vertex = self.noteVtx, texcoord = texCoord, + scale = (1,1,0), rot = (30,1,0,0), multiples = False, color = color) else: #3d Notes shaders.setVar("Material",color,"notes") - if self.isDrum: - self.notepos = self.engine.theme.drumnotepos - self.noterot = self.engine.theme.drumnoterot - else: - self.notepos = self.engine.theme.notepos - self.noterot = self.engine.theme.noterot - - #mesh = outer ring (black) - #mesh_001 = main note (key color) - #mesh_002 = top (spot or hopo if no mesh_003) - #mesh_003 = hopo bump (hopo color) - - if self.isDrum: - if fret == 0: - fret = 4 #fret 4 is angled, get fret 2 :) - #fret = 2 #compensating for this in drum. - elif fret == 4: - fret = 0 - - if spNote == True and self.starMesh is not None and isOpen == False: + self.notepos = self.engine.theme.notepos + self.noterot = self.engine.theme.noterot + + if spNote == True and self.starMesh is not None: meshObj = self.starMesh - elif isOpen == True and self.openMesh is not None: - meshObj = self.openMesh else: meshObj = self.noteMesh @@ -1049,95 +1063,28 @@ def renderNote(self, length, sustain, color, tailOnly = False, isTappable = Fals glDepthMask(1) glShadeModel(GL_SMOOTH) - if spNote == True and self.threeDspin == True and isOpen == False: + if spNote and self.threeDspin: glRotate(90 + self.time/3, 0, 1, 0) - if isOpen == False and spNote == False and self.noterotate == True: + elif not spNote and self.noterotate: glRotatef(90, 0, 1, 0) glRotatef(-90, 1, 0, 0) - if fret == 0: # green note/ drums open note - glRotate(self.noterot[0], 0, 0, 1), glTranslatef(0, self.notepos[0], 0) - elif fret == 1: # red note - glRotate(self.noterot[1], 0, 0, 1), glTranslatef(0, self.notepos[1], 0) - elif fret == 2: # yellow - glRotate(self.noterot[2], 0, 0, 1), glTranslatef(0, self.notepos[2], 0) - elif fret == 3:# blue note - glRotate(self.noterot[3], 0, 0, 1), glTranslatef(0, self.notepos[3], 0) - elif fret == 4:# orange note / green on drums - glRotate(self.noterot[4], 0, 0, 1), glTranslatef(0, self.notepos[4], 0) - - if isOpen: - if self.opentexture_stara and spNote==False and self.starPowerActive: - self.noteTex = self.opentexture_stara - - elif self.opentexture and spNote==False: - self.noteTex = self.opentexture - - elif self.opentexture_star and spNote==True: - self.noteTex = self.opentexture_star - - elif self.spActTex and isOpen == False and spNote == False and spAct and self.isDrum: - self.noteTex = self.spActTex - - elif self.staratex == True and self.starPowerActive and spNote == False and isOpen == False: - self.noteTex = getattr(self,"staratex"+chr(97+fret)) - - elif self.notetex == True and spNote == False and isOpen == False: - self.noteTex = getattr(self,"notetex"+chr(97+fret)) - - elif self.startex == True and spNote == True and isOpen == False: - self.noteTex = getattr(self,"startex"+chr(97+fret)) - - - glColor3f(1,1,1) - glEnable(GL_TEXTURE_2D) - self.noteTex.texture.bind() - glMatrixMode(GL_TEXTURE) - glScalef(1, -1, 1) - glMatrixMode(GL_MODELVIEW) - glScalef(self.boardScaleX, self.boardScaleY, 1) - - if isTappable: - mesh = "Mesh_001" + if fret >= 0 and fret <= 4: + glRotate(self.noterot[fret], 0, 0, 1) + glTranslatef(0, self.notepos[fret], 0) + + if self.notetex: + if self.startex and spNote: + texture = getattr(self,"startex"+chr(97+fret)) + elif self.staratex and self.starPowerActive: + texture = getattr(self,"staratex"+chr(97+fret)) + else: + texture = getattr(self,"notetex"+chr(97+fret)) else: - mesh = "Mesh" - - meshObj.render(mesh) - - if shaders.enable("notes"): - shaders.setVar("isTextured",True) - meshObj.render(mesh) - shaders.disable() - - glMatrixMode(GL_TEXTURE) - glLoadIdentity() - glMatrixMode(GL_MODELVIEW) - glDisable(GL_TEXTURE_2D) - - - if not self.noteTex: - #death_au: fixed 3D note colours - glColor4f(*color) - if isOpen == True and self.starPowerActive == False: - glColor4f(self.opencolor[0],self.opencolor[1],self.opencolor[2], 1) - if shaders.enable("notes"): - shaders.setVar("isTextured",False) - meshObj.render("Mesh_001") - shaders.disable() - glColor3f(self.spotColor[0], self.spotColor[1], self.spotColor[2]) - if isTappable: - if self.hopoColor[0] == -2: - glColor4f(*color) - else: - glColor3f(self.hopoColor[0], self.hopoColor[1], self.hopoColor[2]) - if(meshObj.find("Mesh_003")) == True: - meshObj.render("Mesh_003") - glColor3f(self.spotColor[0], self.spotColor[1], self.spotColor[2]) - meshObj.render("Mesh_002") - glColor3f(self.meshColor[0], self.meshColor[1], self.meshColor[2]) - meshObj.render("Mesh") - - + texture = None + + self.render3DNote(texture, meshObj, color, isTappable) + glDepthMask(0) glPopMatrix() glDisable(GL_DEPTH_TEST) diff --git a/src/MainMenu.py b/src/MainMenu.py index 293ea464e..76eea9442 100644 --- a/src/MainMenu.py +++ b/src/MainMenu.py @@ -150,14 +150,25 @@ def __init__(self, engine): ] self.opt_bkg_size = [float(i) for i in self.engine.theme.opt_bkg_size] - - strCareer = "" - strQuickplay = "" - strSolo = "" - strMultiplayer = "" - strTraining = "" - strSettings = "" - strQuit = "" + self.opt_text_color = self.engine.theme.hexToColor(self.engine.theme.opt_text_colorVar) + self.opt_selected_color = self.engine.theme.hexToColor(self.engine.theme.opt_selected_colorVar) + + if self.BGText: + strCareer = "" + strQuickplay = "" + strSolo = "" + strMultiplayer = "" + strTraining = "" + strSettings = "" + strQuit = "" + else: + strCareer = "Career" + strQuickplay = "Quickplay" + strSolo = "Solo" + strMultiplayer = "Multiplayer" + strTraining = "Training" + strSettings = "Settings" + strQuit = "Quit" multPlayerMenu = [ (_("Face-Off"), lambda: self.newLocalGame(multiplayer = FACEOFF)), @@ -193,8 +204,9 @@ def __init__(self, engine): ] + w, h, = self.engine.view.geometry[2:4] - self.menu = Menu(self.engine, mainMenu, onClose = lambda: self.engine.view.popLayer(self), pos = (12,12), textColor = self.opt_text_color, selectedColor = self.opt_selected_color) + self.menu = Menu(self.engine, mainMenu, onClose = lambda: self.engine.view.popLayer(self), pos = (self.menux, .75-(.75*self.menuy))) engine.mainMenu = self #Points engine.mainMenu to the one and only MainMenu object instance @@ -359,27 +371,28 @@ def render(self, visibility, topMost): #MFH - auto-scaling self.engine.drawImage(self.background, (1.0,-1.0), (w/2, h/2), stretched = 3) - numOfChoices = len(self.menu.choices) - for i in range(numOfChoices): - #Item selected - if self.menu.currentIndex == i: - xpos = (.5,1) - #Item unselected - else: - xpos = (0,.5) - #which item? - ypos = (1/float(numOfChoices) * i, 1/float(numOfChoices) * (i + 1)) - - textcoord = (w*self.menux,h*self.menuy-(h*self.main_menu_vspacing)*i) - sFactor = self.main_menu_scale - wFactor = xpos[1] - xpos[0] - hFactor = ypos[1] - ypos[0] - self.engine.drawImage(self.BGText, + if self.BGText: + numOfChoices = len(self.menu.choices) + for i in range(numOfChoices): + #Item selected + if self.menu.currentIndex == i: + xpos = (.5,1) + #Item unselected + else: + xpos = (0,.5) + #which item? + ypos = (1/float(numOfChoices) * i, 1/float(numOfChoices) * (i + 1)) + + textcoord = (w*self.menux,h*self.menuy-(h*self.main_menu_vspacing)*i) + sFactor = self.main_menu_scale + wFactor = xpos[1] - xpos[0] + hFactor = ypos[1] - ypos[0] + self.engine.drawImage(self.BGText, scale = (wFactor*sFactor,-hFactor*sFactor), coord = textcoord, rect = (xpos[0],xpos[1],ypos[0],ypos[1]), stretched = 11) - -#racer: added version tag to main menu: + + #racer: added version tag to main menu: if self.version != None: wfactor = (w * self.engine.theme.versiontagScale) / self.version.width1() self.engine.drawImage(self.version,( wfactor, -wfactor ),(w*self.engine.theme.versiontagposX, h*self.engine.theme.versiontagposY)) #worldrave - Added theme settings to control X+Y positions of versiontag. diff --git a/src/Menu.py b/src/Menu.py index 01320a42e..fd2fd7bf2 100644 --- a/src/Menu.py +++ b/src/Menu.py @@ -91,7 +91,7 @@ def getText(self, selected): return "%s: %s" % (self.text, self.values[self.valueIndex]) class Menu(Layer, KeyListener): - def __init__(self, engine, choices, name = None, onClose = None, onCancel = None, pos = (.2, .66 - .35), viewSize = 6, fadeScreen = False, font = "font", mainMenu = None, textColor = None, selectedColor = None, append_submenu_char = True, selectedIndex = None, showTips = True, selectedBox = False): + def __init__(self, engine, choices, name = None, onClose = None, onCancel = None, pos = (.2, .31), viewSize = 6, fadeScreen = False, font = "font", mainMenu = None, textColor = None, selectedColor = None, append_submenu_char = True, selectedIndex = None, showTips = True, selectedBox = False): self.engine = engine if self.engine.data.logClassInits == 1: @@ -424,8 +424,6 @@ def render(self, visibility, topMost): glRotate(v * 45, 0, 0, 1) scale = self.engine.theme.settingsmenuScale - if self.mainMenu and self.theme < 2 and i % 2 == 1:#8bit - scale = 0.0016 w, h = font.getStringSize(" ", scale = scale) diff --git a/src/Rockmeter.py b/src/Rockmeter.py index 08a2fca8b..1dc525267 100644 --- a/src/Rockmeter.py +++ b/src/Rockmeter.py @@ -56,6 +56,7 @@ #variables in the rockmeter.ini for you no longer have to use self #to refer to theme, instead it has a more friendly and logical setup. player = None +part = "Guitar" #the player's part/instrument score = 0 #player's score streak = 0 #player's streak @@ -120,8 +121,8 @@ def boardWidth(self, x): return player.boardWidth / math.sqrt((self.stage.scene.camera.origin[1] + x)**2+((self.stage.scene.camera.origin[2] + x)-0.5)**2) * scaleCoef def __init__(self, stage, section): - self.stage = stage #The rockmeter - self.engine = stage.engine #Game Engine + self.stage = stage #The rockmeter + self.engine = stage.engine #Game Engine self.config = stage.config #the rockmeter.ini self.section = section #the section of the rockmeter.ini involving this layer @@ -191,7 +192,7 @@ def __init__(self, stage, section, drawing): self.rectexpr = self.getexpr("rect", "(0.0,1.0,0.0,1.0)") #how much of the image do you want rendered # (left, right, top, bottom) - + self.rect = [0.0,1.0,0.0,1.0] def updateLayer(self, playerNum): #don't try to update an image layer if the texture doesn't even exist if not self.drawing: @@ -218,7 +219,7 @@ def updateLayer(self, playerNum): if "yscale" in self.inPixels: scale[1] /= texture.pixelSize[1] - scale[1] = -scale[1] + scale[1] *= -1 scale[0] *= w/vpc[0] scale[1] *= h/vpc[1] @@ -271,13 +272,16 @@ def __init__(self, stage, section, font): self.font = self.engine.data.fontDict[font] #the font to use self.text = "" #the text that will be rendered to screen self.textexpr = self.getexpr("text", "''") #the text from the ini that will be evalutated - self.replace = "" #replace character a character in the string with this + self.replace = [r.strip() for r in self.get("replace", str, "_").split("_")] + #replace character a character in the string with this self.alignment = halign(self.get("alignment", str, "LEFT"), 'left') #alignment of the text self.useComma = self.get("useComma", bool, False) #use commas when drawing numbers self.shadow = self.get("shadow", bool, False) #show a shadow on the text self.outline = self.get("outline", bool, False) #give the text an outline + self.shadowOpacity = self.get("shadowOpacity", float, 1.0) #the opacity of the shadow on the text + def updateLayer(self, playerNum): w, h, = self.engine.view.geometry[2:4] @@ -287,7 +291,9 @@ def updateLayer(self, playerNum): text = locale.format("%d", text, grouping=True) else: text = str(text) - + + text.replace(self.replace[0], self.replace[1]) + wid, hgt = self.font.getStringSize(str(text)) #needs to be done later because of values that may be dependant on the text's properties @@ -325,7 +331,7 @@ def render(self, visibility, playerNum): if bool(eval(self.condition)): glColor4f(*color) self.font.render(self.text, position, align = alignment, - shadow = self.shadow, outline = self.outline) + shadow = self.shadow, outline = self.outline, shadowOpacity = self.shadowOpacity) #creates a layer that is shaped like a pie-slice/circle instead of a rectangle @@ -415,183 +421,311 @@ def __init__(self, layer, section): self.condition = True + def _smoothstep(self, min, max, x): + if x < min: + return 0 + if x > max: + return 1 + def f(x): + return -2 * x**3 + 3*x**2 + return f((x - min) / (max - min)) + + def triggerPick(self): + if not self.stage.lastPickPos: + return 0.0 + t = position - self.stage.lastPickPos + return (1.0 - self._smoothstep(0, 500.0, t)) + + def triggerMiss(self): + if not self.stage.lastMissPos: + return 0.0 + t = position - self.stage.lastMissPos + return (1.0 - self._smoothstep(0, 500.0, t)) + def update(self): pass +#this class extends effect and is a base for effects that deal with +#incrementing values that provide smooth transitions and animations +class IncrementEffect(Effect): + def __init__(self, layer, section): + super(IncrementEffect, self).__init__(layer, section) + + self.reverse = False #determines if the values should increment back when the + # condition is false or just jump back instantly + + #can hold any number of values, as long as the amount matches + self.start = [] #starting set of values + self.end = [] #ending set of values + self.current = [] #the current value + + #rate at which values will increment between start and end + self.inRates = [] #incoming rates + self.outRates = [] #outgoing rates (if reverse is enabled) + + #catches flickering between 2 values + self.counter = 0 + self.countRate = 0 + + #how long it takes for the transition to take place + self.transitionTime = 512.0 + self.transitionTimeOut = 512.0 + + #gets the rate at which time is passing, usable in finding the rates of things in + #terms of milliseconds instead of frames + def getTime(self, time): + t = time * (max(self.engine.clock.get_fps(), _minFPS)) / 1000.0 + self.countRate = 1.0/max(t, 1.0) + return max(t, 1.0) + + #updates the rates at which values between start and end should change to reach + # the desired point + def updateRates(self): + try: + t = self.getTime(self.transitionTime) + for i in range(len(self.start)): + if self.end[i] < self.start[i]: + self.inRates[i] = (self.start[i] - self.end[i])/t + else: + self.inRates[i] = (self.end[i] - self.start[i])/t + if self.reverse and not bool(eval(self.condition)): + t = self.getTime(self.transitionTimeOut) + for i in range(len(self.start)): + if self.end[i] < self.start[i]: + self.outRates[i] = (self.start[i] - self.end[i])/t + else: + self.outRates[i] = (self.end[i] - self.start[i])/t + except: + #catches if rates have been declared or if they're proper size + # then tries updating them again now that they're proper + self.inRates = [0 for i in range(len(self.start))] + self.outRates = self.inRates[:] + self.updateRates() + + #updates the values with the rates and returns the current saved value + def updateValues(self): + condition = bool(eval(self.condition)) + if condition: + #slides to the end position + for i in range(len(self.start)): + if self.current[i] > self.end[i]: + if self.end[i] < self.start[i]: + self.current[i] -= self.inRates[i] + else: + self.current[i] = self.end[i] + elif self.current[i] < self.end[i]: + if self.end[i] > self.start[i]: + self.current[i] += self.inRates[i] + else: + self.current[i] = self.end[i] + if self.counter >= self.transitionTime: + self.current = self.end[:] + else: + #slides back to original position smoothly + if self.reverse: + for i in range(len(self.start)): + if self.current[i] > self.start[i]: + if self.end[i] > self.start[i]: + self.current[i] -= self.outRates[i] + else: + self.current[i] = self.start[i] + elif self.current[i] < self.start[i]: + if self.end[i] < self.start[i]: + self.current[i] += self.outRates[i] + else: + self.current[i] = self.start[i] + if self.counter <= 0.0: + self.current = self.start[:] + else: #instant jump to starting value + self.current = self.start[:] + self.counter = 0.0 + + return self.current + + #updates the counter, returns true if a change in value occurs + def updateCounter(self): + condition = bool(eval(self.condition)) + if condition: + self.counter += self.countRate + if self.counter >= self.transitionTime: + self.counter = self.transitionTime + return False + return True + else: + self.counter -= self.countRate + if self.counter <= 0.0: + self.counter = 0.0 + return False + return True + + #basic updating for the effect + def update(self): + self.updateRates() + self.updateValues() + self.updateCounter() + #slides the layer from one spot to another #in a set period of time when the condition is met -class Slide(Effect): +class Slide(IncrementEffect): def __init__(self, layer, section): super(Slide, self).__init__(layer, section) - self.startCoord = [eval(self.getexpr("startX", "0.0")), eval(self.getexpr("startY", "0.0"))] + w, h, = self.engine.view.geometry[2:4] + self.start = [eval(self.getexpr("startX", "0.0")), eval(self.getexpr("startY", "0.0"))] #starting position of the image - self.endCoord = [eval(self.getexpr("endX", "0.0")), eval(self.getexpr("endY", "0.0"))] + self.end = [eval(self.getexpr("endX", "0.0")), eval(self.getexpr("endY", "0.0"))] #ending position of the image self.inPixels = self.get("inPixels", str, "").split("|") #variables in terms of pixels - self.condition = self.getexpr("condition", "True") - - w, h, = self.engine.view.geometry[2:4] - if isinstance(self.layer, FontLayer): if "startX" in self.inPixels: - self.startCoord[0] /= vpc[0] + self.start[0] /= vpc[0] if "endX" in self.inPixels: - self.endCoord[0] /= vpc[0] + self.end[0] /= vpc[0] if "startY" in self.inPixels: - self.startCoord[1] /= vpc[1] + self.start[1] /= vpc[1] if "endY" in self.inPixels: - self.endCoord[1] /= vpc[1] + self.end[1] /= vpc[1] else: if "startX" in self.inPixels: - self.startCoord[0] *= w/vpc[0] + self.start[0] *= w/vpc[0] else: - self.startCoord[0] *= w + self.start[0] *= w if "startY" in self.inPixels: - self.startCoord[1] *= h/vpc[1] + self.start[1] *= h/vpc[1] else: - self.startCoord[1] *= h + self.start[1] *= h if "endX" in self.inPixels: - self.endCoord[0] *= w/vpc[0] + self.end[0] *= w/vpc[0] else: - self.endCoord[0] *= w + self.end[0] *= w if "endY" in self.inPixels: - self.endCoord[1] *= h/vpc[1] + self.end[1] *= h/vpc[1] else: - self.endCoord[1] *= h + self.end[1] *= h - self.position = self.startCoord[:] + self.current = self.start[:] #y position needs to be flipped initially if isinstance(self.layer, FontLayer): - self.position[1] *= .75 - self.position[1] = .75 - self.position[1] + self.current[1] *= .75 + self.current[1] = .75 - self.current[1] - self.reverse = bool(eval(self.getexpr("reverse", "True"))) - - #how long it takes for the transition to take place + self.reverse = bool(eval(self.getexpr("reverse", "True"))) + self.condition = self.getexpr("condition", "True") self.transitionTime = self.get("transitionTime", float, 512.0) - - self.rates = [0,0] - self.updateRates() + self.transitionTimeOut = self.get("transitionTimeOut", float, self.transitionTime) - #updates the rate at which the layer will slide - def updateRates(self): - t = self.transitionTime * (max(self.engine.clock.get_fps(), _minFPS)) / 1000.0 - for i in range(2): - if self.endCoord[i] < self.startCoord[i]: - self.rates[i] = (self.startCoord[i] - self.endCoord[i])/t - else: - self.rates[i] = (self.endCoord[i] - self.startCoord[i])/t - - def update(self): - condition = bool(eval(self.condition)) - + def updateValues(self): #reverse the processing for font layer handling if isinstance(self.layer, FontLayer): - self.position[1] = .75 - self.position[1] - self.position[1] /= .75 + self.current[1] = .75 - self.current[1] + self.current[1] /= .75 + + super(Slide, self).updateValues() - self.updateRates() - - if condition: - for i in range(2): - if self.position[i] > self.endCoord[i]: - if self.endCoord[i] < self.startCoord[i]: - self.position[i] -= self.rates[i] - else: - self.position[i] = self.endCoord[i] - elif self.position[i] < self.endCoord[i]: - if self.endCoord[i] > self.startCoord[i]: - self.position[i] += self.rates[i] - else: - self.position[i] = self.endCoord[i] - else: - if self.reverse: - for i in range(2): - if self.position[i] > self.startCoord[i]: - if self.endCoord[i] > self.startCoord[i]: - self.position[i] -= self.rates[i] - else: - self.position[i] = self.startCoord[i] - elif self.position[i] < self.startCoord[i]: - if self.endCoord[i] < self.startCoord[i]: - self.position[i] += self.rates[i] - else: - self.position[i] = self.startCoord[i] - else: - self.position = self.startCoord - #because of the y position being flipped on fonts it needs to be caught if isinstance(self.layer, FontLayer): - self.position[1] *= .75 - self.position[1] = .75 - self.position[1] + self.current[1] *= .75 + self.current[1] = .75 - self.current[1] + + def update(self): + super(Slide, self).update() + + self.layer.position = self.current[:] + +#smoothly scales the layer from one size to another +#in a set period of time when the condition is met +class Scale(IncrementEffect): + def __init__(self, layer, section): + super(Scale, self).__init__(layer, section) + + w, h, = self.engine.view.geometry[2:4] + self.start = [eval(self.getexpr("startX", "0.0")), eval(self.getexpr("startY", "0.0"))] + #starting dimensions of the image + self.end = [eval(self.getexpr("endX", "0.0")), eval(self.getexpr("endY", "0.0"))] + #ending dimensions of the image - self.layer.position = self.position[:] + self.current = self.start[:] + + self.inPixels = self.get("inPixels", str, "").split("|") #variables in terms of pixels + + self.transitionTime = self.get("transitionTime", float, 512.0) + self.transitionTimeOut = self.get("transitionTimeOut", float, self.transitionTime) + self.condition = self.getexpr("condition", "True") + self.reverse = bool(eval(self.getexpr("reverse", "True"))) + + self.fixedScale = isinstance(self.layer, ImageLayer) + + def fixScale(self): + w, h, = self.engine.view.geometry[2:4] + + self.start[0] *= (self.layer.rect[1] - self.layer.rect[0]) + self.start[1] *= (self.layer.rect[3] - self.layer.rect[2]) + self.end[0] *= (self.layer.rect[1] - self.layer.rect[0]) + self.end[1] *= (self.layer.rect[3] - self.layer.rect[2]) + + if "startX" in self.inPixels: + self.start[0] /= self.layer.drawing.pixelSize[0] + if "startY" in self.inPixels: + self.start[1] /= self.layer.drawing.pixelSize[1] + if "endX" in self.inPixels: + self.end[0] /= self.layer.drawing.pixelSize[0] + if "endY" in self.inPixels: + self.end[1] /= self.layer.drawing.pixelSize[1] + + self.start[1] *= -1 + self.end[1] *= -1 + self.start[0] *= w/vpc[0] + self.end[0] *= w/vpc[0] + self.start[1] *= h/vpc[1] + self.end[1] *= h/vpc[1] + + self.current = self.start[:] + + def update(self): + if not self.fixedScale: + self.fixScale() + self.fixedScale = True + + super(Scale, self).update() + + self.layer.scale = self.current[:] #fades the color of the layer between this color and its original #in a set period of time when the condition is met -class Fade(Effect): +class Fade(IncrementEffect): def __init__(self, layer, section): super(Fade, self).__init__(layer, section) - #starting color - color = self.engine.theme.hexToColor(self.get("color", str, "#FFFFFF")) - - #the current color of the image - self.currentColor = list(color) - if len(self.currentColor) == 3: - self.currentColor.append(1.0) + color = list(self.engine.theme.hexToColor(self.get("color", str, "#FFFFFF"))) + self.start = list(color) + if len(self.start) == 3: + self.start.append(1.0) #the color to fade to - color = list(self.engine.theme.hexToColor(self.get("fadeTo", str, "#FFFFFF"))) + self.end = list(self.engine.theme.hexToColor(self.get("fadeTo", str, "#FFFFFF"))) #makes sure alpha is added - if len(color) == 3: + if len(self.end) == 3: color.append(1.0) - #the colors to alternate between - self.colors = [color, self.currentColor] + + #the current color of the image + self.current = self.start[:] - #how long it takes for the transition to take place self.transitionTime = self.get("transitionTime", float, 512.0) - - self.updateRates() - + self.transitionTimeOut = self.get("transitionTimeOut", float, self.transitionTime) self.condition = self.getexpr("condition", "True") self.reverse = bool(eval(self.getexpr("reverse", "True"))) - - def updateRates(self): - t = self.transitionTime * (max(self.engine.clock.get_fps(), _minFPS)) / 1000.0 - self.rates = [(self.colors[0][i] - self.colors[1][i])/t - for i in range(4)] def update(self): - condition = bool(eval(self.condition)) - - self.updateRates() + super(Fade, self).update() - if condition: - for i in range(len(self.currentColor)): - if self.currentColor[i] > self.colors[0][i]: - self.currentColor[i] -= self.rates[i] - elif self.currentColor[i] < self.colors[0][i]: - self.currentColor[i] += self.rates[i] - else: - if self.reverse: - for i in range(len(self.currentColor)): - if self.currentColor[i] > self.colors[1][i]: - self.currentColor[i] -= self.rates[i] - elif self.currentColor[i] < self.colors[1][i]: - self.currentColor[i] += self.rates[i] - else: - self.currentColor[i] = self.colors[1] - - self.layer.color = self.currentColor + self.layer.color = self.current[:] #replaces the image of the layer when the condition is met class Replace(Effect): @@ -742,6 +876,14 @@ def __init__(self, guitarScene, configFileName, coOp = False): self.createImage(self.section, i) break + self.reset() + + def reset(self): + self.lastMissPos = None + self.lastPickPos = None + self.playedNotes = [] + self.averageNotes = [0.0] + #adds a layer to the rockmeter's list def addLayer(self, layer, number, shared = False): if shared: @@ -752,24 +894,20 @@ def addLayer(self, layer, number, shared = False): def loadLayerFX(self, layer, section): section = section.split(":")[0] - types = ["Slide", "Rotate", "Replace", "Fade", "Animate"] + types = {"Slide": "Slide(layer, fxsection)", + "Rotate": "Rotate(layer, fxsection)", + "Replace": "Replace(layer, fxsection)", + "Fade": "Fade(layer, fxsection)", + "Animate": "Animate(layer, fxsection)", + "Scale": "Scale(layer, fxsection)"} for i in range(5): #maximum of 5 effects per layer - for t in types: + for t in types.keys(): fxsection = "%s:fx%d:%s" % (section, i, t) if not self.config.has_section(fxsection): continue else: - if t == types[0]: - layer.effects.append(Slide(layer, fxsection)) -# elif t == types[1]: -# layer.effects.append(Rotate(layer, fxsection)) - elif t == types[2]: - layer.effects.append(Replace(layer, fxsection)) - elif t == types[3]: - layer.effects.append(Fade(layer, fxsection)) - else: - layer.effects.append(Animate(layer, fxsection)) - break #only allow type per effect number + layer.effects.append(eval(types[t])) + break def createFont(self, section, number): @@ -842,9 +980,10 @@ def updateTime(self): #this updates all the usual global variables that are handled by the rockmeter #these are all player specific def updateVars(self, playerNum): - global score, rock, streak, streakMax, power, stars, partialStars, multiplier, bassgroove, boost, player + global score, rock, streak, streakMax, power, stars, partialStars, multiplier, bassgroove, boost, player, part scene = self.scene player = scene.instruments[playerNum] + part = player.__class__.__name__ #this is here for when I finally get coOp worked in if self.coOp: @@ -886,7 +1025,16 @@ def updateVars(self, playerNum): #force bassgroove to false if it's not enabled if not scene.bassGrooveEnabled: bassgroove = False - + + def triggerPick(self, pos, notes): + if notes: + self.lastPickPos = pos + self.playedNotes = self.playedNotes[-3:] + [sum(notes) / float(len(notes))] + self.averageNotes[-1] = sum(self.playedNotes) / float(len(self.playedNotes)) + + def triggerMiss(self, pos): + self.lastMissPos = pos + def render(self, visibility): self.updateTime() diff --git a/src/Settings.py b/src/Settings.py index 2dc43b8a2..7fd0e11e6 100644 --- a/src/Settings.py +++ b/src/Settings.py @@ -812,7 +812,6 @@ def __init__(self, engine): ConfigChoice(self.engine, self.engine.config, "game", "noterotate", autoApply = True), #blazingamer ConfigChoice(self.engine, self.engine.config, "menu", "gfx_version_tag", autoApply = True), #MFH ConfigChoice(self.engine, self.engine.config, "video", "multisamples", isQuickset = 1), - ConfigChoice(self.engine, self.engine.config, "game", "in_game_font_shadowing", autoApply = True), #myfingershurt ConfigChoice(self.engine, self.engine.config, "performance", "static_strings", autoApply = True, isQuickset = 1), #myfingershurt ConfigChoice(self.engine, self.engine.config, "performance", "killfx", autoApply = True, isQuickset = 1), #blazingamer (_("More Effects"), self.shaderSettings, _("Change the settings of the shader system.")), #volshebnyi @@ -838,27 +837,20 @@ def __init__(self, engine): self.fretSettingsMenu = Menu.Menu(self.engine, self.fretSettings, pos = (self.opt_text_x, self.opt_text_y), textColor = self.opt_text_color, selectedColor = self.opt_selected_color) self.themeDisplaySettings = [ - ConfigChoice(self.engine, self.engine.config, "game", "small_rb_mult", autoApply = True), #blazingamer - ConfigChoice(self.engine, self.engine.config, "game", "starfx", autoApply = True), ConfigChoice(self.engine, self.engine.config, "performance", "animated_notes", autoApply = True, isQuickset = 1), ] self.themeDisplayMenu = Menu.Menu(self.engine, self.themeDisplaySettings, pos = (self.opt_text_x, self.opt_text_y), textColor = self.opt_text_color, selectedColor = self.opt_selected_color) self.inGameDisplaySettings = [ (_("Theme Display Settings"), self.themeDisplayMenu, _("Change settings that only affect certain theme types.")), - ConfigChoice(self.engine, self.engine.config, "game", "in_game_stars", autoApply = True, isQuickset = 2),#myfingershurt - ConfigChoice(self.engine, self.engine.config, "game", "partial_stars", autoApply = True, isQuickset = 1),#myfingershurt - ConfigChoice(self.engine, self.engine.config, "performance", "star_continuous_fillup", autoApply = True, isQuickset = 1), #stump ConfigChoice(self.engine, self.engine.config, "game", "game_phrases", autoApply = True, isQuickset = 1), ConfigChoice(self.engine, self.engine.config, "game", "hopo_indicator", autoApply = True), ConfigChoice(self.engine, self.engine.config, "game", "accuracy_mode", autoApply = True), - ConfigChoice(self.engine, self.engine.config, "performance", "in_game_stats", autoApply = True, isQuickset = 1),#myfingershurt ConfigChoice(self.engine, self.engine.config, "game", "gsolo_accuracy_disp", autoApply = True, isQuickset = 1), #MFH ConfigChoice(self.engine, self.engine.config, "game", "solo_frame", autoApply = True), #myfingershurt ConfigChoice(self.engine, self.engine.config, "video", "disable_fretsfx", autoApply = True), ConfigChoice(self.engine, self.engine.config, "video", "disable_flamesfx", autoApply = True), ConfigChoice(self.engine, self.engine.config, "video", "hitglow_color", autoApply = True), - ConfigChoice(self.engine, self.engine.config, "game", "game_time", autoApply = True), ConfigChoice(self.engine, self.engine.config, "video", "counting", autoApply = True, isQuickset = 2), ] self.inGameDisplayMenu = Menu.Menu(self.engine, self.inGameDisplaySettings, pos = (self.opt_text_x, self.opt_text_y), textColor = self.opt_text_color, selectedColor = self.opt_selected_color) @@ -1239,10 +1231,7 @@ def __init__(self, engine): self.keySettingsMenu = Menu.Menu(self.engine, self.keySettings, onClose = self.controlCheck, pos = (self.opt_text_x, self.opt_text_y), textColor = self.opt_text_color, selectedColor = self.opt_selected_color) InGameDisplaySettings = [ - ConfigChoice(engine, engine.config, "game", "in_game_stars", autoApply = True, isQuickset = 2),#myfingershurt ConfigChoice(engine, engine.config, "game", "accuracy_mode", autoApply = True), - ConfigChoice(engine, engine.config, "performance", "in_game_stats", autoApply = True, isQuickset = 1),#myfingershurt - ConfigChoice(engine, engine.config, "game", "game_time", autoApply = True), ConfigChoice(engine, engine.config, "video", "counting", autoApply = True, isQuickset = 2), ] InGameDisplayMenu = Menu.Menu(engine, InGameDisplaySettings, pos = (self.opt_text_x, self.opt_text_y), textColor = self.opt_text_color, selectedColor = self.opt_selected_color) @@ -1433,7 +1422,6 @@ def quickset(config): config.set("game", "sp_notes_while_active", 1) config.set("game", "bass_groove_enable", 1) config.set("game", "big_rock_endings", 1) - config.set("game", "in_game_stars", 1) config.set("game", "mark_solo_sections", 2) Log.debug("Quickset Gameplay - Theme-Based") @@ -1448,7 +1436,6 @@ def quickset(config): config.set("game", "sp_notes_while_active", 3) config.set("game", "bass_groove_enable", 3) config.set("game", "big_rock_endings", 2) - config.set("game", "in_game_stars", 2) config.set("game", "counting", True) config.set("game", "mark_solo_sections", 1) Log.debug("Quickset Gameplay - RB style") @@ -1457,7 +1444,6 @@ def quickset(config): config.set("game", "sp_notes_while_active", 0) config.set("game", "bass_groove_enable", 0) config.set("game", "big_rock_endings", 0) - config.set("game", "in_game_stars", 0) config.set("game", "counting", False) config.set("game", "mark_solo_sections", 0) Log.debug("Quickset Gameplay - GH style") @@ -1466,7 +1452,6 @@ def quickset(config): config.set("game", "sp_notes_while_active", 0) config.set("game", "bass_groove_enable", 0) config.set("game", "big_rock_endings", 0) - config.set("game", "in_game_stars", 0) config.set("game", "counting", True) config.set("game", "mark_solo_sections", 1) Log.debug("Quickset Gameplay - WT style") @@ -1489,12 +1474,10 @@ def quickset(config): config.set("video", "multisamples", 0) config.set("video", "shader_use", False) config.set("game", "game_phrases", 0) - config.set("game", "partial_stars", 0) config.set("stage", "stage_animate", 0) config.set("game", "lyric_mode", 0) config.set("menu", "use_graphical_submenu", 0) config.set("audio", "enable_crowd_tracks", 0) - config.set("performance", "in_game_stats", 0) config.set("performance", "static_strings", True) config.set("performance", "disable_libcount", True) config.set("performance", "killfx", 2) @@ -1519,7 +1502,6 @@ def quickset(config): config.set("game", "lyric_mode", 2) config.set("menu", "use_graphical_submenu", 0) config.set("audio", "enable_crowd_tracks", 1) - config.set("performance", "in_game_stats", 0) config.set("performance", "static_strings", True) config.set("performance", "disable_libcount", True) config.set("performance", "killfx", 0) @@ -1543,7 +1525,6 @@ def quickset(config): config.set("game", "lyric_mode", 2) config.set("menu", "use_graphical_submenu", 1) config.set("audio", "enable_crowd_tracks", 1) - config.set("performance", "in_game_stats", 2) config.set("performance", "static_strings", True) config.set("performance", "disable_libcount", True) config.set("performance", "killfx", 0) @@ -1568,7 +1549,6 @@ def quickset(config): config.set("game", "lyric_mode", 2) config.set("menu", "use_graphical_submenu", 1) config.set("audio", "enable_crowd_tracks", 1) - config.set("performance", "in_game_stats", 2) config.set("performance", "static_strings", False) config.set("performance", "disable_libcount", False) config.set("performance", "killfx", 0) diff --git a/src/Song.py b/src/Song.py index 7492cd388..4340c274f 100644 --- a/src/Song.py +++ b/src/Song.py @@ -558,7 +558,13 @@ def eighthNoteHopo(self): @property def lyrics(self): return self._get("lyrics") - + + @property + #because of how RB3 pro drums are formatted, this tag + #detects a way to properly read the cymbals notes in the midi + def prodrum(self): + return self._get("pro_drum") + def getHighscoresWithPartString(self, difficulty, part = str(parts[GUITAR_PART])): return self.getHighscores(difficulty, part) @@ -1100,13 +1106,22 @@ def __init__(self, engine): if self.logClassInits == 1: Log.debug("Track class init (song.py)...") - def __getitem__(self, index): return self.allEvents[index] def __len__(self): return len(self.allEvents) + @property + def length(self): + lastTime = 0 + for time, event in self.getAllEvents(): + if not isinstance(event, Note) and not isinstance(event, VocalPhrase): + continue + if time + event.length > lastTime: + lastTime = time + event.length + return round((lastTime+1000.0) / 1000.0) * 1000.0 + def addEvent(self, time, event): for t in range(int(time / self.granularity), int((time + event.length) / self.granularity) + 1): if len(self.events) < t + 1: @@ -2258,6 +2273,16 @@ def __init__(self, engine, infoFileName, songTrackName, guitarTrackName, rhythmT scriptReader = ScriptReader(self, open(scriptFileName)) scriptReader.read() + @property + def length(self): + length = 0 + for t in self.tracks: + for n in t: #note/vocal tracks + if n.length > length: + length += (n.length - length) + length += 3000.0 + return length + #myfingershurt: new function to re-retrieve the a/v delay setting so it can be changed in-game: def refreshAudioDelay(self): self.delay = self.engine.config.get("audio", "delay") @@ -3320,7 +3345,7 @@ def note_on(self, channel, note, velocity): except KeyError: pass -def loadSong(engine, name, library = DEFAULT_LIBRARY, seekable = False, playbackOnly = False, notesOnly = False, part = [parts[GUITAR_PART]], practiceMode = False, practiceSpeed = 1.0): +def loadSong(engine, name, library = DEFAULT_LIBRARY, seekable = False, playbackOnly = False, notesOnly = False, part = [parts[GUITAR_PART]], practiceMode = False, practiceSpeed = .5): Log.debug("loadSong function call (song.py)...") crowdsEnabled = engine.config.get("audio", "crowd_tracks_enabled") diff --git a/src/Stage.py b/src/Stage.py index 217920f74..899c95162 100644 --- a/src/Stage.py +++ b/src/Stage.py @@ -569,10 +569,12 @@ def triggerPick(self, pos, notes): self.lastPickPos = pos self.playedNotes = self.playedNotes[-3:] + [sum(notes) / float(len(notes))] self.averageNotes[-1] = sum(self.playedNotes) / float(len(self.playedNotes)) - + self.rockmeter.triggerPick(pos, notes) + def triggerMiss(self, pos): self.lastMissPos = pos - + self.rockmeter.triggerMiss(pos) + def triggerQuarterBeat(self, pos, quarterBeat): self.lastQuarterBeatPos = pos self.quarterBeat = quarterBeat diff --git a/src/Theme.py b/src/Theme.py index 5bfa57179..2144d6ae0 100644 --- a/src/Theme.py +++ b/src/Theme.py @@ -656,35 +656,35 @@ def get(value, type = str, default = None): self.result_star_type = get("result_star_type", int, 0) #Submenus - allfiles = os.listdir(os.path.join(self.themePath,"menu")) self.submenuScale = {} self.submenuX = {} self.submenuY = {} self.submenuVSpace = {} - listmenu = [] - for name in allfiles: - if name.find("text") > -1: - found = os.path.splitext(name)[0] - if found == "maintext": + if os.path.exists(os.path.join(self.themePath,"menu")): + allfiles = os.listdir(os.path.join(self.themePath,"menu")) + listmenu = [] + for name in allfiles: + if name.find("text") > -1: + found = os.path.splitext(name)[0] + if found == "maintext": + continue + Config.define("theme", found, str, None) + self.submenuScale[found] = None + self.submenuX[found] = None + self.submenuY[found] = None + self.submenuVSpace[found] = None + listmenu.append(found) + for i in listmenu: + if i == "maintext": continue - Config.define("theme", found, str, None) - self.submenuScale[found] = None - self.submenuX[found] = None - self.submenuY[found] = None - self.submenuVSpace[found] = None - listmenu.append(found) - for i in listmenu: - if i == "maintext": - continue - if self.submenuX[i]: - self.submenuX[i] = get(i).split(",")[0].strip() - if self.submenuY[i]: - self.submenuY[i] = get(i).split(",")[1].strip() - if self.submenuScale[i]: - self.submenuScale[i] = get(i).split(",")[2].strip() - if self.submenuVSpace[i]: - self.submenuVSpace[i] = get(i).split(",")[3].strip() - + if self.submenuX[i]: + self.submenuX[i] = get(i).split(",")[0].strip() + if self.submenuY[i]: + self.submenuY[i] = get(i).split(",")[1].strip() + if self.submenuScale[i]: + self.submenuScale[i] = get(i).split(",")[2].strip() + if self.submenuVSpace[i]: + self.submenuVSpace[i] = get(i).split(",")[3].strip() def setSelectedColor(self, alpha = 1.0): glColor4f(*(self.selectedColor + (alpha,))) diff --git a/src/World.py b/src/World.py index 3b960c4d5..7ae4b8a17 100644 --- a/src/World.py +++ b/src/World.py @@ -116,6 +116,7 @@ def createPlayer(self, name): player.controlType = self.engine.input.controls.type[player.controller] player.keyList = Player.playerkeys[playerNum] player.configController() + player.practiceMode = (self.gameMode == 1) self.players.append(player) self.songQueue.parts.append(player.part.id) self.songQueue.diffs.append(player.getDifficultyInt())