player number enum

This commit is contained in:
Anthony Samms
2025-11-14 15:20:35 -05:00
parent d06e5276b6
commit aef634ef3d
24 changed files with 301 additions and 356 deletions

View File

@@ -10,7 +10,7 @@ from libs.bg_objects.don_bg import DonBG
from libs.bg_objects.fever import Fever from libs.bg_objects.fever import Fever
from libs.bg_objects.footer import Footer from libs.bg_objects.footer import Footer
from libs.bg_objects.renda import RendaController from libs.bg_objects.renda import RendaController
from libs.global_data import Difficulty from libs.global_data import Difficulty, PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -30,7 +30,7 @@ class Background:
"PRACTICE": (libs.bg_collabs.practice.Background, 'background/collab/practice', 1) "PRACTICE": (libs.bg_collabs.practice.Background, 'background/collab/practice', 1)
} }
def __init__(self, player_num: int, bpm: float, scene_preset: str = ''): def __init__(self, player_num: PlayerNum, bpm: float, scene_preset: str = ''):
""" """
Initialize the background class. Initialize the background class.
@@ -41,12 +41,12 @@ class Background:
""" """
self.tex_wrapper = TextureWrapper() self.tex_wrapper = TextureWrapper()
self.tex_wrapper.load_animations('background') self.tex_wrapper.load_animations('background')
if player_num == 3: if player_num == PlayerNum.TWO_PLAYER:
if scene_preset == '': if scene_preset == '':
self.max_dancers = 5 self.max_dancers = 5
don_bg_num = random.randint(0, 5) don_bg_num = random.randint(0, 5)
self.don_bg = DonBG.create(self.tex_wrapper, don_bg_num, 1) self.don_bg = DonBG.create(self.tex_wrapper, don_bg_num, PlayerNum.P1)
self.don_bg_2 = DonBG.create(self.tex_wrapper, don_bg_num, 2) self.don_bg_2 = DonBG.create(self.tex_wrapper, don_bg_num, PlayerNum.P2)
self.renda = RendaController(self.tex_wrapper, random.randint(0, 2)) self.renda = RendaController(self.tex_wrapper, random.randint(0, 2))
self.chibi = ChibiController(self.tex_wrapper, random.randint(0, 13), bpm) self.chibi = ChibiController(self.tex_wrapper, random.randint(0, 13), bpm)
self.bg_normal = None self.bg_normal = None
@@ -56,7 +56,7 @@ class Background:
self.dancer = None self.dancer = None
else: else:
bg_obj, path, max_dancers = Background.COLLABS[scene_preset] bg_obj, path, max_dancers = Background.COLLABS[scene_preset]
collab_bg = bg_obj(self.tex_wrapper, 1, bpm, path, max_dancers) collab_bg = bg_obj(self.tex_wrapper, PlayerNum.P1, bpm, path, max_dancers)
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = collab_bg.don_bg self.don_bg = collab_bg.don_bg
self.don_bg_2 = collab_bg.don_bg self.don_bg_2 = collab_bg.don_bg
@@ -80,7 +80,7 @@ class Background:
self.chibi = ChibiController(self.tex_wrapper, random.randint(0, 13), bpm) self.chibi = ChibiController(self.tex_wrapper, random.randint(0, 13), bpm)
else: else:
bg_obj, path, max_dancers = Background.COLLABS[scene_preset] bg_obj, path, max_dancers = Background.COLLABS[scene_preset]
collab_bg = bg_obj(self.tex_wrapper, 1, bpm, path, max_dancers) collab_bg = bg_obj(self.tex_wrapper, PlayerNum.P1, bpm, path, max_dancers)
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = collab_bg.don_bg self.don_bg = collab_bg.don_bg
self.don_bg_2 = None self.don_bg_2 = None

View File

@@ -6,10 +6,11 @@ from libs.bg_objects.chibi import ChibiController
from libs.bg_objects.dancer import BaseDancer, BaseDancerGroup from libs.bg_objects.dancer import BaseDancer, BaseDancerGroup
from libs.bg_objects.don_bg import DonBGBase from libs.bg_objects.don_bg import DonBGBase
from libs.bg_objects.renda import RendaController from libs.bg_objects.renda import RendaController
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
class Background: class Background:
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str, max_dancers: int): def __init__(self, tex: TextureWrapper, player_num: PlayerNum, bpm: float, path: str, max_dancers: int):
self.tex_wrapper = tex self.tex_wrapper = tex
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = DonBG(self.tex_wrapper, 0, 1, path) self.don_bg = DonBG(self.tex_wrapper, 0, 1, path)

View File

@@ -6,12 +6,13 @@ from libs.bg_objects.dancer import BaseDancer, BaseDancerGroup
from libs.bg_objects.fever import Fever3 from libs.bg_objects.fever import Fever3
from libs.bg_objects.footer import Footer from libs.bg_objects.footer import Footer
from libs.bg_objects.renda import RendaController from libs.bg_objects.renda import RendaController
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
from libs.bg_objects.don_bg import DonBG4 from libs.bg_objects.don_bg import DonBG4
class Background: class Background:
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str, max_dancers: int): def __init__(self, tex: TextureWrapper, player_num: PlayerNum, bpm: float, path: str, max_dancers: int):
self.tex_wrapper = tex self.tex_wrapper = tex
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = DonBG4(self.tex_wrapper, 4, player_num, 'background') self.don_bg = DonBG4(self.tex_wrapper, 4, player_num, 'background')

View File

@@ -5,12 +5,13 @@ from libs.bg_objects.chibi import ChibiController
from libs.bg_objects.dancer import BaseDancer, BaseDancerGroup from libs.bg_objects.dancer import BaseDancer, BaseDancerGroup
from libs.bg_objects.fever import Fever3 from libs.bg_objects.fever import Fever3
from libs.bg_objects.renda import RendaController from libs.bg_objects.renda import RendaController
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
from libs.bg_objects.don_bg import DonBG4 from libs.bg_objects.don_bg import DonBG4
class Background: class Background:
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str, max_dancers: int): def __init__(self, tex: TextureWrapper, player_num: PlayerNum, bpm: float, path: str, max_dancers: int):
self.tex_wrapper = tex self.tex_wrapper = tex
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = DonBG4(self.tex_wrapper, 4, player_num, 'background') self.don_bg = DonBG4(self.tex_wrapper, 4, player_num, 'background')

View File

@@ -3,13 +3,14 @@ from libs.bg_objects.bg_normal import BGNormalBase
from libs.bg_objects.chibi import ChibiController from libs.bg_objects.chibi import ChibiController
from libs.bg_objects.don_bg import DonBG6 from libs.bg_objects.don_bg import DonBG6
from libs.bg_objects.footer import Footer from libs.bg_objects.footer import Footer
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
class Background: class Background:
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str, max_dancers: int): def __init__(self, tex: TextureWrapper, player_num: PlayerNum, bpm: float, path: str, max_dancers: int):
self.tex_wrapper = tex self.tex_wrapper = tex
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = DonBG(self.tex_wrapper, 0, 1, path) self.don_bg = DonBG(self.tex_wrapper, 0, PlayerNum.P1, path)
self.bg_normal = BGNormalBase(self.tex_wrapper, 0, path) self.bg_normal = BGNormalBase(self.tex_wrapper, 0, path)
self.bg_fever = None self.bg_fever = None
self.footer = Footer(self.tex_wrapper, 0, path) self.footer = Footer(self.tex_wrapper, 0, path)
@@ -19,7 +20,7 @@ class Background:
self.chibi = ChibiController(self.tex_wrapper, 2, bpm, path) self.chibi = ChibiController(self.tex_wrapper, 2, bpm, path)
class DonBG(DonBG6): class DonBG(DonBG6):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.overlay_move_2 = Animation.create_move(8000, total_distance=-760) self.overlay_move_2 = Animation.create_move(8000, total_distance=-760)
self.overlay_move_2.loop = True self.overlay_move_2.loop = True

View File

@@ -6,6 +6,7 @@ from libs.bg_objects.dancer import BaseDancerGroup
from libs.bg_objects.fever import BaseFever from libs.bg_objects.fever import BaseFever
from libs.bg_objects.footer import Footer from libs.bg_objects.footer import Footer
from libs.bg_objects.renda import RendaController from libs.bg_objects.renda import RendaController
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
from libs.bg_objects.don_bg import DonBGBase from libs.bg_objects.don_bg import DonBGBase
@@ -13,7 +14,7 @@ import pyray as ray
class Background: class Background:
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str, max_dancers: int): def __init__(self, tex: TextureWrapper, player_num: PlayerNum, bpm: float, path: str, max_dancers: int):
self.tex_wrapper = tex self.tex_wrapper = tex
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = DonBGBase(self.tex_wrapper, 0, player_num, path) self.don_bg = DonBGBase(self.tex_wrapper, 0, player_num, path)

View File

@@ -6,12 +6,13 @@ from libs.bg_objects.chibi import ChibiController
from libs.bg_objects.dancer import BaseDancerGroup from libs.bg_objects.dancer import BaseDancerGroup
from libs.bg_objects.footer import Footer from libs.bg_objects.footer import Footer
from libs.bg_objects.renda import RendaController from libs.bg_objects.renda import RendaController
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
from libs.bg_objects.don_bg import DonBGBase from libs.bg_objects.don_bg import DonBGBase
class Background: class Background:
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str, max_dancers: int): def __init__(self, tex: TextureWrapper, player_num: PlayerNum, bpm: float, path: str, max_dancers: int):
self.tex_wrapper = tex self.tex_wrapper = tex
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = DonBG(self.tex_wrapper, 0, player_num, path) self.don_bg = DonBG(self.tex_wrapper, 0, player_num, path)
@@ -24,7 +25,7 @@ class Background:
self.chibi = ChibiController(self.tex_wrapper, 0, bpm, path) self.chibi = ChibiController(self.tex_wrapper, 0, bpm, path)
class DonBG(DonBGBase): class DonBG(DonBGBase):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.move = Animation.create_move(3000, total_distance=-304) self.move = Animation.create_move(3000, total_distance=-304)
self.move.loop = True self.move.loop = True
@@ -35,8 +36,8 @@ class DonBG(DonBGBase):
tex.draw_texture(self.name, 'background', frame=self.is_clear, fade=fade, x=(i*304)+self.move.attribute, y=y) tex.draw_texture(self.name, 'background', frame=self.is_clear, fade=fade, x=(i*304)+self.move.attribute, y=y)
class BGNormal(BGNormalBase): class BGNormal(BGNormalBase):
def __init__(self, tex: TextureWrapper, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, path: str):
super().__init__(tex, player_num, path) super().__init__(tex, index, path)
self.screen_change = Animation.create_texture_change(8000, textures=[(0, 2000, 0), (2000, 4000, 1), (4000, 6000, 2), (6000, 8000, 3)]) self.screen_change = Animation.create_texture_change(8000, textures=[(0, 2000, 0), (2000, 4000, 1), (4000, 6000, 2), (6000, 8000, 3)])
self.screen_change.loop = True self.screen_change.loop = True
self.screen_change.start() self.screen_change.start()
@@ -51,8 +52,8 @@ class BGNormal(BGNormalBase):
tex.draw_texture(self.name, 'overlay') tex.draw_texture(self.name, 'overlay')
class BGFever(BGFeverBase): class BGFever(BGFeverBase):
def __init__(self, tex: TextureWrapper, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, path: str):
super().__init__(tex, player_num, path) super().__init__(tex, index, path)
self.screen_change = Animation.create_texture_change(8000, textures=[(0, 2000, 0), (2000, 4000, 1), (4000, 6000, 2), (6000, 8000, 3)]) self.screen_change = Animation.create_texture_change(8000, textures=[(0, 2000, 0), (2000, 4000, 1), (4000, 6000, 2), (6000, 8000, 3)])
self.screen_change.loop = True self.screen_change.loop = True
self.screen_change.start() self.screen_change.start()

View File

@@ -7,13 +7,14 @@ from libs.bg_objects.dancer import BaseDancer, BaseDancerGroup
from libs.bg_objects.don_bg import DonBGBase from libs.bg_objects.don_bg import DonBGBase
from libs.bg_objects.footer import Footer from libs.bg_objects.footer import Footer
from libs.bg_objects.renda import RendaController from libs.bg_objects.renda import RendaController
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
class Background: class Background:
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str, max_dancers: int): def __init__(self, tex: TextureWrapper, player_num: PlayerNum, bpm: float, path: str, max_dancers: int):
self.tex_wrapper = tex self.tex_wrapper = tex
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = DonBG(self.tex_wrapper, 0, 1, path) self.don_bg = DonBG(self.tex_wrapper, 0, player_num, path)
self.bg_normal = BGNormalBase(self.tex_wrapper, 0, path) self.bg_normal = BGNormalBase(self.tex_wrapper, 0, path)
self.bg_fever = BGFever(self.tex_wrapper, 0, path) self.bg_fever = BGFever(self.tex_wrapper, 0, path)
self.footer = Footer(self.tex_wrapper, 0, path) self.footer = Footer(self.tex_wrapper, 0, path)
@@ -37,7 +38,7 @@ class DancerGroup(BaseDancerGroup):
self.add_dancer() self.add_dancer()
class DonBG(DonBGBase): class DonBG(DonBGBase):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.move = Animation.create_move(20000, total_distance=-1344) self.move = Animation.create_move(20000, total_distance=-1344)
self.move.start() self.move.start()

View File

@@ -1,10 +1,11 @@
from libs.bg_objects.bg_normal import BGNormalBase from libs.bg_objects.bg_normal import BGNormalBase
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
from libs.bg_objects.don_bg import DonBG1 from libs.bg_objects.don_bg import DonBG1
class Background: class Background:
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str, max_dancers: int): def __init__(self, tex: TextureWrapper, player_num: PlayerNum, bpm: float, path: str, max_dancers: int):
self.tex_wrapper = tex self.tex_wrapper = tex
self.max_dancers = max_dancers self.max_dancers = max_dancers
self.don_bg = DonBG1(self.tex_wrapper, 0, 1, path) self.don_bg = DonBG1(self.tex_wrapper, 0, 1, path)

View File

