From 9a49bfbcd9d2611f5fcbb27056e0bc5cc8323411 Mon Sep 17 00:00:00 2001 From: Jennifer Taylor Date: Tue, 31 Aug 2021 21:41:51 +0000 Subject: [PATCH] Hook up town mode enable and phase unlocks to front end for Tune Street, start implementing more profile stuff. --- bemani/backend/popn/tunestreet.py | 133 ++++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 18 deletions(-) diff --git a/bemani/backend/popn/tunestreet.py b/bemani/backend/popn/tunestreet.py index 037e4ee..7b42542 100644 --- a/bemani/backend/popn/tunestreet.py +++ b/bemani/backend/popn/tunestreet.py @@ -1,6 +1,6 @@ # vim: set fileencoding=utf-8 import copy -from typing import Optional +from typing import Dict, Any, Optional from bemani.backend.popn.base import PopnMusicBase from bemani.backend.popn.stubs import PopnMusicSengokuRetsuden @@ -59,6 +59,61 @@ class PopnMusicTuneStreet(PopnMusicBase): def previous_version(self) -> Optional[PopnMusicBase]: return PopnMusicSengokuRetsuden(self.data, self.config, self.model) + @classmethod + def get_settings(cls) -> Dict[str, Any]: + """ + Return all of our front-end modifiably settings. + """ + return { + 'ints': [ + { + 'name': 'Game Phase', + 'tip': 'Game unlock phase for all players.', + 'category': 'game_config', + 'setting': 'game_phase', + 'values': { + 0: 'NO PHASE', + 1: 'SECRET DATA RELEASE', + 2: 'MAX: ALL DATA RELEASE', + } + }, + { + 'name': 'Town Mode Phase', + 'tip': 'Town mode phase for all players.', + 'category': 'game_config', + 'setting': 'town_phase', + 'values': { + 0: 'town mode disabled', + 1: 'town phase 1', + 2: 'town phase 2', + 3: 'Pop\'n Naan Festival', + # 4 seems to be a continuation of town phase 2. Intentionally leaving it out. + 5: 'town phase 3', + 6: 'town phase 4', + 7: 'Miracle 4 + 1', + # 8 seems to be a continuation of town phase 4. Intentionally leaving it out. + 9: 'town phase MAX', + 10: 'Find your daughter!', + # 11 is a continuation of phase MAX after find your daughter, with Tanabata + # bamboo grass added as well. + 11: 'town phase MAX+1', + 12: 'Peruri-san visits', + # 13 is a continuation of phase MAX+1 after peruri-san visits, with Watermelon + # pattern tank added as well. + 13: 'town phase MAX+2', + 14: 'Find Deuil!', + # 15 is a continuation of phase MAX+2 after find deuil, with Tsukimi dumplings + # added as well. + 15: 'town phase MAX+3', + 16: 'Landmark stamp rally', + # 17 is a continuation of MAX+3 after landmark stamp rally ends, but offering + # no additional stuff. + } + }, + ], + } + + def __format_flags_for_score(self, score: Score) -> int: # Format song flags (cleared/not, combo flags) playedflag = { @@ -104,16 +159,22 @@ class PopnMusicTuneStreet(PopnMusicBase): root = Node.void('playerdata') # Format profile - binary_profile = [0] * 2200 + binary_profile = [0] * 2198 - # Copy name + # Copy name. We intentionally leave location 12 alone as it is + # the null termination for the name if it happens to be 12 + # characters (6 shift-jis kana). name_binary = profile.get_str('name', 'なし').encode('shift-jis')[0:12] - name_pos = 0 - for byte in name_binary: + for name_pos, byte in enumerate(name_binary): binary_profile[name_pos] = byte - name_pos = name_pos + 1 - # Copy game mode + # Copy game mode. Modes sent to the game are as follows. + # 0 - Enjoy mode. + # 1 - Challenge mode. + # 2 - Battle mode. + # 3 - Net ranking mode (enabled by setting netvs_phase in game.get). + # 4 - Cho challenge mode. + # 5 - Town mode (enabled by event_phase in game.get). binary_profile[13] = { 0: 0, 1: 0, @@ -124,21 +185,24 @@ class PopnMusicTuneStreet(PopnMusicBase): }[profile.get_int('play_mode')] # Copy miscelaneous values - binary_profile[16] = profile.get_int('last_play_flag') & 0xFF + binary_profile[15] = profile.get_int('last_play_flag') & 0xFF + binary_profile[16] = profile.get_int('medal_and_friend') & 0xFF + binary_profile[37] = profile.get_int('read_news') & 0xFF binary_profile[44] = profile.get_int('option') & 0xFF binary_profile[45] = (profile.get_int('option') >> 8) & 0xFF binary_profile[46] = (profile.get_int('option') >> 16) & 0xFF binary_profile[47] = (profile.get_int('option') >> 24) & 0xFF - binary_profile[60] = profile.get_int('chara') & 0xFF - binary_profile[61] = (profile.get_int('chara') >> 8) & 0xFF + binary_profile[48] = profile.get_int('jubeat_collabo') & 0xFF + binary_profile[49] = (profile.get_int('jubeat_collabo') >> 8) & 0xFF + # 52-56 and 56-60 make up two 32 bit colors found in color_3p_flag. + binary_profile[60] = profile.get_int('chara', -1) & 0xFF + binary_profile[61] = (profile.get_int('chara', -1) >> 8) & 0xFF binary_profile[62] = profile.get_int('music') & 0xFF binary_profile[63] = (profile.get_int('music') >> 8) & 0xFF binary_profile[64] = profile.get_int('sheet') & 0xFF binary_profile[65] = profile.get_int('category') & 0xFF - # This might be the count of friends, since Tune Street *does* support - # rivals. However, I can no longer get it running on my cabinet or locally - # so there's no way for me to test. - binary_profile[67] = profile.get_int('medal_and_friend') & 0xFF + binary_profile[66] = profile.get_int('norma_point') & 0xFF + binary_profile[67] = (profile.get_int('norma_point') >> 8) & 0xFF # Format Scores hiscore_array = [0] * int((((self.GAME_MAX_MUSIC_ID * 7) * 17) + 7) / 8) @@ -195,10 +259,25 @@ class PopnMusicTuneStreet(PopnMusicBase): binary_profile[profile_pos + 1] = (musicid >> 8) & 0xFF profile_pos = profile_pos + 2 + # Town purchases, including BGM/announcer changes and such. + # The town customization area will show up if the player owns + # one or more customization in any of the following four + # categories. + town = [0] * 12 + + # Position 8 appears to be purchased pop-kuns. + town[8] = 0 + # Position 8 appears to be purchased themes. + town[9] = 0 + # Position 10 appears to be purchased BGMs. + town[10] = 0 + # Position 11 appears to be purchased sound effects. + town[11] = 0 + # Construct final profile root.add_child(Node.binary('b', bytes(binary_profile))) root.add_child(Node.binary('hiscore', bytes(hiscore_array))) - root.add_child(Node.binary('town', b'')) + root.add_child(Node.binary('town', bytes(town))) return root @@ -251,6 +330,12 @@ class PopnMusicTuneStreet(PopnMusicBase): newprofile.replace_int('sheet', int(request.attribute('sheet_num'))) if 'category_num' in request.attributes: newprofile.replace_int('category', int(request.attribute('category_num'))) + if 'read_news_no_max' in request.attributes: + newprofile.replace_int('read_news', int(request.attribute('read_news_no_max'))) + if 'jubeat_collabo' in request.attributes: + newprofile.replace_int('jubeat_collabo', int(request.attribute('jubeat_collabo'))) + if 'norma_point' in request.attributes: + newprofile.replace_int('norma_point', int(request.attribute('norma_point'))) # Keep track of play statistics self.update_play_statistics(userid) @@ -334,10 +419,22 @@ class PopnMusicTuneStreet(PopnMusicBase): method = request.attribute('method') if method == 'get': - # TODO: Hook these up to config so we can change this + game_config = self.get_game_config() + game_phase = game_config.get_int('game_phase') + town_phase = game_config.get_int('town_phase') + root = Node.void('game') - root.set_attribute('game_phase', '2') - root.set_attribute('psp_phase', '2') + root.set_attribute('game_phase', str(game_phase)) # Phase unlocks, for song availability. + root.set_attribute('boss_battle_point', '1') + root.set_attribute('boss_diff', '100,100,100,100,100,100,100,100,100,100') + root.set_attribute('card_phase', '3') + root.set_attribute('event_phase', str(town_phase)) # Town mode, for the main event. + root.set_attribute('gfdm_phase', '2') + root.set_attribute('ir_phase', '14') + root.set_attribute('jubeat_phase', '2') + root.set_attribute('local_matching_enable', '1') + root.set_attribute('matching_sec', '120') + root.set_attribute('netvs_phase', '0') # Net taisen mode phase, maximum 18 (no lobby support). return root if method == 'active':