Additional flag documentation as well as frontend config for UsaNeko. Also fixed NAVI-kun event to work. Also fixed Eclale area bounds that was mistakenly adjusted.
This commit is contained in:
parent
2582f0e523
commit
a1c786a525
@ -119,11 +119,18 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
||||
return Node.void('pcb24')
|
||||
|
||||
@abstractmethod
|
||||
def get_phases(self) -> Dict[int, int]:
|
||||
...
|
||||
def get_common_config(self) -> Tuple[Dict[int, int], bool]:
|
||||
"""
|
||||
Return a tuple of configuration options for sending the common node back
|
||||
to the client. The first parameter is a dictionary whose keys are event
|
||||
IDs and values are the event phase number. The second parameter is a bool
|
||||
representing whether or not to send areas.
|
||||
"""
|
||||
|
||||
def __construct_common_info(self, root: Node) -> None:
|
||||
for phaseid, phase_value in self.get_phases().items():
|
||||
phases, send_areas = self.get_common_config()
|
||||
|
||||
for phaseid, phase_value in phases.items():
|
||||
phase = Node.void('phase')
|
||||
root.add_child(phase)
|
||||
phase.add_child(Node.s16('event_id', phaseid))
|
||||
@ -199,7 +206,8 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
||||
subnode.add_child(Node.u8('clear_type', ach.data.get_int('clear_type')))
|
||||
subnode.add_child(Node.u8('clear_rank', ach.data.get_int('clear_rank')))
|
||||
|
||||
for area_id in range(0, 16):
|
||||
if send_areas:
|
||||
for area_id in range(1, 16):
|
||||
area = Node.void('area')
|
||||
root.add_child(area)
|
||||
area.add_child(Node.s16('area_id', area_id))
|
||||
@ -958,6 +966,18 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
||||
if 'navi_points' in profile:
|
||||
navi_data.add_child(Node.s32_array('raisePoint', profile.get_int_array('navi_points', 5)))
|
||||
|
||||
game_config = self.get_game_config()
|
||||
if game_config.get_bool('force_unlock_songs'):
|
||||
songs = self.data.local.music.get_all_songs(self.game, self.version)
|
||||
for song in songs:
|
||||
item = Node.void('item')
|
||||
root.add_child(item)
|
||||
item.add_child(Node.u8('type', 0))
|
||||
item.add_child(Node.u16('id', song.id))
|
||||
item.add_child(Node.u16('param', 15))
|
||||
item.add_child(Node.bool('is_new', False))
|
||||
item.add_child(Node.u64('get_time', 0))
|
||||
|
||||
# Set up achievements
|
||||
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
|
||||
for achievement in achievements:
|
||||
@ -967,8 +987,6 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
||||
is_new = achievement.data.get_bool('is_new')
|
||||
get_time = achievement.data.get_int('get_time')
|
||||
|
||||
item = Node.void('item')
|
||||
root.add_child(item)
|
||||
# Item type can be 0-6 inclusive and is the type of the unlock/item.
|
||||
# Item 0 is music unlocks. In this case, the id is the song ID according
|
||||
# to the game. Unclear what the param is supposed to be, but i've seen
|
||||
@ -982,6 +1000,12 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
||||
# 4: 1
|
||||
# 5: 1
|
||||
# 6: 60
|
||||
if game_config.get_bool('force_unlock_songs') and itemtype == 0:
|
||||
# We already sent song unlocks in the force unlock section above.
|
||||
continue
|
||||
|
||||
item = Node.void('item')
|
||||
root.add_child(item)
|
||||
item.add_child(Node.u8('type', itemtype))
|
||||
item.add_child(Node.u16('id', achievement.id))
|
||||
item.add_child(Node.u16('param', param))
|
||||
@ -1223,6 +1247,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
||||
)
|
||||
|
||||
# Extract achievements
|
||||
game_config = self.get_game_config()
|
||||
for node in request.children:
|
||||
if node.name == 'item':
|
||||
itemid = node.child_value('id')
|
||||
@ -1231,6 +1256,10 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
||||
is_new = node.child_value('is_new')
|
||||
get_time = node.child_value('get_time')
|
||||
|
||||
if game_config.get_bool('force_unlock_songs') and itemtype == 0:
|
||||
# If we enabled force song unlocks, don't save songs to the profile.
|
||||
continue
|
||||
|
||||
self.data.local.user.put_achievement(
|
||||
self.game,
|
||||
self.version,
|
||||
|
@ -164,7 +164,7 @@ class PopnMusicEclale(PopnMusicBase):
|
||||
phase.add_child(Node.s16('phase', phases[phaseid]))
|
||||
|
||||
if game_config.get_bool('starmaker_enable'):
|
||||
for areaid in range(51):
|
||||
for areaid in range(1, 51):
|
||||
area = Node.void('area')
|
||||
root.add_child(area)
|
||||
area.add_child(Node.s16('area_id', areaid))
|
||||
|
@ -1,5 +1,5 @@
|
||||
# vim: set fileencoding=utf-8
|
||||
from typing import Dict
|
||||
from typing import Dict, Tuple
|
||||
|
||||
from bemani.backend.popn.base import PopnMusicBase
|
||||
from bemani.backend.popn.common import PopnMusicModernBase
|
||||
@ -18,10 +18,11 @@ class PopnMusicPeace(PopnMusicModernBase):
|
||||
def previous_version(self) -> PopnMusicBase:
|
||||
return PopnMusicUsaNeko(self.data, self.config, self.model)
|
||||
|
||||
def get_phases(self) -> Dict[int, int]:
|
||||
def get_common_config(self) -> Tuple[Dict[int, int], bool]:
|
||||
# Event phases
|
||||
# TODO: Hook event mode settings up to the front end.
|
||||
return {
|
||||
return (
|
||||
{
|
||||
# Default song phase availability (0-23)
|
||||
0: 23,
|
||||
# Unknown event (0-2)
|
||||
@ -72,4 +73,6 @@ class PopnMusicPeace(PopnMusicModernBase):
|
||||
23: 1,
|
||||
# Unknown event (0-1)
|
||||
24: 1,
|
||||
}
|
||||
},
|
||||
False,
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# vim: set fileencoding=utf-8
|
||||
from typing import Dict
|
||||
from typing import Any, Dict, Tuple
|
||||
|
||||
from bemani.backend.popn.base import PopnMusicBase
|
||||
from bemani.backend.popn.common import PopnMusicModernBase
|
||||
@ -18,12 +18,105 @@ class PopnMusicUsaNeko(PopnMusicModernBase):
|
||||
def previous_version(self) -> PopnMusicBase:
|
||||
return PopnMusicEclale(self.data, self.config, self.model)
|
||||
|
||||
def get_phases(self) -> Dict[int, int]:
|
||||
# Event phases
|
||||
# TODO: Hook event mode settings up to the front end.
|
||||
@classmethod
|
||||
def get_settings(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Return all of our front-end modifiably settings.
|
||||
"""
|
||||
return {
|
||||
'ints': [
|
||||
{
|
||||
'name': 'Music Open Phase',
|
||||
'tip': 'Default music phase for all players.',
|
||||
'category': 'game_config',
|
||||
'setting': 'music_phase',
|
||||
'values': {
|
||||
0: 'No music unlocks',
|
||||
1: 'Phase 1',
|
||||
2: 'Phase 2',
|
||||
3: 'Phase 3',
|
||||
4: 'Phase 4',
|
||||
5: 'Phase 5',
|
||||
6: 'Phase 6',
|
||||
7: 'Phase 7',
|
||||
8: 'Phase 8',
|
||||
9: 'Phase 9',
|
||||
10: 'Phase 10',
|
||||
11: 'Phase MAX',
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'Active Event',
|
||||
'tip': 'Active event for all players.',
|
||||
'category': 'game_config',
|
||||
'setting': 'active_event',
|
||||
'values': {
|
||||
0: 'No event',
|
||||
1: 'NAVI-Kun event',
|
||||
2: 'Daily Mission event',
|
||||
},
|
||||
},
|
||||
{
|
||||
'name': 'NAVI-Kun Event Phase',
|
||||
'tip': 'NAVI-Kun event phase for all players.',
|
||||
'category': 'game_config',
|
||||
'setting': 'navikun_phase',
|
||||
'values': {
|
||||
0: 'Phase 1',
|
||||
1: 'Phase 2',
|
||||
2: 'Phase 3',
|
||||
3: 'Phase 4',
|
||||
4: 'Phase 5',
|
||||
5: 'Phase 6',
|
||||
6: 'Phase 7',
|
||||
7: 'Phase 8',
|
||||
8: 'Phase 9',
|
||||
9: 'Phase 10',
|
||||
10: 'Phase 11',
|
||||
11: 'Phase 12',
|
||||
12: 'Phase 13',
|
||||
13: 'Phase 14',
|
||||
14: 'Phase 15',
|
||||
15: 'Phase MAX',
|
||||
},
|
||||
},
|
||||
],
|
||||
'bools': [
|
||||
{
|
||||
'name': 'Force Song Unlock',
|
||||
'tip': 'Force unlock all songs.',
|
||||
'category': 'game_config',
|
||||
'setting': 'force_unlock_songs',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
def get_common_config(self) -> Tuple[Dict[int, int], bool]:
|
||||
game_config = self.get_game_config()
|
||||
music_phase = game_config.get_int('music_phase')
|
||||
active_event = game_config.get_int('active_event')
|
||||
navikun_phase = game_config.get_int('navikun_phase')
|
||||
|
||||
navikun_enabled = active_event == 1
|
||||
daily_mission_enabled = active_event == 2
|
||||
|
||||
# Event phases
|
||||
return (
|
||||
{
|
||||
# Default song phase availability (0-11)
|
||||
0: 11,
|
||||
# The following songs are unlocked when the phase is at or above the number specified:
|
||||
# 1 - 1589, 1590, 1591
|
||||
# 2 - 1594, 1595
|
||||
# 3 - 1596, 1597
|
||||
# 4 - 1593
|
||||
# 5 - 1602
|
||||
# 6 - 1604
|
||||
# 7 - 1629, 1630, 1631, 1633, 1641, 1642, 1643, 1644, 1645, 1646, 1647
|
||||
# 8 - 1632
|
||||
# 9 - 1651
|
||||
# 10 - 1679, 1680, 1681
|
||||
# 11 - 1669, 1670, 1669, 1670
|
||||
0: music_phase,
|
||||
# Unknown event (0-2)
|
||||
1: 2,
|
||||
# Unknown event (0-2)
|
||||
@ -41,13 +134,31 @@ class PopnMusicUsaNeko(PopnMusicModernBase):
|
||||
# Unknown event (0-2)
|
||||
8: 2,
|
||||
# Daily Mission (0-2)
|
||||
9: 2,
|
||||
9: 2 if daily_mission_enabled else 0,
|
||||
# NAVI-kun Song phase availability (0-15)
|
||||
10: 15,
|
||||
# The following songs are unlocked when the phase is at or above the number specified:
|
||||
# 1 - 1553
|
||||
# 2 - 1577, 1576, 1569
|
||||
# 3 - 1575, 1557
|
||||
# 4 - 1567
|
||||
# 5 - 1587, 1588, 1585
|
||||
# 6 - 1586
|
||||
# 7 - 1601, 1600, 1599
|
||||
# 8 - 1603
|
||||
# 9 - 1606, 1607, 1605
|
||||
# 10 - 1610, 1611, 1612
|
||||
# 11 - 1616, 1613, 1614, 1615
|
||||
# 12 - 1619, 1618, 1620, 1617
|
||||
# 13 - 1624, 1621, 1623, 1622
|
||||
# 14 - 1627, 1626, 1625
|
||||
# 15 - 1628
|
||||
10: navikun_phase,
|
||||
# Unknown event (0-1)
|
||||
11: 1,
|
||||
# Unknown event (0-2)
|
||||
12: 2,
|
||||
# Enable Pop'n Peace preview song (0-1)
|
||||
# Enable Pop'n Peace preview song (1703) (0-1)
|
||||
13: 1,
|
||||
}
|
||||
},
|
||||
navikun_enabled,
|
||||
)
|
||||
|
@ -41,10 +41,13 @@ class PopnMusicUsaNekoClient(BaseClient):
|
||||
def __verify_common(self, root: str, resp: Node) -> None:
|
||||
self.assert_path(resp, f"response/{root}/phase/event_id")
|
||||
self.assert_path(resp, f"response/{root}/phase/phase")
|
||||
self.assert_path(resp, f"response/{root}/area/area_id")
|
||||
self.assert_path(resp, f"response/{root}/area/end_date")
|
||||
self.assert_path(resp, f"response/{root}/area/medal_id")
|
||||
self.assert_path(resp, f"response/{root}/area/is_limit")
|
||||
|
||||
# Area stuff is only necessary if navikun event is active.
|
||||
# self.assert_path(resp, f"response/{root}/area/area_id")
|
||||
# self.assert_path(resp, f"response/{root}/area/end_date")
|
||||
# self.assert_path(resp, f"response/{root}/area/medal_id")
|
||||
# self.assert_path(resp, f"response/{root}/area/is_limit")
|
||||
|
||||
self.assert_path(resp, f"response/{root}/choco/choco_id")
|
||||
self.assert_path(resp, f"response/{root}/choco/param")
|
||||
self.assert_path(resp, f"response/{root}/goods/item_id")
|
||||
|
Loading…
Reference in New Issue
Block a user