@@ -1,3 +1,4 @@
from libs.global_data import PlayerNum
from libs.texture import TextureWrapper from libs.texture import TextureWrapper
@@ -10,7 +11,7 @@ class DonBG:
return selected_obj(tex, index, player_num, path) return selected_obj(tex, index, player_num, path)
class DonBGBase: class DonBGBase:
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
self.name = f'{index}_{player_num}' self.name = f'{index}_{player_num}'
tex.load_zip(path, f'donbg/{self.name}') tex.load_zip(path, f'donbg/{self.name}')
self.move = tex.get_animation(0) self.move = tex.get_animation(0)
@@ -34,7 +35,7 @@ class DonBGBase:
self.clear_fade.update(current_time_ms) self.clear_fade.update(current_time_ms)
class DonBG1(DonBGBase): class DonBG1(DonBGBase):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.overlay_move = tex.get_animation(2) self.overlay_move = tex.get_animation(2)
def update(self, current_time_ms: float, is_clear: bool): def update(self, current_time_ms: float, is_clear: bool):
@@ -49,7 +50,7 @@ class DonBG1(DonBGBase):
tex.draw_texture(self.name, 'footer', frame=self.is_clear, fade=fade, x=(i*56)+self.move.attribute*((56/328)*3), y=self.overlay_move.attribute+y) tex.draw_texture(self.name, 'footer', frame=self.is_clear, fade=fade, x=(i*56)+self.move.attribute*((56/328)*3), y=self.overlay_move.attribute+y)
class DonBG2(DonBGBase): class DonBG2(DonBGBase):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.overlay_move = tex.get_animation(3) self.overlay_move = tex.get_animation(3)
def update(self, current_time_ms: float, is_clear: bool): def update(self, current_time_ms: float, is_clear: bool):
@@ -61,7 +62,7 @@ class DonBG2(DonBGBase):
tex.draw_texture(self.name, 'overlay', frame=self.is_clear, fade=fade, x=(i*328)+self.move.attribute, y=self.overlay_move.attribute+y) tex.draw_texture(self.name, 'overlay', frame=self.is_clear, fade=fade, x=(i*328)+self.move.attribute, y=self.overlay_move.attribute+y)
class DonBG3(DonBGBase): class DonBG3(DonBGBase):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.bounce_up = tex.get_animation(4) self.bounce_up = tex.get_animation(4)
self.bounce_down = tex.get_animation(5) self.bounce_down = tex.get_animation(5)
@@ -88,7 +89,7 @@ class DonBG3(DonBGBase):
tex.draw_texture(self.name, 'overlay', frame=self.is_clear, fade=fade, x=(i*328)+(self.move.attribute*2), y=y_pos+y) tex.draw_texture(self.name, 'overlay', frame=self.is_clear, fade=fade, x=(i*328)+(self.move.attribute*2), y=y_pos+y)
class DonBG4(DonBGBase): class DonBG4(DonBGBase):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.overlay_move = tex.get_animation(2) self.overlay_move = tex.get_animation(2)
def update(self, current_time_ms: float, is_clear: bool): def update(self, current_time_ms: float, is_clear: bool):
@@ -101,7 +102,7 @@ class DonBG4(DonBGBase):
tex.draw_texture(self.name, 'overlay', frame=self.is_clear, fade=fade, x=(i*328)+self.move.attribute, y=self.overlay_move.attribute+y) tex.draw_texture(self.name, 'overlay', frame=self.is_clear, fade=fade, x=(i*328)+self.move.attribute, y=self.overlay_move.attribute+y)
class DonBG5(DonBGBase): class DonBG5(DonBGBase):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.bounce_up = tex.get_animation(4) self.bounce_up = tex.get_animation(4)
self.bounce_down = tex.get_animation(5) self.bounce_down = tex.get_animation(5)
@@ -125,7 +126,7 @@ class DonBG5(DonBGBase):
tex.draw_texture(self.name, 'overlay', frame=self.is_clear, fade=fade, x=(i*368)+(self.move.attribute * ((184/328)*2)), y=self.bounce_up.attribute - self.bounce_down.attribute - self.adjust.attribute + y) tex.draw_texture(self.name, 'overlay', frame=self.is_clear, fade=fade, x=(i*368)+(self.move.attribute * ((184/328)*2)), y=self.bounce_up.attribute - self.bounce_down.attribute - self.adjust.attribute + y)
class DonBG6(DonBGBase): class DonBG6(DonBGBase):
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str): def __init__(self, tex: TextureWrapper, index: int, player_num: PlayerNum, path: str):
super().__init__(tex, index, player_num, path) super().__init__(tex, index, player_num, path)
self.overlay_move = tex.get_animation(2) self.overlay_move = tex.get_animation(2)
def update(self, current_time_ms: float, is_clear: bool): def update(self, current_time_ms: float, is_clear: bool):

View File

@@ -3,6 +3,14 @@ from enum import IntEnum
from pathlib import Path from pathlib import Path
from typing import Any, TypedDict from typing import Any, TypedDict
class PlayerNum(IntEnum):
ALL = 0
P1 = 1
P2 = 2
TWO_PLAYER = 3
DAN = 4
class Difficulty(IntEnum): class Difficulty(IntEnum):
EASY = 0 EASY = 0
NORMAL = 1 NORMAL = 1
@@ -40,8 +48,8 @@ class NameplateConfig(TypedDict):
rainbow: bool rainbow: bool
class PathsConfig(TypedDict): class PathsConfig(TypedDict):
tja_path: list[str] tja_path: list[Path]
video_path: list[str] video_path: list[Path]
class KeysConfig(TypedDict): class KeysConfig(TypedDict):
exit_key: str exit_key: str
@@ -204,7 +212,7 @@ class GlobalData:
song_progress (float): The progress of the loading bar. song_progress (float): The progress of the loading bar.
total_songs (int): The total number of songs. total_songs (int): The total number of songs.
hit_sound (list[int]): The indices of the hit sounds currently used. hit_sound (list[int]): The indices of the hit sounds currently used.
player_num (int): The player number. Either 1 or 2. player_num (PlayerNum): The player number.
input_locked (int): The input lock status. 0 means unlocked, 1 or greater means locked. input_locked (int): The input lock status. 0 means unlocked, 1 or greater means locked.
modifiers (list[Modifiers]): The modifiers for the game. modifiers (list[Modifiers]): The modifiers for the game.
session_data (list[SessionData]): Session data for both players. session_data (list[SessionData]): Session data for both players.
@@ -215,15 +223,15 @@ class GlobalData:
song_paths: dict[Path, str] = field(default_factory=lambda: dict()) #path to hash song_paths: dict[Path, str] = field(default_factory=lambda: dict()) #path to hash
song_progress: float = 0.0 song_progress: float = 0.0
total_songs: int = 0 total_songs: int = 0
hit_sound: list[int] = field(default_factory=lambda: [0, 0]) hit_sound: list[int] = field(default_factory=lambda: [0, 0, 0])
player_num: int = 1 player_num: PlayerNum = PlayerNum.P1
input_locked: int = 0 input_locked: int = 0
modifiers: list[Modifiers] = field(default_factory=lambda: [Modifiers(), Modifiers()]) modifiers: list[Modifiers] = field(default_factory=lambda: [Modifiers(), Modifiers(), Modifiers()])
session_data: list[SessionData] = field(default_factory=lambda: [SessionData(), SessionData()]) session_data: list[SessionData] = field(default_factory=lambda: [SessionData(), SessionData(), SessionData()])
global_data = GlobalData() global_data = GlobalData()
def reset_session(): def reset_session():
"""Reset the session data.""" """Reset the session data."""
global_data.session_data[0] = SessionData()
global_data.session_data[1] = SessionData() global_data.session_data[1] = SessionData()
global_data.session_data[2] = SessionData()

View File

@@ -1,13 +1,14 @@
from enum import Enum from enum import Enum
import pyray as ray import pyray as ray
from libs.global_data import PlayerNum
from libs.utils import OutlinedText, get_config, global_tex from libs.utils import OutlinedText, get_config, global_tex
from libs.audio import audio from libs.audio import audio
class Nameplate: class Nameplate:
"""Nameplate for displaying player information.""" """Nameplate for displaying player information."""
def __init__(self, name: str, title: str, player_num: int, dan: int, is_gold: bool, is_rainbow: bool, title_bg: int): def __init__(self, name: str, title: str, player_num: PlayerNum, dan: int, is_gold: bool, is_rainbow: bool, title_bg: int):
"""Initialize a Nameplate object. """Initialize a Nameplate object.
Args: Args:
@@ -54,7 +55,7 @@ class Nameplate:
""" """
tex = global_tex tex = global_tex
tex.draw_texture('nameplate', 'shadow', x=x, y=y, fade=min(0.5, fade)) tex.draw_texture('nameplate', 'shadow', x=x, y=y, fade=min(0.5, fade))
if self.player_num == -1: if self.player_num == 0:
frame = 2 frame = 2
title_offset = 0 title_offset = 0
else: else:
@@ -75,7 +76,7 @@ class Nameplate:
else: else:
tex.draw_texture('nameplate', 'dan_emblem', x=x, y=y, frame=self.dan_index, fade=fade) tex.draw_texture('nameplate', 'dan_emblem', x=x, y=y, frame=self.dan_index, fade=fade)
offset = 34 offset = 34
if self.player_num != -1: if self.player_num != 0:
tex.draw_texture('nameplate', f'{self.player_num}p', x=x, y=y, fade=fade) tex.draw_texture('nameplate', f'{self.player_num}p', x=x, y=y, fade=fade)
self.name.draw(outline_color=ray.BLACK, x=x+136 - (min(255 - offset*4, self.name.texture.width)//2) + offset, y=y+24, x2=min(255 - offset*4, self.name.texture.width)-self.name.texture.width, color=ray.fade(ray.WHITE, fade)) self.name.draw(outline_color=ray.BLACK, x=x+136 - (min(255 - offset*4, self.name.texture.width)//2) + offset, y=y+24, x2=min(255 - offset*4, self.name.texture.width)-self.name.texture.width, color=ray.fade(ray.WHITE, fade))

View File

@@ -1,11 +1,10 @@
import ctypes import ctypes
import hashlib import hashlib
import math
import sys import sys
import logging import logging
import time import time
import json import json
from libs.global_data import Config, global_data from libs.global_data import Config, PlayerNum, global_data
from functools import lru_cache from functools import lru_cache
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
@@ -103,149 +102,73 @@ def get_key_code(key: str) -> int:
raise ValueError(f"Invalid key: {key}") raise ValueError(f"Invalid key: {key}")
return key_code return key_code
def is_l_don_pressed(player_num: str = '0') -> bool: def is_input_key_pressed(keys: list[str], gamepad_buttons: list[int]):
"""Check if the left don button is pressed"""
if global_data.input_locked: if global_data.input_locked:
return False return False
if player_num == '0': for key in keys:
key_code = get_key_code(key)
if ray.is_key_pressed(key_code):
return True
if ray.is_gamepad_available(0):
for button in gamepad_buttons:
if ray.is_gamepad_button_pressed(0, button):
return True
return False
def is_l_don_pressed(player_num: PlayerNum = PlayerNum.ALL) -> bool:
"""Check if the left don button is pressed"""
if player_num == PlayerNum.ALL:
keys = global_data.config["keys_1p"]["left_don"] + global_data.config["keys_2p"]["left_don"] keys = global_data.config["keys_1p"]["left_don"] + global_data.config["keys_2p"]["left_don"]
elif player_num == '1': elif player_num == PlayerNum.P1:
keys = global_data.config["keys_1p"]["left_don"] keys = global_data.config["keys_1p"]["left_don"]
elif player_num == '2': elif player_num == PlayerNum.P2:
keys = global_data.config["keys_2p"]["left_don"] keys = global_data.config["keys_2p"]["left_don"]
else: else:
return False return False
for key in keys:
key_code = get_key_code(key)
if ray.is_key_pressed(key_code):
return True
gamepad_buttons = global_data.config["gamepad"]["left_don"] gamepad_buttons = global_data.config["gamepad"]["left_don"]
if ray.is_gamepad_available(0): return is_input_key_pressed(keys, gamepad_buttons)
for button in gamepad_buttons:
if ray.is_gamepad_button_pressed(0, button):
return True
if not global_data.config["general"]["touch_enabled"]: def is_r_don_pressed(player_num: PlayerNum = PlayerNum.ALL) -> bool:
return False
mid_x, mid_y = (1280//2, 720)
allowed_gestures = {ray.Gesture.GESTURE_TAP, ray.Gesture.GESTURE_DOUBLETAP}
if ray.get_gesture_detected() in allowed_gestures and ray.is_gesture_detected(ray.get_gesture_detected()):
for i in range(min(ray.get_touch_point_count(), 10)):
tap_pos = (ray.get_touch_position(i).x, ray.get_touch_position(i).y)
if math.dist(tap_pos, (mid_x, mid_y)) < 300 and tap_pos[0] <= mid_x:
return True
return False
def is_r_don_pressed(player_num: str = '0') -> bool:
"""Check if the right don button is pressed""" """Check if the right don button is pressed"""
if global_data.input_locked: if player_num == PlayerNum.ALL:
return False
if player_num == '0':
keys = global_data.config["keys_1p"]["right_don"] + global_data.config["keys_2p"]["right_don"] keys = global_data.config["keys_1p"]["right_don"] + global_data.config["keys_2p"]["right_don"]
elif player_num == '1': elif player_num == PlayerNum.P1:
keys = global_data.config["keys_1p"]["right_don"] keys = global_data.config["keys_1p"]["right_don"]
elif player_num == '2': elif player_num == PlayerNum.P2:
keys = global_data.config["keys_2p"]["right_don"] keys = global_data.config["keys_2p"]["right_don"]
else: else:
return False return False
for key in keys:
key_code = get_key_code(key)
if ray.is_key_pressed(key_code):
return True
gamepad_buttons = global_data.config["gamepad"]["right_don"] gamepad_buttons = global_data.config["gamepad"]["right_don"]
if ray.is_gamepad_available(0): return is_input_key_pressed(keys, gamepad_buttons)
for button in gamepad_buttons:
if ray.is_gamepad_button_pressed(0, button):
return True
if not global_data.config["general"]["touch_enabled"]: def is_l_kat_pressed(player_num: PlayerNum = PlayerNum.ALL) -> bool:
return False
mid_x, mid_y = (1280//2, 720)
allowed_gestures = {ray.Gesture.GESTURE_TAP, ray.Gesture.GESTURE_DOUBLETAP}
if ray.get_gesture_detected() in allowed_gestures and ray.is_gesture_detected(ray.get_gesture_detected()):
for i in range(min(ray.get_touch_point_count(), 10)):
tap_pos = (ray.get_touch_position(i).x, ray.get_touch_position(i).y)
if math.dist(tap_pos, (mid_x, mid_y)) < 300 and tap_pos[0] > mid_x:
return True
return False
def is_l_kat_pressed(player_num: str = '0') -> bool:
"""Check if the left kat button is pressed""" """Check if the left kat button is pressed"""
if global_data.input_locked: if player_num == PlayerNum.ALL:
return False
if player_num == '0':
keys = global_data.config["keys_1p"]["left_kat"] + global_data.config["keys_2p"]["left_kat"] keys = global_data.config["keys_1p"]["left_kat"] + global_data.config["keys_2p"]["left_kat"]
elif player_num == '1': elif player_num == PlayerNum.P1:
keys = global_data.config["keys_1p"]["left_kat"] keys = global_data.config["keys_1p"]["left_kat"]
elif player_num == '2': elif player_num == PlayerNum.P2:
keys = global_data.config["keys_2p"]["left_kat"] keys = global_data.config["keys_2p"]["left_kat"]
else: else:
return False return False
for key in keys:
key_code = get_key_code(key)
if ray.is_key_pressed(key_code):
return True
gamepad_buttons = global_data.config["gamepad"]["left_kat"] gamepad_buttons = global_data.config["gamepad"]["left_kat"]
if ray.is_gamepad_available(0): return is_input_key_pressed(keys, gamepad_buttons)
for button in gamepad_buttons:
if ray.is_gamepad_button_pressed(0, button):
return True
if not global_data.config["general"]["touch_enabled"]: def is_r_kat_pressed(player_num: PlayerNum = PlayerNum.ALL) -> bool:
return False
mid_x, mid_y = (1280//2, 720)
allowed_gestures = {ray.Gesture.GESTURE_TAP, ray.Gesture.GESTURE_DOUBLETAP}
if ray.get_gesture_detected() in allowed_gestures and ray.is_gesture_detected(ray.get_gesture_detected()):
for i in range(min(ray.get_touch_point_count(), 10)):
tap_pos = (ray.get_touch_position(i).x, ray.get_touch_position(i).y)
if math.dist(tap_pos, (mid_x, mid_y)) >= 300 and tap_pos[0] <= mid_x:
return True
return False
def is_r_kat_pressed(player_num: str = '0') -> bool:
"""Check if the right kat button is pressed""" """Check if the right kat button is pressed"""
if global_data.input_locked: if player_num == PlayerNum.ALL:
return False
if player_num == '0':
keys = global_data.config["keys_1p"]["right_kat"] + global_data.config["keys_2p"]["right_kat"] keys = global_data.config["keys_1p"]["right_kat"] + global_data.config["keys_2p"]["right_kat"]
elif player_num == '1': elif player_num == PlayerNum.P1:
keys = global_data.config["keys_1p"]["right_kat"] keys = global_data.config["keys_1p"]["right_kat"]
elif player_num == '2': elif player_num == PlayerNum.P2:
keys = global_data.config["keys_2p"]["right_kat"] keys = global_data.config["keys_2p"]["right_kat"]
else: else:
return False return False
for key in keys:
key_code = get_key_code(key)
if ray.is_key_pressed(key_code):
return True
gamepad_buttons = global_data.config["gamepad"]["right_kat"] gamepad_buttons = global_data.config["gamepad"]["right_kat"]
if ray.is_gamepad_available(0): return is_input_key_pressed(keys, gamepad_buttons)
for button in gamepad_buttons:
if ray.is_gamepad_button_pressed(0, button):
return True
if not global_data.config["general"]["touch_enabled"]:
return False
mid_x, mid_y = (1280//2, 720)
allowed_gestures = {ray.Gesture.GESTURE_TAP, ray.Gesture.GESTURE_DOUBLETAP}
if ray.get_gesture_detected() in allowed_gestures and ray.is_gesture_detected(ray.get_gesture_detected()):
for i in range(min(ray.get_touch_point_count(), 10)):
tap_pos = (ray.get_touch_position(i).x, ray.get_touch_position(i).y)
if math.dist(tap_pos, (mid_x, mid_y)) >= 300 and tap_pos[0] > mid_x:
return True
return False
global_tex = TextureWrapper() global_tex = TextureWrapper()

View File

@@ -3,7 +3,7 @@ import pyray as ray
from libs.animation import Animation from libs.animation import Animation
from libs.chara_2d import Chara2D from libs.chara_2d import Chara2D
from libs.global_data import reset_session from libs.global_data import PlayerNum, reset_session
from libs.audio import audio from libs.audio import audio
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate
from libs.screen import Screen from libs.screen import Screen
@@ -28,11 +28,11 @@ class DanResultScreen(Screen):
self.coin_overlay = CoinOverlay() self.coin_overlay = CoinOverlay()
self.allnet_indicator = AllNetIcon() self.allnet_indicator = AllNetIcon()
self.start_ms = get_current_ms() self.start_ms = get_current_ms()
self.background = Background('4', 1280) self.background = Background(PlayerNum.DAN, 1280)
self.player = DanResultPlayer(global_data.player_num) self.player = DanResultPlayer(global_data.player_num)
self.is_result_2 = False self.is_result_2 = False
self.result_2_fade_in = tex.get_animation(1) self.result_2_fade_in = tex.get_animation(1)
self.gauge = DanGauge(str(global_data.player_num), global_data.session_data[global_data.player_num-1].dan_result_data.gauge_length) self.gauge = DanGauge(global_data.player_num, global_data.session_data[global_data.player_num-1].dan_result_data.gauge_length)
self.song_names = [OutlinedText(song.song_title, 40, ray.WHITE) for song in global_data.session_data[global_data.player_num-1].dan_result_data.songs] self.song_names = [OutlinedText(song.song_title, 40, ray.WHITE) for song in global_data.session_data[global_data.player_num-1].dan_result_data.songs]
self.hori_name = OutlinedText(global_data.session_data[global_data.player_num-1].dan_result_data.dan_title, 40, ray.WHITE) self.hori_name = OutlinedText(global_data.session_data[global_data.player_num-1].dan_result_data.dan_title, 40, ray.WHITE)
self.exam_info = global_data.session_data[global_data.player_num-1].dan_result_data.exams self.exam_info = global_data.session_data[global_data.player_num-1].dan_result_data.exams
@@ -204,7 +204,7 @@ class DanResultScreen(Screen):
self.draw_overlay() self.draw_overlay()
class DanResultPlayer: class DanResultPlayer:
def __init__(self, player_num: int): def __init__(self, player_num: PlayerNum):
plate_info = global_data.config[f'nameplate_{player_num}p'] plate_info = global_data.config[f'nameplate_{player_num}p']
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) self.nameplate = Nameplate(plate_info['name'], plate_info['title'], player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg'])
self.chara = Chara2D(player_num-1, 100) self.chara = Chara2D(player_num-1, 100)
@@ -219,7 +219,7 @@ class DanResultPlayer:
class DanGauge(Gauge): class DanGauge(Gauge):
"""The player's gauge""" """The player's gauge"""
def __init__(self, player_num: str, gauge_length: float): def __init__(self, player_num: PlayerNum, gauge_length: float):
self.player_num = player_num self.player_num = player_num
self.gauge_length = gauge_length self.gauge_length = gauge_length
self.visual_length = int(self.gauge_length * 8) self.visual_length = int(self.gauge_length * 8)

View File

@@ -3,7 +3,7 @@ import logging
import pyray as ray import pyray as ray
from libs.audio import audio from libs.audio import audio
from libs.global_data import global_data from libs.global_data import PlayerNum, global_data
from libs.texture import tex from libs.texture import tex
from libs.chara_2d import Chara2D from libs.chara_2d import Chara2D
from libs.global_objects import AllNetIcon, CoinOverlay, Indicator, Nameplate, Timer from libs.global_objects import AllNetIcon, CoinOverlay, Indicator, Nameplate, Timer
@@ -24,7 +24,7 @@ class DanSelectScreen(Screen):
self.allnet_indicator = AllNetIcon() self.allnet_indicator = AllNetIcon()
self.timer = Timer(60, get_current_ms(), self.navigator.select_current_item) self.timer = Timer(60, get_current_ms(), self.navigator.select_current_item)
self.indicator = Indicator(Indicator.State.SELECT) self.indicator = Indicator(Indicator.State.SELECT)
self.player = DanSelectPlayer(str(global_data.player_num)) self.player = DanSelectPlayer(global_data.player_num)
self.state = State.BROWSING self.state = State.BROWSING
self.transition = Transition('', '') self.transition = Transition('', '')
self.last_moved = 0 self.last_moved = 0
@@ -32,7 +32,7 @@ class DanSelectScreen(Screen):
audio.play_sound('dan_select', 'voice') audio.play_sound('dan_select', 'voice')
def on_screen_end(self, next_screen: str): def on_screen_end(self, next_screen: str):
session_data = global_data.session_data[global_data.player_num-1] session_data = global_data.session_data[global_data.player_num]
current_item = self.navigator.get_current_item() current_item = self.navigator.get_current_item()
if isinstance(current_item, DanCourse): if isinstance(current_item, DanCourse):
session_data.selected_song = current_item.charts[0] session_data.selected_song = current_item.charts[0]
@@ -118,7 +118,7 @@ class DanSelectScreen(Screen):
self.allnet_indicator.draw() self.allnet_indicator.draw()
class DanSelectPlayer: class DanSelectPlayer:
def __init__(self, player_num: str): def __init__(self, player_num: PlayerNum):
self.player_num = player_num self.player_num = player_num
self.selected_difficulty = -3 self.selected_difficulty = -3
self.prev_diff = -3 self.prev_diff = -3
@@ -135,7 +135,7 @@ class DanSelectPlayer:
self.chara = Chara2D(int(self.player_num) - 1, 100) self.chara = Chara2D(int(self.player_num) - 1, 100)
plate_info = global_data.config[f'nameplate_{self.player_num}p'] plate_info = global_data.config[f'nameplate_{self.player_num}p']
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], self.nameplate = Nameplate(plate_info['name'], plate_info['title'],
int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) self.player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg'])
def update(self, current_time): def update(self, current_time):
"""Update player state""" """Update player state"""
@@ -210,7 +210,7 @@ class DanSelectPlayer:
return None return None
def draw(self): def draw(self):
if self.player_num == '1': if self.player_num == PlayerNum.P1:
self.nameplate.draw(30, 640) self.nameplate.draw(30, 640)
self.chara.draw(x=-50, y=410) self.chara.draw(x=-50, y=410)
else: else:

View File

@@ -6,7 +6,7 @@ from libs.animation import Animation
from libs.audio import audio from libs.audio import audio
from libs.background import Background from libs.background import Background
from libs.file_navigator import Exam from libs.file_navigator import Exam
from libs.global_data import DanResultExam, DanResultSong, global_data from libs.global_data import DanResultExam, DanResultSong, PlayerNum, global_data
from libs.global_objects import AllNetIcon from libs.global_objects import AllNetIcon
from libs.tja import TJAParser from libs.tja import TJAParser
from libs.transition import Transition from libs.transition import Transition
@@ -45,7 +45,7 @@ class DanGameScreen(GameScreen):
logger.info("Loaded nijiiro notes textures") logger.info("Loaded nijiiro notes textures")
ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture0"), tex.textures['balloon']['rainbow_mask'].texture) ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture0"), tex.textures['balloon']['rainbow_mask'].texture)
ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture1"), tex.textures['balloon']['rainbow'].texture) ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture1"), tex.textures['balloon']['rainbow'].texture)
self.hori_name = OutlinedText(global_data.session_data[global_data.player_num-1].song_title, 40, ray.WHITE) self.hori_name = OutlinedText(global_data.session_data[global_data.player_num].song_title, 40, ray.WHITE)
self.init_dan() self.init_dan()
self.background = Background(global_data.player_num, self.bpm, scene_preset='DAN') self.background = Background(global_data.player_num, self.bpm, scene_preset='DAN')
self.transition = Transition('', '', is_second=True) self.transition = Transition('', '', is_second=True)
@@ -53,11 +53,11 @@ class DanGameScreen(GameScreen):
self.dan_transition = DanTransition() self.dan_transition = DanTransition()
self.dan_transition.start() self.dan_transition.start()
self.allnet_indicator = AllNetIcon() self.allnet_indicator = AllNetIcon()
self.result_transition = ResultTransition(4) self.result_transition = ResultTransition(PlayerNum.DAN)
self.load_hitsounds() self.load_hitsounds()
def init_dan(self): def init_dan(self):
session_data = global_data.session_data[global_data.player_num-1] session_data = global_data.session_data[global_data.player_num]
songs = copy.deepcopy(session_data.selected_dan) songs = copy.deepcopy(session_data.selected_dan)
self.exams = copy.deepcopy(session_data.selected_dan_exam) self.exams = copy.deepcopy(session_data.selected_dan_exam)
self.total_notes = 0 self.total_notes = 0
@@ -75,7 +75,7 @@ class DanGameScreen(GameScreen):
self.init_tja(song.file_path) self.init_tja(song.file_path)
self.color = session_data.dan_color self.color = session_data.dan_color
self.player_1.is_dan = True self.player_1.is_dan = True
self.player_1.gauge = DanGauge(str(global_data.player_num), self.total_notes) self.player_1.gauge = DanGauge(global_data.player_num, self.total_notes)
self.song_info = SongInfo(song.metadata.title.get(global_data.config["general"]["language"], "en"), genre_index) self.song_info = SongInfo(song.metadata.title.get(global_data.config["general"]["language"], "en"), genre_index)
self.bpm = self.tja.metadata.bpm self.bpm = self.tja.metadata.bpm
logger.info(f"TJA initialized for song: {song.file_path}") logger.info(f"TJA initialized for song: {song.file_path}")
@@ -85,7 +85,7 @@ class DanGameScreen(GameScreen):
self.exam_failed = [False] * len(self.exams) self.exam_failed = [False] * len(self.exams)
def change_song(self): def change_song(self):
session_data = global_data.session_data[global_data.player_num-1] session_data = global_data.session_data[global_data.player_num]
songs = session_data.selected_dan songs = session_data.selected_dan
song, genre_index, difficulty, level = songs[self.song_index] song, genre_index, difficulty, level = songs[self.song_index]
session_data.selected_difficulty = difficulty session_data.selected_difficulty = difficulty
@@ -174,7 +174,7 @@ class DanGameScreen(GameScreen):
@override @override
def spawn_ending_anims(self): def spawn_ending_anims(self):
if sum(song.bad for song in global_data.session_data[global_data.player_num-1].dan_result_data.songs) == 0: if sum(song.bad for song in global_data.session_data[global_data.player_num].dan_result_data.songs) == 0:
self.player_1.ending_anim = FCAnimation(self.player_1.is_2p) self.player_1.ending_anim = FCAnimation(self.player_1.is_2p)
if self.player_1.gauge.is_clear and not any(self.exam_failed): if self.player_1.gauge.is_clear and not any(self.exam_failed):
self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p) self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p)
@@ -205,7 +205,7 @@ class DanGameScreen(GameScreen):
logger.info("Result transition finished, moving to RESULT screen") logger.info("Result transition finished, moving to RESULT screen")
return self.on_screen_end('DAN_RESULT') return self.on_screen_end('DAN_RESULT')
elif self.current_ms >= self.player_1.end_time + 1000: elif self.current_ms >= self.player_1.end_time + 1000:
session_data = global_data.session_data[global_data.player_num-1] session_data = global_data.session_data[global_data.player_num]
if len(session_data.selected_dan) > len(session_data.dan_result_data.songs): if len(session_data.selected_dan) > len(session_data.dan_result_data.songs):
song_info = DanResultSong() song_info = DanResultSong()
song_info.song_title = self.song_info.song_name song_info.song_title = self.song_info.song_name
@@ -359,7 +359,7 @@ class DanTransition:
class DanGauge(Gauge): class DanGauge(Gauge):
"""The player's gauge""" """The player's gauge"""
def __init__(self, player_num: str, total_notes: int): def __init__(self, player_num: PlayerNum, total_notes: int):
self.player_num = player_num self.player_num = player_num
self.string_diff = "_hard" self.string_diff = "_hard"
self.gauge_length = 0 self.gauge_length = 0

View File

@@ -4,6 +4,7 @@ import pyray as ray
from libs.audio import audio from libs.audio import audio
from libs.chara_2d import Chara2D from libs.chara_2d import Chara2D
from libs.global_data import PlayerNum
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate, Indicator, EntryOverlay, Timer from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate, Indicator, EntryOverlay, Timer
from libs.texture import tex from libs.texture import tex
from libs.screen import Screen from libs.screen import Screen
@@ -34,7 +35,7 @@ class EntryScreen(Screen):
# Initial nameplate for side selection # Initial nameplate for side selection
plate_info = global_data.config['nameplate_1p'] plate_info = global_data.config['nameplate_1p']
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], -1, -1, False, False, 0) self.nameplate = Nameplate(plate_info['name'], plate_info['title'], PlayerNum.ALL, -1, False, False, 0)
self.coin_overlay = CoinOverlay() self.coin_overlay = CoinOverlay()
self.allnet_indicator = AllNetIcon() self.allnet_indicator = AllNetIcon()
@@ -62,12 +63,12 @@ class EntryScreen(Screen):
if is_l_don_pressed() or is_r_don_pressed(): if is_l_don_pressed() or is_r_don_pressed():
if self.side == 1: if self.side == 1:
return self.on_screen_end("TITLE") return self.on_screen_end("TITLE")
global_data.player_num = round((self.side/3) + 1) global_data.player_num = PlayerNum.P1 if self.side == 0 else PlayerNum.P2
if self.players[0]: if self.players[0]:
self.players[1] = EntryPlayer(global_data.player_num, self.side, self.box_manager) self.players[1] = EntryPlayer(global_data.player_num, self.side, self.box_manager)
self.players[1].start_animations() self.players[1].start_animations()
global_data.player_num = 1 global_data.player_num = PlayerNum.P1
self.is_2p = True self.is_2p = True
else: else:
self.players[0] = EntryPlayer(global_data.player_num, self.side, self.box_manager) self.players[0] = EntryPlayer(global_data.player_num, self.side, self.box_manager)
@@ -80,17 +81,17 @@ class EntryScreen(Screen):
audio.play_sound('don', 'sound') audio.play_sound('don', 'sound')
if is_l_kat_pressed(): if is_l_kat_pressed():
audio.play_sound('kat', 'sound') audio.play_sound('kat', 'sound')
if self.players[0] and self.players[0].player_num == 1: if self.players[0] and self.players[0].player_num == PlayerNum.P1:
self.side = 1 self.side = 1
elif self.players[0] and self.players[0].player_num == 2: elif self.players[0] and self.players[0].player_num == PlayerNum.P2:
self.side = 0 self.side = 0
else: else:
self.side = max(0, self.side - 1) self.side = max(0, self.side - 1)
if is_r_kat_pressed(): if is_r_kat_pressed():
audio.play_sound('kat', 'sound') audio.play_sound('kat', 'sound')
if self.players[0] and self.players[0].player_num == 1: if self.players[0] and self.players[0].player_num == PlayerNum.P1:
self.side = 2 self.side = 2
elif self.players[0] and self.players[0].player_num == 2: elif self.players[0] and self.players[0].player_num == PlayerNum.P2:
self.side = 1 self.side = 1
else: else:
self.side = min(2, self.side + 1) self.side = min(2, self.side + 1)
@@ -98,15 +99,15 @@ class EntryScreen(Screen):
for player in self.players: for player in self.players:
if player: if player:
player.handle_input() player.handle_input()
if self.players[0] and self.players[0].player_num == 1 and is_l_don_pressed('2') or is_r_don_pressed('2'): if self.players[0] and self.players[0].player_num == PlayerNum.P1 and is_l_don_pressed(PlayerNum.P2) or is_r_don_pressed(PlayerNum.P2):
audio.play_sound('don', 'sound') audio.play_sound('don', 'sound')
self.state = State.SELECT_SIDE self.state = State.SELECT_SIDE
plate_info = global_data.config['nameplate_2p'] plate_info = global_data.config['nameplate_2p']
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], -1, -1, False, False, 1) self.nameplate = Nameplate(plate_info['name'], plate_info['title'], PlayerNum.ALL, -1, False, False, 1)
self.chara = Chara2D(1, 100) self.chara = Chara2D(1, 100)
self.side_select_fade.restart() self.side_select_fade.restart()
self.side = 1 self.side = 1
elif self.players[0] and self.players[0].player_num == 2 and is_l_don_pressed('1') or is_r_don_pressed('1'): elif self.players[0] and self.players[0].player_num == PlayerNum.P2 and is_l_don_pressed(PlayerNum.P1) or is_r_don_pressed(PlayerNum.P1):
audio.play_sound('don', 'sound') audio.play_sound('don', 'sound')
self.state = State.SELECT_SIDE self.state = State.SELECT_SIDE
self.side_select_fade.restart() self.side_select_fade.restart()
@@ -198,9 +199,9 @@ class EntryScreen(Screen):
elif not self.players[0]: elif not self.players[0]:
tex.draw_texture('side_select', 'footer_left') tex.draw_texture('side_select', 'footer_left')
tex.draw_texture('side_select', 'footer_right') tex.draw_texture('side_select', 'footer_right')
elif self.players[0] and self.players[0].player_num == 1: elif self.players[0] and self.players[0].player_num == PlayerNum.P1:
tex.draw_texture('side_select', 'footer_right') tex.draw_texture('side_select', 'footer_right')
elif self.players[0] and self.players[0].player_num == 2: elif self.players[0] and self.players[0].player_num == PlayerNum.P2:
tex.draw_texture('side_select', 'footer_left') tex.draw_texture('side_select', 'footer_left')
@@ -220,7 +221,7 @@ class EntryScreen(Screen):
class EntryPlayer: class EntryPlayer:
"""Player-specific state and rendering for the entry screen""" """Player-specific state and rendering for the entry screen"""
def __init__(self, player_num: int, side: int, box_manager: 'BoxManager'): def __init__(self, player_num: PlayerNum, side: int, box_manager: 'BoxManager'):
""" """
Initialize a player for the entry screen Initialize a player for the entry screen
Args: Args:
@@ -341,13 +342,13 @@ class EntryPlayer:
if self.box_manager.is_box_selected(): if self.box_manager.is_box_selected():
return return
if is_l_don_pressed(str(self.player_num)) or is_r_don_pressed(str(self.player_num)): if is_l_don_pressed(self.player_num) or is_r_don_pressed(self.player_num):
audio.play_sound('don', 'sound') audio.play_sound('don', 'sound')
self.box_manager.select_box() self.box_manager.select_box()
if is_l_kat_pressed(str(self.player_num)): if is_l_kat_pressed(self.player_num):
audio.play_sound('kat', 'sound') audio.play_sound('kat', 'sound')
self.box_manager.move_left() self.box_manager.move_left()
if is_r_kat_pressed(str(self.player_num)): if is_r_kat_pressed(self.player_num):
audio.play_sound('kat', 'sound') audio.play_sound('kat', 'sound')
self.box_manager.move_right() self.box_manager.move_right()

View File

@@ -12,7 +12,7 @@ from libs.animation import Animation
from libs.audio import audio from libs.audio import audio
from libs.background import Background from libs.background import Background
from libs.chara_2d import Chara2D from libs.chara_2d import Chara2D
from libs.global_data import Crown, Difficulty, Modifiers from libs.global_data import Crown, Difficulty, Modifiers, PlayerNum
from libs.global_objects import AllNetIcon, Nameplate from libs.global_objects import AllNetIcon, Nameplate
from libs.screen import Screen from libs.screen import Screen
from libs.texture import tex from libs.texture import tex
@@ -71,7 +71,7 @@ class GameScreen(Screen):
logger.info("Loaded nijiiro notes textures") logger.info("Loaded nijiiro notes textures")
ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture0"), tex.textures['balloon']['rainbow_mask'].texture) ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture0"), tex.textures['balloon']['rainbow_mask'].texture)
ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture1"), tex.textures['balloon']['rainbow'].texture) ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture1"), tex.textures['balloon']['rainbow'].texture)
session_data = global_data.session_data[global_data.player_num-1] session_data = global_data.session_data[global_data.player_num]
self.init_tja(session_data.selected_song) self.init_tja(session_data.selected_song)
logger.info(f"TJA initialized for song: {session_data.selected_song}") logger.info(f"TJA initialized for song: {session_data.selected_song}")
self.load_hitsounds() self.load_hitsounds()
@@ -109,16 +109,16 @@ class GameScreen(Screen):
audio.load_sound(Path('none.wav'), 'hitsound_kat_1p') audio.load_sound(Path('none.wav'), 'hitsound_kat_1p')
logger.info("Loaded default (none) hit sounds for 1P") logger.info("Loaded default (none) hit sounds for 1P")
if global_data.hit_sound == 0: if global_data.hit_sound == 0:
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "don.wav", 'hitsound_don_1p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P1]) / "don.wav", 'hitsound_don_1p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "ka.wav", 'hitsound_kat_1p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P1]) / "ka.wav", 'hitsound_kat_1p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "don.wav", 'hitsound_don_2p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P2]) / "don.wav", 'hitsound_don_2p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "ka.wav", 'hitsound_kat_2p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P2]) / "ka.wav", 'hitsound_kat_2p')
logger.info("Loaded wav hit sounds for 1P and 2P") logger.info("Loaded wav hit sounds for 1P and 2P")
else: else:
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "don.ogg", 'hitsound_don_1p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P1]) / "don.ogg", 'hitsound_don_1p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "ka.ogg", 'hitsound_kat_1p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P1]) / "ka.ogg", 'hitsound_kat_1p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "don.ogg", 'hitsound_don_2p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P2]) / "don.ogg", 'hitsound_don_2p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "ka.ogg", 'hitsound_kat_2p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P2]) / "ka.ogg", 'hitsound_kat_2p')
logger.info("Loaded ogg hit sounds for 1P and 2P") logger.info("Loaded ogg hit sounds for 1P and 2P")
def init_tja(self, song: Path): def init_tja(self, song: Path):
@@ -129,11 +129,11 @@ class GameScreen(Screen):
self.movie.set_volume(0.0) self.movie.set_volume(0.0)
else: else:
self.movie = None self.movie = None
global_data.session_data[0].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en']) global_data.session_data[global_data.player_num].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None: if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None:
self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song') self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song')
self.player_1 = Player(self.tja, global_data.player_num, global_data.session_data[global_data.player_num-1].selected_difficulty, False, global_data.modifiers[0]) self.player_1 = Player(self.tja, global_data.player_num, global_data.session_data[global_data.player_num].selected_difficulty, False, global_data.modifiers[global_data.player_num])
self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000) self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000)
def get_song_hash(self, song: Path): def get_song_hash(self, song: Path):
@@ -158,10 +158,10 @@ class GameScreen(Screen):
def write_score(self): def write_score(self):
"""Write the score to the database""" """Write the score to the database"""
if global_data.modifiers[global_data.player_num-1].auto: if global_data.modifiers[global_data.player_num].auto:
return return
with sqlite3.connect('scores.db') as con: with sqlite3.connect('scores.db') as con:
session_data = global_data.session_data[global_data.player_num-1] session_data = global_data.session_data[global_data.player_num]
cursor = con.cursor() cursor = con.cursor()
hash = self.get_song_hash(session_data.selected_song) hash = self.get_song_hash(session_data.selected_song)
check_query = "SELECT score, clear FROM Scores WHERE hash = ? LIMIT 1" check_query = "SELECT score, clear FROM Scores WHERE hash = ? LIMIT 1"
@@ -221,7 +221,7 @@ class GameScreen(Screen):
if ray.is_key_pressed(get_key_code(global_data.config["keys"]["restart_key"])): if ray.is_key_pressed(get_key_code(global_data.config["keys"]["restart_key"])):
if self.song_music is not None: if self.song_music is not None:
audio.stop_music_stream(self.song_music) audio.stop_music_stream(self.song_music)
self.init_tja(global_data.session_data[global_data.player_num-1].selected_song) self.init_tja(global_data.session_data[global_data.player_num].selected_song)
audio.play_sound('restart', 'sound') audio.play_sound('restart', 'sound')
self.song_started = False self.song_started = False
@@ -234,7 +234,7 @@ class GameScreen(Screen):
self.pause_song() self.pause_song()
def spawn_ending_anims(self): def spawn_ending_anims(self):
if global_data.session_data[global_data.player_num-1].result_data.bad == 0: if global_data.session_data[global_data.player_num].result_data.bad == 0:
self.player_1.ending_anim = FCAnimation(self.player_1.is_2p) self.player_1.ending_anim = FCAnimation(self.player_1.is_2p)
elif self.player_1.gauge.is_clear: elif self.player_1.gauge.is_clear:
self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p) self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p)
@@ -269,7 +269,7 @@ class GameScreen(Screen):
logger.info("Result transition finished, moving to RESULT screen") logger.info("Result transition finished, moving to RESULT screen")
return self.on_screen_end('RESULT') return self.on_screen_end('RESULT')
elif self.current_ms >= self.player_1.end_time: elif self.current_ms >= self.player_1.end_time:
session_data = global_data.session_data[global_data.player_num-1] session_data = global_data.session_data[global_data.player_num]
session_data.result_data.score, session_data.result_data.good, session_data.result_data.ok, session_data.result_data.bad, session_data.result_data.max_combo, session_data.result_data.total_drumroll = self.player_1.get_result_score() session_data.result_data.score, session_data.result_data.good, session_data.result_data.ok, session_data.result_data.bad, session_data.result_data.max_combo, session_data.result_data.total_drumroll = self.player_1.get_result_score()
if self.player_1.gauge is not None: if self.player_1.gauge is not None:
session_data.result_data.gauge_length = self.player_1.gauge.gauge_length session_data.result_data.gauge_length = self.player_1.gauge.gauge_length
@@ -312,10 +312,10 @@ class Player:
TIMING_OK_EASY = 108.441665649414 TIMING_OK_EASY = 108.441665649414
TIMING_BAD_EASY = 125.125 TIMING_BAD_EASY = 125.125
def __init__(self, tja: TJAParser, player_number: int, difficulty: int, is_2p: bool, modifiers: Modifiers): def __init__(self, tja: TJAParser, player_num: PlayerNum, difficulty: int, is_2p: bool, modifiers: Modifiers):
self.is_2p = is_2p self.is_2p = is_2p
self.is_dan = False self.is_dan = False
self.player_number = str(player_number) self.player_num = player_num
self.difficulty = difficulty self.difficulty = difficulty
self.visual_offset = global_data.config["general"]["visual_offset"] self.visual_offset = global_data.config["general"]["visual_offset"]
self.modifiers = modifiers self.modifiers = modifiers
@@ -345,13 +345,13 @@ class Player:
self.combo_display = Combo(self.combo, 0, self.is_2p) self.combo_display = Combo(self.combo, 0, self.is_2p)
self.score_counter = ScoreCounter(self.score, self.is_2p) self.score_counter = ScoreCounter(self.score, self.is_2p)
self.gogo_time: Optional[GogoTime] = None self.gogo_time: Optional[GogoTime] = None
self.combo_announce = ComboAnnounce(self.combo, 0, player_number, self.is_2p) self.combo_announce = ComboAnnounce(self.combo, 0, player_num, self.is_2p)
self.branch_indicator = BranchIndicator(self.is_2p) if tja and tja.metadata.course_data[self.difficulty].is_branching else None self.branch_indicator = BranchIndicator(self.is_2p) if tja and tja.metadata.course_data[self.difficulty].is_branching else None
self.ending_anim: Optional[FailAnimation | ClearAnimation | FCAnimation] = None self.ending_anim: Optional[FailAnimation | ClearAnimation | FCAnimation] = None
self.is_gogo_time = False self.is_gogo_time = False
plate_info = global_data.config[f'nameplate_{self.is_2p+1}p'] plate_info = global_data.config[f'nameplate_{self.is_2p+1}p']
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], global_data.player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) self.nameplate = Nameplate(plate_info['name'], plate_info['title'], global_data.player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg'])
self.chara = Chara2D(player_number - 1, self.bpm) self.chara = Chara2D(player_num - 1, self.bpm)
if global_data.config['general']['judge_counter']: if global_data.config['general']['judge_counter']:
self.judge_counter = JudgeCounter() self.judge_counter = JudgeCounter()
else: else:
@@ -359,7 +359,7 @@ class Player:
self.input_log: dict[float, str] = dict() self.input_log: dict[float, str] = dict()
stars = tja.metadata.course_data[self.difficulty].level stars = tja.metadata.course_data[self.difficulty].level
self.gauge = Gauge(self.player_number, self.difficulty, stars, self.total_notes, self.is_2p) self.gauge = Gauge(self.player_num, self.difficulty, stars, self.total_notes, self.is_2p)
self.gauge_hit_effect: list[GaugeHitEffect] = [] self.gauge_hit_effect: list[GaugeHitEffect] = []
self.autoplay_hit_side = 'L' self.autoplay_hit_side = 'L'
@@ -628,12 +628,12 @@ class Player:
if self.combo % 10 == 0: if self.combo % 10 == 0:
self.chara.set_animation('10_combo') self.chara.set_animation('10_combo')
if self.combo % 100 == 0: if self.combo % 100 == 0:
self.combo_announce = ComboAnnounce(self.combo, current_time, int(self.player_number), self.is_2p) self.combo_announce = ComboAnnounce(self.combo, current_time, self.player_num, self.is_2p)
if self.combo > self.max_combo: if self.combo > self.max_combo:
self.max_combo = self.combo self.max_combo = self.combo
if note.type != NoteType.KUSUDAMA: if note.type != NoteType.KUSUDAMA:
self.draw_arc_list.append(NoteArc(note.type, current_time, self.is_2p + 1, note.type == NoteType.DON_L or note.type == NoteType.KAT_L or note.type == NoteType.BALLOON_HEAD, note.type == NoteType.BALLOON_HEAD)) self.draw_arc_list.append(NoteArc(note.type, current_time, PlayerNum(self.is_2p + 1), note.type == NoteType.DON_L or note.type == NoteType.KAT_L or note.type == NoteType.BALLOON_HEAD, note.type == NoteType.BALLOON_HEAD))
if note in self.current_notes_draw: if note in self.current_notes_draw:
index = self.current_notes_draw.index(note) index = self.current_notes_draw.index(note)
@@ -641,7 +641,7 @@ class Player:
def check_drumroll(self, drum_type: int, background: Optional[Background], current_time: float): def check_drumroll(self, drum_type: int, background: Optional[Background], current_time: float):
"""Checks if a note has been hit during a drumroll""" """Checks if a note has been hit during a drumroll"""
self.draw_arc_list.append(NoteArc(drum_type, current_time, self.is_2p + 1, drum_type == 3 or drum_type == 4, False)) self.draw_arc_list.append(NoteArc(drum_type, current_time, PlayerNum(self.is_2p + 1), drum_type == 3 or drum_type == 4, False))
self.curr_drumroll_count += 1 self.curr_drumroll_count += 1
self.total_drumroll += 1 self.total_drumroll += 1
if self.is_branch and self.branch_condition == 'r': if self.is_branch and self.branch_condition == 'r':
@@ -649,7 +649,7 @@ class Player:
if background is not None: if background is not None:
background.add_renda() background.add_renda()
self.score += 100 self.score += 100
self.base_score_list.append(ScoreCounterAnimation(self.player_number, 100, self.is_2p)) self.base_score_list.append(ScoreCounterAnimation(self.player_num, 100, self.is_2p))
if not isinstance(self.current_notes_draw[0], Drumroll): if not isinstance(self.current_notes_draw[0], Drumroll):
return return
self.current_notes_draw[0].color = max(0, 255 - (self.curr_drumroll_count * 10)) self.current_notes_draw[0].color = max(0, 255 - (self.curr_drumroll_count * 10))
@@ -662,11 +662,11 @@ class Player:
self.check_kusudama(note) self.check_kusudama(note)
return return
if self.balloon_anim is None: if self.balloon_anim is None:
self.balloon_anim = BalloonAnimation(current_time, note.count, int(self.player_number), self.is_2p) self.balloon_anim = BalloonAnimation(current_time, note.count, self.player_num, self.is_2p)
self.curr_balloon_count += 1 self.curr_balloon_count += 1
self.total_drumroll += 1 self.total_drumroll += 1
self.score += 100 self.score += 100
self.base_score_list.append(ScoreCounterAnimation(self.player_number, 100, self.is_2p)) self.base_score_list.append(ScoreCounterAnimation(self.player_num, 100, self.is_2p))
if self.curr_balloon_count == note.count: if self.curr_balloon_count == note.count:
self.is_balloon = False self.is_balloon = False
note.popped = True note.popped = True
@@ -682,7 +682,7 @@ class Player:
self.curr_balloon_count += 1 self.curr_balloon_count += 1
self.total_drumroll += 1 self.total_drumroll += 1
self.score += 100 self.score += 100
self.base_score_list.append(ScoreCounterAnimation(self.player_number, 100, self.is_2p)) self.base_score_list.append(ScoreCounterAnimation(self.player_num, 100, self.is_2p))
if self.curr_balloon_count == note.count: if self.curr_balloon_count == note.count:
audio.play_sound('kusudama_pop', 'hitsound') audio.play_sound('kusudama_pop', 'hitsound')
self.is_balloon = False self.is_balloon = False
@@ -734,7 +734,7 @@ class Player:
self.lane_hit_effect = LaneHitEffect('GOOD', self.is_2p) self.lane_hit_effect = LaneHitEffect('GOOD', self.is_2p)
self.good_count += 1 self.good_count += 1
self.score += self.base_score self.score += self.base_score
self.base_score_list.append(ScoreCounterAnimation(self.player_number, self.base_score, self.is_2p)) self.base_score_list.append(ScoreCounterAnimation(self.player_num, self.base_score, self.is_2p))
self.input_log[curr_note.index] = 'GOOD' self.input_log[curr_note.index] = 'GOOD'
self.note_correct(curr_note, current_time) self.note_correct(curr_note, current_time)
if self.gauge is not None: if self.gauge is not None:
@@ -751,7 +751,7 @@ class Player:
self.draw_judge_list.append(Judgement('OK', big, self.is_2p)) self.draw_judge_list.append(Judgement('OK', big, self.is_2p))
self.ok_count += 1 self.ok_count += 1
self.score += 10 * math.floor(self.base_score / 2 / 10) self.score += 10 * math.floor(self.base_score / 2 / 10)
self.base_score_list.append(ScoreCounterAnimation(self.player_number, 10 * math.floor(self.base_score / 2 / 10), self.is_2p)) self.base_score_list.append(ScoreCounterAnimation(self.player_num, 10 * math.floor(self.base_score / 2 / 10), self.is_2p))
self.input_log[curr_note.index] = 'OK' self.input_log[curr_note.index] = 'OK'
self.note_correct(curr_note, current_time) self.note_correct(curr_note, current_time)
if self.gauge is not None: if self.gauge is not None:
@@ -813,13 +813,13 @@ class Player:
def handle_input(self, ms_from_start: float, current_time: float, background: Optional[Background]): def handle_input(self, ms_from_start: float, current_time: float, background: Optional[Background]):
input_checks = [ input_checks = [
(is_l_don_pressed, 'DON', 'L', f'hitsound_don_{self.player_number}p'), (is_l_don_pressed, 'DON', 'L', f'hitsound_don_{self.player_num}p'),
(is_r_don_pressed, 'DON', 'R', f'hitsound_don_{self.player_number}p'), (is_r_don_pressed, 'DON', 'R', f'hitsound_don_{self.player_num}p'),
(is_l_kat_pressed, 'KAT', 'L', f'hitsound_kat_{self.player_number}p'), (is_l_kat_pressed, 'KAT', 'L', f'hitsound_kat_{self.player_num}p'),
(is_r_kat_pressed, 'KAT', 'R', f'hitsound_kat_{self.player_number}p') (is_r_kat_pressed, 'KAT', 'R', f'hitsound_kat_{self.player_num}p')
] ]
for check_func, note_type, side, sound in input_checks: for check_func, note_type, side, sound in input_checks:
if check_func(self.player_number): if check_func(self.player_num):
self.spawn_hit_effects(note_type, side) self.spawn_hit_effects(note_type, side)
audio.play_sound(sound, 'hitsound') audio.play_sound(sound, 'hitsound')
@@ -846,7 +846,7 @@ class Player:
hit_type = 'DON' hit_type = 'DON'
self.autoplay_hit_side = 'R' if self.autoplay_hit_side == 'L' else 'L' self.autoplay_hit_side = 'R' if self.autoplay_hit_side == 'L' else 'L'
self.spawn_hit_effects(hit_type, self.autoplay_hit_side) self.spawn_hit_effects(hit_type, self.autoplay_hit_side)
audio.play_sound(f'hitsound_don_{self.player_number}p', 'hitsound') audio.play_sound(f'hitsound_don_{self.player_num}p', 'hitsound')
note_type = NoteType.DON_L if note.type == NoteType.ROLL_HEAD_L else NoteType.DON note_type = NoteType.DON_L if note.type == NoteType.ROLL_HEAD_L else NoteType.DON
self.check_note(ms_from_start, note_type, current_time, background) self.check_note(ms_from_start, note_type, current_time, background)
else: else:
@@ -856,7 +856,7 @@ class Player:
hit_type = 'DON' hit_type = 'DON'
self.autoplay_hit_side = 'R' if self.autoplay_hit_side == 'L' else 'L' self.autoplay_hit_side = 'R' if self.autoplay_hit_side == 'L' else 'L'
self.spawn_hit_effects(hit_type, self.autoplay_hit_side) self.spawn_hit_effects(hit_type, self.autoplay_hit_side)
audio.play_sound(f'hitsound_don_{self.player_number}p', 'hitsound') audio.play_sound(f'hitsound_don_{self.player_num}p', 'hitsound')
self.check_note(ms_from_start, 1, current_time, background) self.check_note(ms_from_start, 1, current_time, background)
# Handle KAT notes # Handle KAT notes
@@ -865,7 +865,7 @@ class Player:
hit_type = 'KAT' hit_type = 'KAT'
self.autoplay_hit_side = 'R' if self.autoplay_hit_side == 'L' else 'L' self.autoplay_hit_side = 'R' if self.autoplay_hit_side == 'L' else 'L'
self.spawn_hit_effects(hit_type, self.autoplay_hit_side) self.spawn_hit_effects(hit_type, self.autoplay_hit_side)
audio.play_sound(f'hitsound_kat_{self.player_number}p', 'hitsound') audio.play_sound(f'hitsound_kat_{self.player_num}p', 'hitsound')
self.check_note(ms_from_start, 2, current_time, background) self.check_note(ms_from_start, 2, current_time, background)
def evaluate_branch(self, current_ms): def evaluate_branch(self, current_ms):
@@ -1066,21 +1066,21 @@ class Player:
modifiers_to_draw = ['mod_shinuchi'] modifiers_to_draw = ['mod_shinuchi']
# Speed modifiers # Speed modifiers
if global_data.modifiers[int(self.player_number)-1].speed >= 4: if global_data.modifiers[self.player_num].speed >= 4:
modifiers_to_draw.append('mod_yonbai') modifiers_to_draw.append('mod_yonbai')
elif global_data.modifiers[int(self.player_number)-1].speed >= 3: elif global_data.modifiers[self.player_num].speed >= 3:
modifiers_to_draw.append('mod_sanbai') modifiers_to_draw.append('mod_sanbai')
elif global_data.modifiers[int(self.player_number)-1].speed > 1: elif global_data.modifiers[self.player_num].speed > 1:
modifiers_to_draw.append('mod_baisaku') modifiers_to_draw.append('mod_baisaku')
# Other modifiers # Other modifiers
if global_data.modifiers[int(self.player_number)-1].display: if global_data.modifiers[self.player_num].display:
modifiers_to_draw.append('mod_doron') modifiers_to_draw.append('mod_doron')
if global_data.modifiers[int(self.player_number)-1].inverse: if global_data.modifiers[self.player_num].inverse:
modifiers_to_draw.append('mod_abekobe') modifiers_to_draw.append('mod_abekobe')
if global_data.modifiers[int(self.player_number)-1].random == 2: if global_data.modifiers[self.player_num].random == 2:
modifiers_to_draw.append('mod_detarame') modifiers_to_draw.append('mod_detarame')
elif global_data.modifiers[int(self.player_number)-1].random == 1: elif global_data.modifiers[self.player_num].random == 1:
modifiers_to_draw.append('mod_kimagure') modifiers_to_draw.append('mod_kimagure')
# Draw all modifiers in one batch # Draw all modifiers in one batch
@@ -1089,7 +1089,7 @@ class Player:
def draw_overlays(self, mask_shader: ray.Shader): def draw_overlays(self, mask_shader: ray.Shader):
# Group 4: Lane covers and UI elements (batch similar textures) # Group 4: Lane covers and UI elements (batch similar textures)
tex.draw_texture('lane', f'{self.player_number}p_lane_cover', index=self.is_2p) tex.draw_texture('lane', f'{self.player_num}p_lane_cover', index=self.is_2p)
if self.is_dan: if self.is_dan:
tex.draw_texture('lane', 'dan_lane_cover') tex.draw_texture('lane', 'dan_lane_cover')
tex.draw_texture('lane', 'drum', index=self.is_2p) tex.draw_texture('lane', 'drum', index=self.is_2p)
@@ -1111,7 +1111,7 @@ class Player:
tex.draw_texture('lane', 'lane_score_cover', index=self.is_2p, mirror='vertical') tex.draw_texture('lane', 'lane_score_cover', index=self.is_2p, mirror='vertical')
else: else:
tex.draw_texture('lane', 'lane_score_cover', index=self.is_2p) tex.draw_texture('lane', 'lane_score_cover', index=self.is_2p)
tex.draw_texture('lane', f'{self.player_number}p_icon', index=self.is_2p) tex.draw_texture('lane', f'{self.player_num}p_icon', index=self.is_2p)
if self.is_dan: if self.is_dan:
tex.draw_texture('lane', 'lane_difficulty', frame=6) tex.draw_texture('lane', 'lane_difficulty', frame=6)
else: else:
@@ -1373,7 +1373,7 @@ class GaugeHitEffect:
class NoteArc: class NoteArc:
"""Note arcing from the player to the gauge""" """Note arcing from the player to the gauge"""
def __init__(self, note_type: int, current_ms: float, player_number: int, big: bool, is_balloon: bool): def __init__(self, note_type: int, current_ms: float, player_num: PlayerNum, big: bool, is_balloon: bool):
self.note_type = note_type self.note_type = note_type
self.is_big = big self.is_big = big
self.is_balloon = is_balloon self.is_balloon = is_balloon
@@ -1381,7 +1381,7 @@ class NoteArc:
self.arc_duration = 22 self.arc_duration = 22
self.current_progress = 0 self.current_progress = 0
self.create_ms = current_ms self.create_ms = current_ms
self.player_number = player_number self.player_num = player_num
self.explosion_point_index = 0 self.explosion_point_index = 0
self.points_per_explosion = 5 self.points_per_explosion = 5
@@ -1389,13 +1389,13 @@ class NoteArc:
curve_height = 425 curve_height = 425
self.start_x, self.start_y = 350, 192 self.start_x, self.start_y = 350, 192
self.end_x, self.end_y = 1158, 101 self.end_x, self.end_y = 1158, 101
if self.player_number == 2: if self.player_num == PlayerNum.P2:
self.start_y += 176 self.start_y += 176
self.end_y += 372 self.end_y += 372
self.explosion_x = self.start_x self.explosion_x = self.start_x
self.explosion_y = self.start_y self.explosion_y = self.start_y
if self.player_number == 1: if self.player_num == PlayerNum.P1:
# Control point influences the curve shape # Control point influences the curve shape
self.control_x = (self.start_x + self.end_x) // 2 self.control_x = (self.start_x + self.end_x) // 2
self.control_y = min(self.start_y, self.end_y) - curve_height # Arc upward self.control_y = min(self.start_y, self.end_y) - curve_height # Arc upward
@@ -1447,7 +1447,7 @@ class NoteArc:
def draw(self, mask_shader: ray.Shader): def draw(self, mask_shader: ray.Shader):
if self.is_balloon: if self.is_balloon:
rainbow = tex.textures['balloon']['rainbow'] rainbow = tex.textures['balloon']['rainbow']
if self.player_number == 2: if self.player_num == PlayerNum.P2:
rainbow_height = -rainbow.height rainbow_height = -rainbow.height
else: else:
rainbow_height = rainbow.height rainbow_height = rainbow.height
@@ -1462,8 +1462,8 @@ class NoteArc:
if crop_width > 0: if crop_width > 0:
src = ray.Rectangle(crop_start_x, 0, crop_width, rainbow_height) src = ray.Rectangle(crop_start_x, 0, crop_width, rainbow_height)
mirror = 'vertical' if self.player_number == 2 else '' mirror = 'vertical' if self.player_num == PlayerNum.P2 else ''
y = 435 if self.player_number == 2 else 0 y = 435 if self.player_num == PlayerNum.P2 else 0
ray.begin_shader_mode(mask_shader) ray.begin_shader_mode(mask_shader)
tex.draw_texture('balloon', 'rainbow_mask', src=src, x=crop_start_x, x2=-rainbow.width + crop_width, mirror=mirror, y=y) tex.draw_texture('balloon', 'rainbow_mask', src=src, x=crop_start_x, x2=-rainbow.width + crop_width, mirror=mirror, y=y)
ray.end_shader_mode() ray.end_shader_mode()
@@ -1510,7 +1510,7 @@ class DrumrollCounter:
class BalloonAnimation: class BalloonAnimation:
"""Draws a Balloon""" """Draws a Balloon"""
def __init__(self, current_ms: float, balloon_total: int, player_num: int, is_2p: bool): def __init__(self, current_ms: float, balloon_total: int, player_num: PlayerNum, is_2p: bool):
self.player_num = player_num self.player_num = player_num
self.is_2p = is_2p self.is_2p = is_2p
self.create_ms = current_ms self.create_ms = current_ms
@@ -1726,7 +1726,7 @@ class ScoreCounter:
class ScoreCounterAnimation: class ScoreCounterAnimation:
"""Displays the score init being added to the total score""" """Displays the score init being added to the total score"""
def __init__(self, player_num: str, counter: int, is_2p: bool): def __init__(self, player_num: PlayerNum, counter: int, is_2p: bool):
self.is_2p = is_2p self.is_2p = is_2p
self.counter = counter self.counter = counter
self.direction = -1 if self.is_2p else 1 self.direction = -1 if self.is_2p else 1
@@ -1743,7 +1743,7 @@ class ScoreCounterAnimation:
self.move_animation_4 = Animation.create_move(80, delay=366.74, total_distance=10, start_position=148) self.move_animation_4 = Animation.create_move(80, delay=366.74, total_distance=10, start_position=148)
self.move_animation_4.start() self.move_animation_4.start()
if player_num == '2': if player_num == PlayerNum.P2:
self.base_color = ray.Color(84, 250, 238, 255) self.base_color = ray.Color(84, 250, 238, 255)
else: else:
self.base_color = ray.Color(254, 102, 0, 255) self.base_color = ray.Color(254, 102, 0, 255)
@@ -1819,7 +1819,7 @@ class SongInfo:
class ResultTransition: class ResultTransition:
"""Displays the result transition animation""" """Displays the result transition animation"""
def __init__(self, player_num: int): def __init__(self, player_num: PlayerNum):
self.player_num = player_num self.player_num = player_num
self.move = global_tex.get_animation(5) self.move = global_tex.get_animation(5)
self.move.reset() self.move.reset()
@@ -1838,16 +1838,16 @@ class ResultTransition:
x = 0 x = 0
screen_width = 1280 screen_width = 1280
while x < screen_width: while x < screen_width:
if self.player_num == 3: if self.player_num == PlayerNum.TWO_PLAYER:
global_tex.draw_texture('result_transition', '1p_shutter', frame=0, x=x, y=-720 + self.move.attribute) global_tex.draw_texture('result_transition', '1p_shutter', frame=0, x=x, y=-720 + self.move.attribute)
global_tex.draw_texture('result_transition', '2p_shutter', frame=0, x=x, y=720 - self.move.attribute) global_tex.draw_texture('result_transition', '2p_shutter', frame=0, x=x, y=720 - self.move.attribute)
global_tex.draw_texture('result_transition', '1p_shutter_footer', x=x, y=-432 + self.move.attribute) global_tex.draw_texture('result_transition', '1p_shutter_footer', x=x, y=-432 + self.move.attribute)
global_tex.draw_texture('result_transition', '2p_shutter_footer', x=x, y=1008 - self.move.attribute) global_tex.draw_texture('result_transition', '2p_shutter_footer', x=x, y=1008 - self.move.attribute)
else: else:
global_tex.draw_texture('result_transition', f'{str(self.player_num)}p_shutter', frame=0, x=x, y=-720 + self.move.attribute) global_tex.draw_texture('result_transition', f'{self.player_num}p_shutter', frame=0, x=x, y=-720 + self.move.attribute)
global_tex.draw_texture('result_transition', f'{str(self.player_num)}p_shutter', frame=0, x=x, y=720 - self.move.attribute) global_tex.draw_texture('result_transition', f'{self.player_num}p_shutter', frame=0, x=x, y=720 - self.move.attribute)
global_tex.draw_texture('result_transition', f'{str(self.player_num)}p_shutter_footer', x=x, y=-432 + self.move.attribute) global_tex.draw_texture('result_transition', f'{self.player_num}p_shutter_footer', x=x, y=-432 + self.move.attribute)
global_tex.draw_texture('result_transition', f'{str(self.player_num)}p_shutter_footer', x=x, y=1008 - self.move.attribute) global_tex.draw_texture('result_transition', f'{self.player_num}p_shutter_footer', x=x, y=1008 - self.move.attribute)
x += 256 x += 256
class GogoTime: class GogoTime:
@@ -1874,7 +1874,7 @@ class GogoTime:
class ComboAnnounce: class ComboAnnounce:
"""Displays the combo every 100 combos""" """Displays the combo every 100 combos"""
def __init__(self, combo: int, current_time_ms: float, player_num: int, is_2p: bool): def __init__(self, combo: int, current_time_ms: float, player_num: PlayerNum, is_2p: bool):
self.player_num = player_num self.player_num = player_num
self.is_2p = is_2p self.is_2p = is_2p
self.combo = combo self.combo = combo
@@ -2187,7 +2187,7 @@ class JudgeCounter:
class Gauge: class Gauge:
"""The player's gauge""" """The player's gauge"""
def __init__(self, player_num: str, difficulty: int, level: int, total_notes: int, is_2p: bool): def __init__(self, player_num: PlayerNum, difficulty: int, level: int, total_notes: int, is_2p: bool):
self.is_2p = is_2p self.is_2p = is_2p
self.player_num = player_num self.player_num = player_num
self.string_diff = "_hard" self.string_diff = "_hard"

View File

@@ -8,7 +8,7 @@ import copy
from libs.animation import Animation from libs.animation import Animation
from libs.audio import audio from libs.audio import audio
from libs.background import Background from libs.background import Background
from libs.global_data import Modifiers, global_data from libs.global_data import Modifiers, PlayerNum, global_data
from libs.tja import Balloon, Drumroll, Note, NoteType, TJAParser, apply_modifiers from libs.tja import Balloon, Drumroll, Note, NoteType, TJAParser, apply_modifiers
from libs.utils import get_current_ms, get_key_code from libs.utils import get_current_ms, get_key_code
from libs.texture import tex from libs.texture import tex
@@ -19,7 +19,7 @@ logger = logging.getLogger(__name__)
class PracticeGameScreen(GameScreen): class PracticeGameScreen(GameScreen):
def on_screen_start(self): def on_screen_start(self):
super().on_screen_start() super().on_screen_start()
self.background = Background(1, self.bpm, scene_preset='PRACTICE') self.background = Background(PlayerNum.P1, self.bpm, scene_preset='PRACTICE')
def init_tja(self, song: Path): def init_tja(self, song: Path):
"""Initialize the TJA file""" """Initialize the TJA file"""
@@ -28,7 +28,7 @@ class PracticeGameScreen(GameScreen):
global_data.session_data[0].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en']) global_data.session_data[0].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None: if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None:
self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song') self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song')
self.player_1 = PracticePlayer(self.tja, global_data.player_num, global_data.session_data[global_data.player_num-1].selected_difficulty, False, global_data.modifiers[0]) self.player_1 = PracticePlayer(self.tja, global_data.player_num, global_data.session_data[global_data.player_num].selected_difficulty, False, global_data.modifiers[global_data.player_num])
notes, branch_m, branch_e, branch_n = self.tja.notes_to_position(self.player_1.difficulty) notes, branch_m, branch_e, branch_n = self.tja.notes_to_position(self.player_1.difficulty)
_, self.scrobble_note_list, self.bars = apply_modifiers(notes, self.player_1.modifiers) _, self.scrobble_note_list, self.bars = apply_modifiers(notes, self.player_1.modifiers)
self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000) self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000)
@@ -96,7 +96,7 @@ class PracticeGameScreen(GameScreen):
if ray.is_key_pressed(get_key_code(global_data.config["keys"]["restart_key"])): if ray.is_key_pressed(get_key_code(global_data.config["keys"]["restart_key"])):
if self.song_music is not None: if self.song_music is not None:
audio.stop_music_stream(self.song_music) audio.stop_music_stream(self.song_music)
self.init_tja(global_data.session_data[global_data.player_num-1].selected_song) self.init_tja(global_data.session_data[global_data.player_num].selected_song)
audio.play_sound('restart', 'sound') audio.play_sound('restart', 'sound')
self.song_started = False self.song_started = False
@@ -253,7 +253,7 @@ class PracticeGameScreen(GameScreen):
tex.draw_texture('practice', 'large_drum', index=1) tex.draw_texture('practice', 'large_drum', index=1)
self.player_1.draw_overlays(self.mask_shader) self.player_1.draw_overlays(self.mask_shader)
if not self.paused: if not self.paused:
tex.draw_texture('practice', 'playing', index=int(self.player_1.player_number)-1, fade=0.5) tex.draw_texture('practice', 'playing', index=self.player_1.player_num-1, fade=0.5)
tex.draw_texture('practice', 'progress_bar_bg') tex.draw_texture('practice', 'progress_bar_bg')
if self.paused: if self.paused:
tex.draw_texture('practice', 'paused', fade=0.5) tex.draw_texture('practice', 'paused', fade=0.5)
@@ -267,19 +267,19 @@ class PracticeGameScreen(GameScreen):
class PracticePlayer(Player): class PracticePlayer(Player):
def __init__(self, tja: TJAParser, player_number: int, difficulty: int, is_2p: bool, modifiers: Modifiers): def __init__(self, tja: TJAParser, player_num: PlayerNum, difficulty: int, is_2p: bool, modifiers: Modifiers):
super().__init__(tja, player_number, difficulty, is_2p, modifiers) super().__init__(tja, player_num, difficulty, is_2p, modifiers)
self.judge_counter = JudgeCounter() self.judge_counter = JudgeCounter()
self.gauge = None self.gauge = None
self.paused = False self.paused = False
def spawn_hit_effects(self, note_type: str, side: str): def spawn_hit_effects(self, note_type: str, side: str):
self.lane_hit_effect = LaneHitEffect(note_type, self.is_2p) self.lane_hit_effect = LaneHitEffect(note_type, self.is_2p)
self.draw_drum_hit_list.append(PracticeDrumHitEffect(note_type, side, self.is_2p, player_number=int(self.player_number)-1)) self.draw_drum_hit_list.append(PracticeDrumHitEffect(note_type, side, self.is_2p, player_num=self.player_num))
def draw_overlays(self, mask_shader: ray.Shader): def draw_overlays(self, mask_shader: ray.Shader):
# Group 4: Lane covers and UI elements (batch similar textures) # Group 4: Lane covers and UI elements (batch similar textures)
tex.draw_texture('lane', f'{self.player_number}p_lane_cover', index=self.is_2p) tex.draw_texture('lane', f'{self.player_num}p_lane_cover', index=self.is_2p)
tex.draw_texture('lane', 'drum', index=self.is_2p) tex.draw_texture('lane', 'drum', index=self.is_2p)
if self.ending_anim is not None: if self.ending_anim is not None:
self.ending_anim.draw() self.ending_anim.draw()
@@ -295,7 +295,7 @@ class PracticePlayer(Player):
# Group 6: UI overlays # Group 6: UI overlays
self.combo_display.draw() self.combo_display.draw()
self.combo_announce.draw() self.combo_announce.draw()
tex.draw_texture('lane', f'{self.player_number}p_icon', index=self.is_2p) tex.draw_texture('lane', f'{self.player_num}p_icon', index=self.is_2p)
tex.draw_texture('lane', 'lane_difficulty', frame=self.difficulty, index=self.is_2p) tex.draw_texture('lane', 'lane_difficulty', frame=self.difficulty, index=self.is_2p)
if self.judge_counter is not None: if self.judge_counter is not None:
self.judge_counter.draw() self.judge_counter.draw()
@@ -343,9 +343,9 @@ class PracticePlayer(Player):
self.draw_notes(ms_from_start, start_ms) self.draw_notes(ms_from_start, start_ms)
class PracticeDrumHitEffect(DrumHitEffect): class PracticeDrumHitEffect(DrumHitEffect):
def __init__(self, type, side, is_2p, player_number: int = 0): def __init__(self, type, side, is_2p, player_num: PlayerNum = PlayerNum.P1):
super().__init__(type, side, is_2p) super().__init__(type, side, is_2p)
self.player_number = player_number self.player_num = player_num - 1
def draw(self): def draw(self):
if self.type == 'DON': if self.type == 'DON':
@@ -353,11 +353,11 @@ class PracticeDrumHitEffect(DrumHitEffect):
tex.draw_texture('lane', 'drum_don_l', index=self.is_2p, fade=self.fade.attribute) tex.draw_texture('lane', 'drum_don_l', index=self.is_2p, fade=self.fade.attribute)
elif self.side == 'R': elif self.side == 'R':
tex.draw_texture('lane', 'drum_don_r', index=self.is_2p, fade=self.fade.attribute) tex.draw_texture('lane', 'drum_don_r', index=self.is_2p, fade=self.fade.attribute)
tex.draw_texture('practice', 'large_drum_don', index=self.player_number, fade=self.fade.attribute) tex.draw_texture('practice', 'large_drum_don', index=self.player_num, fade=self.fade.attribute)
elif self.type == 'KAT': elif self.type == 'KAT':
if self.side == 'L': if self.side == 'L':
tex.draw_texture('lane', 'drum_kat_l', index=self.is_2p, fade=self.fade.attribute) tex.draw_texture('lane', 'drum_kat_l', index=self.is_2p, fade=self.fade.attribute)
tex.draw_texture('practice', 'large_drum_kat_l', index=self.player_number, fade=self.fade.attribute) tex.draw_texture('practice', 'large_drum_kat_l', index=self.player_num, fade=self.fade.attribute)
elif self.side == 'R': elif self.side == 'R':
tex.draw_texture('lane', 'drum_kat_r', index=self.is_2p, fade=self.fade.attribute) tex.draw_texture('lane', 'drum_kat_r', index=self.is_2p, fade=self.fade.attribute)
tex.draw_texture('practice', 'large_drum_kat_r', index=self.player_number, fade=self.fade.attribute) tex.draw_texture('practice', 'large_drum_kat_r', index=self.player_num, fade=self.fade.attribute)

View File

@@ -1,7 +1,7 @@
import logging import logging
import pyray as ray import pyray as ray
from libs.global_data import Difficulty, reset_session from libs.global_data import Difficulty, PlayerNum, reset_session
from libs.audio import audio from libs.audio import audio
from libs.chara_2d import Chara2D from libs.chara_2d import Chara2D
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate
@@ -26,16 +26,16 @@ class State:
class ResultScreen(Screen): class ResultScreen(Screen):
def on_screen_start(self): def on_screen_start(self):
super().on_screen_start() super().on_screen_start()
self.song_info = OutlinedText(global_data.session_data[0].song_title, 40, ray.WHITE, outline_thickness=5) self.song_info = OutlinedText(global_data.session_data[global_data.player_num].song_title, 40, ray.WHITE, outline_thickness=5)
audio.play_sound('bgm', 'music') audio.play_sound('bgm', 'music')
self.fade_in = FadeIn(str(global_data.player_num)) self.fade_in = FadeIn(global_data.player_num)
self.fade_out = tex.get_animation(0) self.fade_out = tex.get_animation(0)
self.coin_overlay = CoinOverlay() self.coin_overlay = CoinOverlay()
self.allnet_indicator = AllNetIcon() self.allnet_indicator = AllNetIcon()
self.start_ms = get_current_ms() self.start_ms = get_current_ms()
self.is_skipped = False self.is_skipped = False
self.background = Background(str(global_data.player_num), 1280) self.background = Background(global_data.player_num, 1280)
self.player_1 = ResultPlayer(str(global_data.player_num), False, False) self.player_1 = ResultPlayer(global_data.player_num, False, False)
def on_screen_end(self, next_screen: str): def on_screen_end(self, next_screen: str):
global_data.songs_played += 1 global_data.songs_played += 1
@@ -82,12 +82,12 @@ class ResultScreen(Screen):
class Background: class Background:
def __init__(self, player_num: str, width: int): def __init__(self, player_num: PlayerNum, width: int):
self.player_num = player_num self.player_num = player_num
self.width = width self.width = width
def draw(self): def draw(self):
x = 0 x = 0
if self.player_num == '3': if self.player_num == PlayerNum.TWO_PLAYER:
while x < self.width: while x < self.width:
tex.draw_texture('background', 'background_1p', x=x, y=-360) tex.draw_texture('background', 'background_1p', x=x, y=-360)
tex.draw_texture('background', 'background_2p', x=x, y=360) tex.draw_texture('background', 'background_2p', x=x, y=360)
@@ -104,7 +104,7 @@ class Background:
tex.draw_texture('background', 'result_text') tex.draw_texture('background', 'result_text')
class ResultPlayer: class ResultPlayer:
def __init__(self, player_num: str, has_2p: bool, is_2p: bool): def __init__(self, player_num: PlayerNum, has_2p: bool, is_2p: bool):
self.player_num = player_num self.player_num = player_num
self.has_2p = has_2p self.has_2p = has_2p
self.is_2p = is_2p self.is_2p = is_2p
@@ -117,10 +117,10 @@ class ResultPlayer:
self.state = None self.state = None
self.high_score_indicator = None self.high_score_indicator = None
self.chara = Chara2D(int(self.player_num) - 1, 100) self.chara = Chara2D(int(self.player_num) - 1, 100)
session_data = global_data.session_data[int(self.player_num)-1] session_data = global_data.session_data[self.player_num]
self.score_animator = ScoreAnimator(session_data.result_data.score) self.score_animator = ScoreAnimator(session_data.result_data.score)
plate_info = global_data.config[f'nameplate_{self.player_num}p'] plate_info = global_data.config[f'nameplate_{self.player_num}p']
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) self.nameplate = Nameplate(plate_info['name'], plate_info['title'], self.player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg'])
self.score, self.good, self.ok, self.bad, self.max_combo, self.total_drumroll = '', '', '', '', '', '' self.score, self.good, self.ok, self.bad, self.max_combo, self.total_drumroll = '', '', '', '', '', ''
self.update_list: list[tuple[str, int]] = [('score', session_data.result_data.score), self.update_list: list[tuple[str, int]] = [('score', session_data.result_data.score),
('good', session_data.result_data.good), ('good', session_data.result_data.good),
@@ -162,14 +162,14 @@ class ResultPlayer:
self.score_animator = ScoreAnimator(self.update_list[self.update_index][1]) self.score_animator = ScoreAnimator(self.update_list[self.update_index][1])
self.score_delay += 16.67 * 3 self.score_delay += 16.67 * 3
if self.update_index > 0 and self.high_score_indicator is None: if self.update_index > 0 and self.high_score_indicator is None:
session_data = global_data.session_data[int(self.player_num)-1] session_data = global_data.session_data[self.player_num]
if session_data.result_data.score > session_data.result_data.prev_score: if session_data.result_data.score > session_data.result_data.prev_score:
self.high_score_indicator = HighScoreIndicator(session_data.result_data.prev_score, session_data.result_data.score, self.is_2p) self.high_score_indicator = HighScoreIndicator(session_data.result_data.prev_score, session_data.result_data.score, self.is_2p)
def update(self, current_ms: float, fade_in_finished: bool, is_skipped: bool): def update(self, current_ms: float, fade_in_finished: bool, is_skipped: bool):
self.fade_in_finished = fade_in_finished self.fade_in_finished = fade_in_finished
if self.fade_in_finished and self.gauge is None: if self.fade_in_finished and self.gauge is None:
self.gauge = Gauge(self.player_num, global_data.session_data[int(self.player_num)-1].result_data.gauge_length, self.is_2p) self.gauge = Gauge(self.player_num, global_data.session_data[self.player_num].result_data.gauge_length, self.is_2p)
self.bottom_characters.start() self.bottom_characters.start()
self.bottom_characters.update(self.state) self.bottom_characters.update(self.state)
self.update_score_animation(is_skipped) self.update_score_animation(is_skipped)
@@ -221,19 +221,19 @@ class ResultPlayer:
def draw_modifiers(self): def draw_modifiers(self):
"""Draw the modifiers if enabled.""" """Draw the modifiers if enabled."""
if global_data.modifiers[int(self.player_num)-1].display: if global_data.modifiers[self.player_num].display:
tex.draw_texture('score', 'mod_doron', index=self.is_2p) tex.draw_texture('score', 'mod_doron', index=self.is_2p)
if global_data.modifiers[int(self.player_num)-1].inverse: if global_data.modifiers[self.player_num].inverse:
tex.draw_texture('score', 'mod_abekobe', index=self.is_2p) tex.draw_texture('score', 'mod_abekobe', index=self.is_2p)
if global_data.modifiers[int(self.player_num)-1].random == 1: if global_data.modifiers[self.player_num].random == 1:
tex.draw_texture('score', 'mod_kimagure', index=self.is_2p) tex.draw_texture('score', 'mod_kimagure', index=self.is_2p)
elif global_data.modifiers[int(self.player_num)-1].random == 2: elif global_data.modifiers[self.player_num].random == 2:
tex.draw_texture('score', 'mod_detarame', index=self.is_2p) tex.draw_texture('score', 'mod_detarame', index=self.is_2p)
if global_data.modifiers[int(self.player_num)-1].speed >= 4: if global_data.modifiers[self.player_num].speed >= 4:
tex.draw_texture('score', 'mod_yonbai', index=self.is_2p) tex.draw_texture('score', 'mod_yonbai', index=self.is_2p)
elif global_data.modifiers[int(self.player_num)-1].speed >= 3: elif global_data.modifiers[self.player_num].speed >= 3:
tex.draw_texture('score', 'mod_sanbai', index=self.is_2p) tex.draw_texture('score', 'mod_sanbai', index=self.is_2p)
elif global_data.modifiers[int(self.player_num)-1].speed > 1: elif global_data.modifiers[self.player_num].speed > 1:
tex.draw_texture('score', 'mod_baisaku', index=self.is_2p) tex.draw_texture('score', 'mod_baisaku', index=self.is_2p)
def draw(self): def draw(self):
@@ -249,7 +249,7 @@ class ResultPlayer:
elif self.state == State.CLEAR: elif self.state == State.CLEAR:
tex.draw_texture('background', 'gradient_clear', fade=min(0.4, self.fade_in_bottom.attribute), y=y) tex.draw_texture('background', 'gradient_clear', fade=min(0.4, self.fade_in_bottom.attribute), y=y)
tex.draw_texture('score', 'overlay', color=ray.fade(ray.WHITE, 0.75), index=self.is_2p) tex.draw_texture('score', 'overlay', color=ray.fade(ray.WHITE, 0.75), index=self.is_2p)
tex.draw_texture('score', 'difficulty', frame=global_data.session_data[int(self.player_num)-1].selected_difficulty, index=self.is_2p) tex.draw_texture('score', 'difficulty', frame=global_data.session_data[self.player_num].selected_difficulty, index=self.is_2p)
if not self.has_2p: if not self.has_2p:
self.bottom_characters.draw() self.bottom_characters.draw()
@@ -390,7 +390,7 @@ class BottomCharacters:
class FadeIn: class FadeIn:
"""A fade out disguised as a fade in""" """A fade out disguised as a fade in"""
def __init__(self, player_num: str): def __init__(self, player_num: PlayerNum):
self.fadein = tex.get_animation(15) self.fadein = tex.get_animation(15)
self.fadein.start() self.fadein.start()
self.is_finished = False self.is_finished = False
@@ -402,7 +402,7 @@ class FadeIn:
def draw(self): def draw(self):
x = 0 x = 0
if self.player_num == '3': if self.player_num == PlayerNum.TWO_PLAYER:
while x < 1280: while x < 1280:
tex.draw_texture('background', 'background_1p', x=x, y=-360, fade=self.fadein.attribute) tex.draw_texture('background', 'background_1p', x=x, y=-360, fade=self.fadein.attribute)
tex.draw_texture('background', 'background_2p', x=x, y=360, fade=self.fadein.attribute) tex.draw_texture('background', 'background_2p', x=x, y=360, fade=self.fadein.attribute)
@@ -466,10 +466,10 @@ class HighScoreIndicator:
class Gauge: class Gauge:
"""The gauge from the game screen, at 0.9x scale""" """The gauge from the game screen, at 0.9x scale"""
def __init__(self, player_num: str, gauge_length: float, is_2p: bool): def __init__(self, player_num: PlayerNum, gauge_length: float, is_2p: bool):
self.is_2p = is_2p self.is_2p = is_2p
self.player_num = player_num self.player_num = player_num
self.difficulty = min(Difficulty.HARD, global_data.session_data[int(player_num)-1].selected_difficulty) self.difficulty = min(Difficulty.HARD, global_data.session_data[player_num].selected_difficulty)
self.gauge_length = gauge_length self.gauge_length = gauge_length
self.clear_start = [69, 69, 69] self.clear_start = [69, 69, 69]
self.gauge_max = 87 self.gauge_max = 87

View File

@@ -9,7 +9,7 @@ from libs.file_navigator import DanCourse, navigator
from libs.audio import audio from libs.audio import audio
from libs.chara_2d import Chara2D from libs.chara_2d import Chara2D
from libs.file_navigator import Directory, SongBox, SongFile from libs.file_navigator import Directory, SongBox, SongFile
from libs.global_data import Difficulty, Modifiers from libs.global_data import Difficulty, Modifiers, PlayerNum
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate, Indicator, Timer from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate, Indicator, Timer
from libs.screen import Screen from libs.screen import Screen
from libs.texture import tex from libs.texture import tex
@@ -67,8 +67,8 @@ class SongSelectScreen(Screen):
self.ura_switch_animation = UraSwitchAnimation() self.ura_switch_animation = UraSwitchAnimation()
self.dan_transition = DanTransition() self.dan_transition = DanTransition()
session_data = global_data.session_data[global_data.player_num-1] session_data = global_data.session_data[global_data.player_num]
self.player_1 = SongSelectPlayer(str(global_data.player_num), self.text_fade_in) self.player_1 = SongSelectPlayer(global_data.player_num, self.text_fade_in)
if self.navigator.items == []: if self.navigator.items == []:
logger.warning("No navigator items found, returning to ENTRY screen") logger.warning("No navigator items found, returning to ENTRY screen")
@@ -84,9 +84,9 @@ class SongSelectScreen(Screen):
self.navigator.add_recent() self.navigator.add_recent()
def finalize_song(self): def finalize_song(self):
global_data.session_data[global_data.player_num-1].selected_song = self.navigator.get_current_item().path global_data.session_data[global_data.player_num].selected_song = self.navigator.get_current_item().path
global_data.session_data[global_data.player_num-1].selected_difficulty = self.player_1.selected_difficulty global_data.session_data[global_data.player_num].selected_difficulty = self.player_1.selected_difficulty
global_data.session_data[global_data.player_num-1].genre_index = self.navigator.get_current_item().box.name_texture_index global_data.session_data[global_data.player_num].genre_index = self.navigator.get_current_item().box.name_texture_index
def on_screen_end(self, next_screen): def on_screen_end(self, next_screen):
self.screen_init = False self.screen_init = False
@@ -374,7 +374,7 @@ class SongSelectScreen(Screen):
self.allnet_indicator.draw() self.allnet_indicator.draw()
class SongSelectPlayer: class SongSelectPlayer:
def __init__(self, player_num: str, text_fade_in): def __init__(self, player_num: PlayerNum, text_fade_in):
self.player_num = player_num self.player_num = player_num
self.selected_difficulty = -3 self.selected_difficulty = -3
self.prev_diff = -3 self.prev_diff = -3
@@ -400,7 +400,7 @@ class SongSelectPlayer:
self.chara = Chara2D(int(self.player_num) - 1, 100) self.chara = Chara2D(int(self.player_num) - 1, 100)
plate_info = global_data.config[f'nameplate_{self.player_num}p'] plate_info = global_data.config[f'nameplate_{self.player_num}p']
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], self.nameplate = Nameplate(plate_info['name'], plate_info['title'],
int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg']) self.player_num, plate_info['dan'], plate_info['gold'], plate_info['rainbow'], plate_info['title_bg'])
def update(self, current_time): def update(self, current_time):
"""Update player state""" """Update player state"""
@@ -681,7 +681,7 @@ class SongSelectPlayer:
def draw_background_diffs(self, state: int): def draw_background_diffs(self, state: int):
if (self.selected_song and state == State.SONG_SELECTED and self.selected_difficulty >= Difficulty.EASY): if (self.selected_song and state == State.SONG_SELECTED and self.selected_difficulty >= Difficulty.EASY):
if self.player_num == '2': if self.player_num == PlayerNum.P2:
tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, fade=min(0.5, self.selected_diff_fadein.attribute), x=1025, y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute) tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, fade=min(0.5, self.selected_diff_fadein.attribute), x=1025, y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute)
if self.selected_diff_highlight_fade.is_reversing or self.selected_diff_highlight_fade.is_finished: if self.selected_diff_highlight_fade.is_reversing or self.selected_diff_highlight_fade.is_finished:
tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, x=1025, y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute) tex.draw_texture('global', 'background_diff', frame=self.selected_difficulty, x=1025, y=-self.selected_diff_bounce.attribute, y2=self.selected_diff_bounce.attribute)
@@ -713,7 +713,7 @@ class SongSelectPlayer:
offset += -370 offset += -370
else: else:
offset *= -1 offset *= -1
if self.player_num == '1': if self.player_num == PlayerNum.P1:
self.nameplate.draw(30, 640) self.nameplate.draw(30, 640)
self.chara.draw(x=-50, y=410 + (offset*0.6)) self.chara.draw(x=-50, y=410 + (offset*0.6))
else: else:
@@ -981,9 +981,9 @@ class DiffSortSelect:
class NeiroSelector: class NeiroSelector:
"""The menu for selecting the game hitsounds.""" """The menu for selecting the game hitsounds."""
def __init__(self, player_num: str): def __init__(self, player_num: PlayerNum):
self.player_num = player_num self.player_num = player_num
self.selected_sound = global_data.hit_sound[int(self.player_num)-1] self.selected_sound = global_data.hit_sound[self.player_num]
with open(Path("Sounds") / 'hit_sounds' / 'neiro_list.txt', encoding='utf-8-sig') as neiro_list: with open(Path("Sounds") / 'hit_sounds' / 'neiro_list.txt', encoding='utf-8-sig') as neiro_list:
self.sounds = neiro_list.readlines() self.sounds = neiro_list.readlines()
self.sounds.append('無音') self.sounds.append('無音')
@@ -1049,9 +1049,9 @@ class NeiroSelector:
if self.move.is_started and not self.move.is_finished: if self.move.is_started and not self.move.is_finished:
return return
if self.selected_sound == len(self.sounds): if self.selected_sound == len(self.sounds):
global_data.hit_sound[int(self.player_num)-1] = -1 global_data.hit_sound[self.player_num] = -1
else: else:
global_data.hit_sound[int(self.player_num)-1] = self.selected_sound global_data.hit_sound[self.player_num] = self.selected_sound
self.is_confirmed = True self.is_confirmed = True
self.move.restart() self.move.restart()
@@ -1106,7 +1106,7 @@ class ModifierSelector:
"inverse": "あべこべ", "inverse": "あべこべ",
"random": "ランダム" "random": "ランダム"
} }
def __init__(self, player_num: str): def __init__(self, player_num: PlayerNum):
self.player_num = player_num self.player_num = player_num
self.mods = fields(Modifiers) self.mods = fields(Modifiers)
self.current_mod_index = 0 self.current_mod_index = 0
@@ -1123,14 +1123,14 @@ class ModifierSelector:
self.text_name = [OutlinedText(ModifierSelector.NAME_MAP[mod.name], 30, ray.WHITE, outline_thickness=3.5) for mod in self.mods] self.text_name = [OutlinedText(ModifierSelector.NAME_MAP[mod.name], 30, ray.WHITE, outline_thickness=3.5) for mod in self.mods]
self.text_true = OutlinedText('する', 30, ray.WHITE, outline_thickness=3.5) self.text_true = OutlinedText('する', 30, ray.WHITE, outline_thickness=3.5)
self.text_false = OutlinedText('しない', 30, ray.WHITE, outline_thickness=3.5) self.text_false = OutlinedText('しない', 30, ray.WHITE, outline_thickness=3.5)
self.text_speed = OutlinedText(str(global_data.modifiers[int(self.player_num)-1].speed), 30, ray.WHITE, outline_thickness=3.5) self.text_speed = OutlinedText(str(global_data.modifiers[self.player_num].speed), 30, ray.WHITE, outline_thickness=3.5)
self.text_kimagure = OutlinedText('きまぐれ', 30, ray.WHITE, outline_thickness=3.5) self.text_kimagure = OutlinedText('きまぐれ', 30, ray.WHITE, outline_thickness=3.5)
self.text_detarame = OutlinedText('でたらめ', 30, ray.WHITE, outline_thickness=3.5) self.text_detarame = OutlinedText('でたらめ', 30, ray.WHITE, outline_thickness=3.5)
# Secondary text objects for animation # Secondary text objects for animation
self.text_true_2 = OutlinedText('する', 30, ray.WHITE, outline_thickness=3.5) self.text_true_2 = OutlinedText('する', 30, ray.WHITE, outline_thickness=3.5)
self.text_false_2 = OutlinedText('しない', 30, ray.WHITE, outline_thickness=3.5) self.text_false_2 = OutlinedText('しない', 30, ray.WHITE, outline_thickness=3.5)
self.text_speed_2 = OutlinedText(str(global_data.modifiers[int(self.player_num)-1].speed), 30, ray.WHITE, outline_thickness=3.5) self.text_speed_2 = OutlinedText(str(global_data.modifiers[self.player_num].speed), 30, ray.WHITE, outline_thickness=3.5)
self.text_kimagure_2 = OutlinedText('きまぐれ', 30, ray.WHITE, outline_thickness=3.5) self.text_kimagure_2 = OutlinedText('きまぐれ', 30, ray.WHITE, outline_thickness=3.5)
self.text_detarame_2 = OutlinedText('でたらめ', 30, ray.WHITE, outline_thickness=3.5) self.text_detarame_2 = OutlinedText('でたらめ', 30, ray.WHITE, outline_thickness=3.5)
@@ -1161,7 +1161,7 @@ class ModifierSelector:
# Update primary text objects immediately # Update primary text objects immediately
current_mod = self.mods[self.current_mod_index] current_mod = self.mods[self.current_mod_index]
current_value = getattr(global_data.modifiers[int(self.player_num)-1], current_mod.name) current_value = getattr(global_data.modifiers[self.player_num], current_mod.name)
if current_mod.name == 'speed': if current_mod.name == 'speed':
# text_speed_2 becomes the old value (fades out) # text_speed_2 becomes the old value (fades out)
@@ -1192,34 +1192,34 @@ class ModifierSelector:
if self.is_confirmed: if self.is_confirmed:
return return
current_mod = self.mods[self.current_mod_index] current_mod = self.mods[self.current_mod_index]
current_value = getattr(global_data.modifiers[int(self.player_num)-1], current_mod.name) current_value = getattr(global_data.modifiers[self.player_num], current_mod.name)
if current_mod.type is bool: if current_mod.type is bool:
setattr(global_data.modifiers[int(self.player_num)-1], current_mod.name, not current_value) setattr(global_data.modifiers[self.player_num], current_mod.name, not current_value)
self._start_text_animation(-1, current_value) self._start_text_animation(-1, current_value)
elif current_mod.name == 'speed': elif current_mod.name == 'speed':
new_value = max(0.1, (current_value*10 - 1))/10 new_value = max(0.1, (current_value*10 - 1))/10
setattr(global_data.modifiers[int(self.player_num)-1], current_mod.name, new_value) setattr(global_data.modifiers[self.player_num], current_mod.name, new_value)
self._start_text_animation(-1, current_value) self._start_text_animation(-1, current_value)
elif current_mod.name == 'random': elif current_mod.name == 'random':
new_value = max(0, current_value-1) new_value = max(0, current_value-1)
setattr(global_data.modifiers[int(self.player_num)-1], current_mod.name, new_value) setattr(global_data.modifiers[self.player_num], current_mod.name, new_value)
self._start_text_animation(-1, current_value) self._start_text_animation(-1, current_value)
def right(self): def right(self):
if self.is_confirmed: if self.is_confirmed:
return return
current_mod = self.mods[self.current_mod_index] current_mod = self.mods[self.current_mod_index]
current_value = getattr(global_data.modifiers[int(self.player_num)-1], current_mod.name) current_value = getattr(global_data.modifiers[self.player_num], current_mod.name)
if current_mod.type is bool: if current_mod.type is bool:
setattr(global_data.modifiers[int(self.player_num)-1], current_mod.name, not current_value) setattr(global_data.modifiers[self.player_num], current_mod.name, not current_value)
self._start_text_animation(1, current_value) self._start_text_animation(1, current_value)
elif current_mod.name == 'speed': elif current_mod.name == 'speed':
new_value = (current_value*10 + 1)/10 new_value = (current_value*10 + 1)/10
setattr(global_data.modifiers[int(self.player_num)-1], current_mod.name, new_value) setattr(global_data.modifiers[self.player_num], current_mod.name, new_value)
self._start_text_animation(1, current_value) self._start_text_animation(1, current_value)
elif current_mod.name == 'random': elif current_mod.name == 'random':
new_value = (current_value+1) % 3 new_value = (current_value+1) % 3
setattr(global_data.modifiers[int(self.player_num)-1], current_mod.name, new_value) setattr(global_data.modifiers[self.player_num], current_mod.name, new_value)
self._start_text_animation(1, current_value) self._start_text_animation(1, current_value)
def _draw_animated_text(self, text_primary: OutlinedText, text_secondary: OutlinedText, x: float, y: float, should_animate: bool): def _draw_animated_text(self, text_primary: OutlinedText, text_secondary: OutlinedText, x: float, y: float, should_animate: bool):
@@ -1253,7 +1253,7 @@ class ModifierSelector:
self.text_name[i].draw(outline_color=ray.BLACK, x=92 + x, y=819 + move + (i*50)) self.text_name[i].draw(outline_color=ray.BLACK, x=92 + x, y=819 + move + (i*50))
current_mod = self.mods[i] current_mod = self.mods[i]
current_value = getattr(global_data.modifiers[int(self.player_num)-1], current_mod.name) current_value = getattr(global_data.modifiers[self.player_num], current_mod.name)
is_current_mod = (i == self.current_mod_index) is_current_mod = (i == self.current_mod_index)
if current_mod.type is bool: if current_mod.type is bool:

View File

@@ -1,6 +1,7 @@
import logging import logging
import copy import copy
from pathlib import Path from pathlib import Path
from libs.global_data import PlayerNum
from libs.tja import TJAParser from libs.tja import TJAParser
from libs.utils import get_current_ms from libs.utils import get_current_ms
from libs.audio import audio from libs.audio import audio
@@ -17,41 +18,41 @@ class TwoPlayerGameScreen(GameScreen):
scene_preset = self.tja.metadata.scene_preset scene_preset = self.tja.metadata.scene_preset
if self.background is not None: if self.background is not None:
self.background.unload() self.background.unload()
self.background = Background(3, self.bpm, scene_preset=scene_preset) self.background = Background(PlayerNum.TWO_PLAYER, self.bpm, scene_preset=scene_preset)
self.result_transition = ResultTransition(3) self.result_transition = ResultTransition(PlayerNum.TWO_PLAYER)
def load_hitsounds(self): def load_hitsounds(self):
"""Load the hit sounds""" """Load the hit sounds"""
sounds_dir = Path("Sounds") sounds_dir = Path("Sounds")
# Load hitsounds for 1P # Load hitsounds for 1P
if global_data.hit_sound[0] == -1: if global_data.hit_sound[PlayerNum.P1] == -1:
audio.load_sound(Path('none.wav'), 'hitsound_don_1p') audio.load_sound(Path('none.wav'), 'hitsound_don_1p')
audio.load_sound(Path('none.wav'), 'hitsound_kat_1p') audio.load_sound(Path('none.wav'), 'hitsound_kat_1p')
logger.info("Loaded default (none) hit sounds for 1P") logger.info("Loaded default (none) hit sounds for 1P")
elif global_data.hit_sound[0] == 0: elif global_data.hit_sound[PlayerNum.P1] == 0:
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "don.wav", 'hitsound_don_1p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P1]) / "don.wav", 'hitsound_don_1p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "ka.wav", 'hitsound_kat_1p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P1]) / "ka.wav", 'hitsound_kat_1p')
logger.info("Loaded wav hit sounds for 1P") logger.info("Loaded wav hit sounds for 1P")
else: else:
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "don.ogg", 'hitsound_don_1p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P1]) / "don.ogg", 'hitsound_don_1p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "ka.ogg", 'hitsound_kat_1p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P1]) / "ka.ogg", 'hitsound_kat_1p')
logger.info("Loaded ogg hit sounds for 1P") logger.info("Loaded ogg hit sounds for 1P")
audio.set_sound_pan('hitsound_don_1p', 0.0) audio.set_sound_pan('hitsound_don_1p', 0.0)
audio.set_sound_pan('hitsound_kat_1p', 0.0) audio.set_sound_pan('hitsound_kat_1p', 0.0)
# Load hitsounds for 2P # Load hitsounds for 2P
if global_data.hit_sound[1] == -1: if global_data.hit_sound[PlayerNum.P2] == -1:
audio.load_sound(Path('none.wav'), 'hitsound_don_2p') audio.load_sound(Path('none.wav'), 'hitsound_don_2p')
audio.load_sound(Path('none.wav'), 'hitsound_kat_2p') audio.load_sound(Path('none.wav'), 'hitsound_kat_2p')
logger.info("Loaded default (none) hit sounds for 2P") logger.info("Loaded default (none) hit sounds for 2P")
elif global_data.hit_sound[1] == 0: elif global_data.hit_sound[PlayerNum.P2] == 0:
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "don_2p.wav", 'hitsound_don_2p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P2]) / "don_2p.wav", 'hitsound_don_2p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "ka_2p.wav", 'hitsound_kat_2p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P2]) / "ka_2p.wav", 'hitsound_kat_2p')
logger.info("Loaded wav hit sounds for 2P") logger.info("Loaded wav hit sounds for 2P")
else: else:
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "don.ogg", 'hitsound_don_2p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P2]) / "don.ogg", 'hitsound_don_2p')
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "ka.ogg", 'hitsound_kat_2p') audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[PlayerNum.P2]) / "ka.ogg", 'hitsound_kat_2p')
logger.info("Loaded ogg hit sounds for 2P") logger.info("Loaded ogg hit sounds for 2P")
audio.set_sound_pan('hitsound_don_2p', 1.0) audio.set_sound_pan('hitsound_don_2p', 1.0)
audio.set_sound_pan('hitsound_kat_2p', 1.0) audio.set_sound_pan('hitsound_kat_2p', 1.0)
@@ -60,7 +61,7 @@ class TwoPlayerGameScreen(GameScreen):
if ray.is_key_pressed(ray.KeyboardKey.KEY_F1): if ray.is_key_pressed(ray.KeyboardKey.KEY_F1):
if self.song_music is not None: if self.song_music is not None:
audio.stop_music_stream(self.song_music) audio.stop_music_stream(self.song_music)
self.init_tja(global_data.session_data[global_data.player_num-1].selected_song) self.init_tja(global_data.session_data[global_data.player_num].selected_song)
audio.play_sound('restart', 'sound') audio.play_sound('restart', 'sound')
self.song_started = False self.song_started = False
logger.info("F1 pressed: song restarted") logger.info("F1 pressed: song restarted")
@@ -79,25 +80,25 @@ class TwoPlayerGameScreen(GameScreen):
self.movie.set_volume(0.0) self.movie.set_volume(0.0)
else: else:
self.movie = None self.movie = None
global_data.session_data[0].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en']) global_data.session_data[PlayerNum.P1].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None: if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None:
self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song') self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song')
tja_copy = copy.deepcopy(self.tja) tja_copy = copy.deepcopy(self.tja)
self.player_1 = Player(self.tja, 1, global_data.session_data[0].selected_difficulty, False, global_data.modifiers[0]) self.player_1 = Player(self.tja, PlayerNum.P1, global_data.session_data[PlayerNum.P1].selected_difficulty, False, global_data.modifiers[PlayerNum.P1])
self.player_2 = Player(tja_copy, 2, global_data.session_data[1].selected_difficulty, True, global_data.modifiers[1]) self.player_2 = Player(tja_copy, PlayerNum.P2, global_data.session_data[PlayerNum.P2].selected_difficulty, True, global_data.modifiers[PlayerNum.P2])
self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000) self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000)
logger.info(f"TJA initialized for two-player song: {song}") logger.info(f"TJA initialized for two-player song: {song}")
def spawn_ending_anims(self): def spawn_ending_anims(self):
if global_data.session_data[0].result_data.bad == 0: if global_data.session_data[PlayerNum.P1].result_data.bad == 0:
self.player_1.ending_anim = FCAnimation(self.player_1.is_2p) self.player_1.ending_anim = FCAnimation(self.player_1.is_2p)
elif self.player_1.gauge.is_clear: elif self.player_1.gauge.is_clear:
self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p) self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p)
elif not self.player_1.gauge.is_clear: elif not self.player_1.gauge.is_clear:
self.player_1.ending_anim = FailAnimation(self.player_1.is_2p) self.player_1.ending_anim = FailAnimation(self.player_1.is_2p)
if global_data.session_data[1].result_data.bad == 0: if global_data.session_data[PlayerNum.P2].result_data.bad == 0:
self.player_2.ending_anim = FCAnimation(self.player_2.is_2p) self.player_2.ending_anim = FCAnimation(self.player_2.is_2p)
elif self.player_2.gauge.is_clear: elif self.player_2.gauge.is_clear:
self.player_2.ending_anim = ClearAnimation(self.player_2.is_2p) self.player_2.ending_anim = ClearAnimation(self.player_2.is_2p)
@@ -122,10 +123,10 @@ class TwoPlayerGameScreen(GameScreen):
if self.result_transition.is_finished and not audio.is_sound_playing('result_transition'): if self.result_transition.is_finished and not audio.is_sound_playing('result_transition'):
return self.on_screen_end('RESULT_2P') return self.on_screen_end('RESULT_2P')
elif self.current_ms >= self.player_1.end_time: elif self.current_ms >= self.player_1.end_time:
session_data = global_data.session_data[0] session_data = global_data.session_data[PlayerNum.P1]
session_data.result_data.score, session_data.result_data.good, session_data.result_data.ok, session_data.result_data.bad, session_data.result_data.max_combo, session_data.result_data.total_drumroll = self.player_1.get_result_score() session_data.result_data.score, session_data.result_data.good, session_data.result_data.ok, session_data.result_data.bad, session_data.result_data.max_combo, session_data.result_data.total_drumroll = self.player_1.get_result_score()
session_data.result_data.gauge_length = int(self.player_1.gauge.gauge_length) session_data.result_data.gauge_length = int(self.player_1.gauge.gauge_length)
session_data = global_data.session_data[1] session_data = global_data.session_data[PlayerNum.P2]
session_data.result_data.score, session_data.result_data.good, session_data.result_data.ok, session_data.result_data.bad, session_data.result_data.max_combo, session_data.result_data.total_drumroll = self.player_2.get_result_score() session_data.result_data.score, session_data.result_data.good, session_data.result_data.ok, session_data.result_data.bad, session_data.result_data.max_combo, session_data.result_data.total_drumroll = self.player_2.get_result_score()
session_data.result_data.gauge_length = int(self.player_2.gauge.gauge_length) session_data.result_data.gauge_length = int(self.player_2.gauge.gauge_length)
if self.end_ms != 0: if self.end_ms != 0:

View File

@@ -1,4 +1,5 @@
import logging import logging
from libs.global_data import PlayerNum
from libs.utils import get_current_ms from libs.utils import get_current_ms
from scenes.result import Background, FadeIn, ResultPlayer, ResultScreen from scenes.result import Background, FadeIn, ResultPlayer, ResultScreen
@@ -7,10 +8,10 @@ logger = logging.getLogger(__name__)
class TwoPlayerResultScreen(ResultScreen): class TwoPlayerResultScreen(ResultScreen):
def on_screen_start(self): def on_screen_start(self):
super().on_screen_start() super().on_screen_start()
self.background = Background('3', 1280) self.background = Background(PlayerNum.TWO_PLAYER, 1280)
self.fade_in = FadeIn('3') self.fade_in = FadeIn(PlayerNum.TWO_PLAYER)
self.player_1 = ResultPlayer('1', True, False) self.player_1 = ResultPlayer(PlayerNum.P1, True, False)
self.player_2 = ResultPlayer('2', True, True) self.player_2 = ResultPlayer(PlayerNum.P2, True, True)
def update(self): def update(self):
super(ResultScreen, self).update() super(ResultScreen, self).update()

View File

@@ -1,5 +1,6 @@
import logging import logging
from libs.file_navigator import SongFile from libs.file_navigator import SongFile
from libs.global_data import PlayerNum
from libs.transition import Transition from libs.transition import Transition
from scenes.song_select import DiffSortSelect, SongSelectPlayer, SongSelectScreen, State from scenes.song_select import DiffSortSelect, SongSelectPlayer, SongSelectScreen, State
from libs.utils import get_current_ms, global_data from libs.utils import get_current_ms, global_data
@@ -10,13 +11,13 @@ logger = logging.getLogger(__name__)
class TwoPlayerSongSelectScreen(SongSelectScreen): class TwoPlayerSongSelectScreen(SongSelectScreen):
def on_screen_start(self): def on_screen_start(self):
super().on_screen_start() super().on_screen_start()
self.player_1 = SongSelectPlayer('1', self.text_fade_in) self.player_1 = SongSelectPlayer(PlayerNum.P1, self.text_fade_in)
self.player_2 = SongSelectPlayer('2', self.text_fade_in) self.player_2 = SongSelectPlayer(PlayerNum.P2, self.text_fade_in)
def finalize_song(self): def finalize_song(self):
global_data.session_data[0].selected_song = self.navigator.get_current_item().path global_data.session_data[PlayerNum.P1].selected_song = self.navigator.get_current_item().path
global_data.session_data[0].genre_index = self.navigator.get_current_item().box.name_texture_index global_data.session_data[PlayerNum.P1].genre_index = self.navigator.get_current_item().box.name_texture_index
logger.info(f"Finalized song selection: {global_data.session_data[0].selected_song}") logger.info(f"Finalized song selection: {global_data.session_data[PlayerNum.P1].selected_song}")
def handle_input(self): def handle_input(self):
if self.player_1.is_ready: if self.player_1.is_ready:
@@ -139,12 +140,12 @@ class TwoPlayerSongSelectScreen(SongSelectScreen):
audio.play_sound('don', 'sound') audio.play_sound('don', 'sound')
audio.play_sound(f'voice_start_song_{global_data.player_num}p', 'voice') audio.play_sound(f'voice_start_song_{global_data.player_num}p', 'voice')
if player_selected == 1: if player_selected == 1:
global_data.session_data[0].selected_difficulty = self.player_1.selected_difficulty global_data.session_data[PlayerNum.P1].selected_difficulty = self.player_1.selected_difficulty
self.player_1.selected_diff_highlight_fade.start() self.player_1.selected_diff_highlight_fade.start()
self.player_1.selected_diff_text_resize.start() self.player_1.selected_diff_text_resize.start()
self.player_1.selected_diff_text_fadein.start() self.player_1.selected_diff_text_fadein.start()
elif player_selected == 2: elif player_selected == 2:
global_data.session_data[1].selected_difficulty = self.player_2.selected_difficulty global_data.session_data[PlayerNum.P2].selected_difficulty = self.player_2.selected_difficulty
self.player_2.selected_diff_highlight_fade.start() self.player_2.selected_diff_highlight_fade.start()
self.player_2.selected_diff_text_resize.start() self.player_2.selected_diff_text_resize.start()
self.player_2.selected_diff_text_fadein.start() self.player_2.selected_diff_text_fadein.start()