|
|
|
|
@@ -72,11 +72,15 @@ import org.newdawn.slick.Input;
|
|
|
|
|
import org.newdawn.slick.SlickException;
|
|
|
|
|
import org.newdawn.slick.SpriteSheet;
|
|
|
|
|
import org.newdawn.slick.gui.TextField;
|
|
|
|
|
import org.newdawn.slick.state.BasicGameState;
|
|
|
|
|
import org.newdawn.slick.state.StateBasedGame;
|
|
|
|
|
import org.newdawn.slick.state.transition.EasedFadeOutTransition;
|
|
|
|
|
import org.newdawn.slick.state.transition.EmptyTransition;
|
|
|
|
|
import org.newdawn.slick.state.transition.FadeInTransition;
|
|
|
|
|
import yugecin.opsudance.core.DisplayContainer;
|
|
|
|
|
import yugecin.opsudance.core.events.EventListener;
|
|
|
|
|
import yugecin.opsudance.core.inject.InstanceContainer;
|
|
|
|
|
import yugecin.opsudance.core.state.BaseOpsuState;
|
|
|
|
|
import yugecin.opsudance.events.ResolutionChangedEvent;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* "Song Selection" state.
|
|
|
|
|
@@ -84,7 +88,10 @@ import org.newdawn.slick.state.transition.FadeInTransition;
|
|
|
|
|
* Players are able to select a beatmap to play, view previous scores, choose game mods,
|
|
|
|
|
* manage beatmaps, or change game options from this state.
|
|
|
|
|
*/
|
|
|
|
|
public class SongMenu extends BasicGameState {
|
|
|
|
|
public class SongMenu extends BaseOpsuState {
|
|
|
|
|
|
|
|
|
|
private final InstanceContainer instanceContainer;
|
|
|
|
|
|
|
|
|
|
/** The max number of song buttons to be shown on each screen. */
|
|
|
|
|
public static final int MAX_SONG_BUTTONS = 6;
|
|
|
|
|
|
|
|
|
|
@@ -169,7 +176,8 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
private MenuButton selectModsButton, selectRandomButton, selectMapOptionsButton, selectOptionsButton;
|
|
|
|
|
|
|
|
|
|
/** The search textfield. */
|
|
|
|
|
private TextField search;
|
|
|
|
|
//private TextField search;
|
|
|
|
|
// TODO d recreate textfield
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Delay timer, in milliseconds, before running another search.
|
|
|
|
|
@@ -321,47 +329,39 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
private boolean isScrollingToFocusNode = false;
|
|
|
|
|
|
|
|
|
|
/** Sort order dropdown menu. */
|
|
|
|
|
private DropdownMenu<BeatmapSortOrder> sortMenu;
|
|
|
|
|
// TODO: d remake dropdownmenu
|
|
|
|
|
//private DropdownMenu<BeatmapSortOrder> sortMenu;
|
|
|
|
|
|
|
|
|
|
// game-related variables
|
|
|
|
|
private GameContainer container;
|
|
|
|
|
private StateBasedGame game;
|
|
|
|
|
private Input input;
|
|
|
|
|
private final int state;
|
|
|
|
|
|
|
|
|
|
public SongMenu(int state) {
|
|
|
|
|
this.state = state;
|
|
|
|
|
public SongMenu(final DisplayContainer displayContainer, InstanceContainer instanceContainer) {
|
|
|
|
|
super(displayContainer);
|
|
|
|
|
this.instanceContainer = instanceContainer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void init(GameContainer container, StateBasedGame game)
|
|
|
|
|
throws SlickException {
|
|
|
|
|
this.container = container;
|
|
|
|
|
this.game = game;
|
|
|
|
|
this.input = container.getInput();
|
|
|
|
|
|
|
|
|
|
int width = container.getWidth();
|
|
|
|
|
int height = container.getHeight();
|
|
|
|
|
public void revalidate() {
|
|
|
|
|
super.revalidate();
|
|
|
|
|
|
|
|
|
|
// header/footer coordinates
|
|
|
|
|
headerY = height * 0.0075f + GameImage.MENU_MUSICNOTE.getImage().getHeight() +
|
|
|
|
|
headerY = displayContainer.height * 0.0075f + GameImage.MENU_MUSICNOTE.getImage().getHeight() +
|
|
|
|
|
Fonts.BOLD.getLineHeight() + Fonts.DEFAULT.getLineHeight() +
|
|
|
|
|
Fonts.SMALL.getLineHeight();
|
|
|
|
|
footerY = height - GameImage.SELECTION_MODS.getImage().getHeight();
|
|
|
|
|
footerY = displayContainer.height - GameImage.SELECTION_MODS.getImage().getHeight();
|
|
|
|
|
|
|
|
|
|
// footer logo coordinates
|
|
|
|
|
float footerHeight = height - footerY;
|
|
|
|
|
float footerHeight = displayContainer.height - footerY;
|
|
|
|
|
footerLogoSize = footerHeight * 3.25f;
|
|
|
|
|
Image logo = GameImage.MENU_LOGO.getImage();
|
|
|
|
|
logo = logo.getScaledCopy(footerLogoSize / logo.getWidth());
|
|
|
|
|
footerLogoButton = new MenuButton(logo, width - footerHeight * 0.8f, height - footerHeight * 0.65f);
|
|
|
|
|
footerLogoButton = new MenuButton(logo, displayContainer.width - footerHeight * 0.8f, displayContainer.height - footerHeight * 0.65f);
|
|
|
|
|
footerLogoButton.setHoverAnimationDuration(1);
|
|
|
|
|
footerLogoButton.setHoverExpand(1.2f);
|
|
|
|
|
|
|
|
|
|
// initialize sorts
|
|
|
|
|
int sortWidth = (int) (width * 0.12f);
|
|
|
|
|
// TODO d reenable dropdown
|
|
|
|
|
/*
|
|
|
|
|
int sortWidth = (int) (displayContainer.width * 0.12f);
|
|
|
|
|
sortMenu = new DropdownMenu<BeatmapSortOrder>(container, BeatmapSortOrder.values(),
|
|
|
|
|
width * 0.87f, headerY - GameImage.MENU_TAB.getImage().getHeight() * 2.25f, sortWidth) {
|
|
|
|
|
displayContainer.width * 0.87f, headerY - GameImage.MENU_TAB.getImage().getHeight() * 2.25f, sortWidth) {
|
|
|
|
|
@Override
|
|
|
|
|
public void itemSelected(int index, BeatmapSortOrder item) {
|
|
|
|
|
BeatmapSortOrder.set(item);
|
|
|
|
|
@@ -386,36 +386,40 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
sortMenu.setBackgroundColor(Colors.BLACK_BG_HOVER);
|
|
|
|
|
sortMenu.setBorderColor(Colors.BLUE_DIVIDER);
|
|
|
|
|
sortMenu.setChevronRightColor(Color.white);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// initialize group tabs
|
|
|
|
|
for (BeatmapGroup group : BeatmapGroup.values())
|
|
|
|
|
group.init(width, headerY - DIVIDER_LINE_WIDTH / 2);
|
|
|
|
|
group.init(displayContainer.width, headerY - DIVIDER_LINE_WIDTH / 2);
|
|
|
|
|
|
|
|
|
|
// initialize score data buttons
|
|
|
|
|
ScoreData.init(width, headerY + height * 0.01f);
|
|
|
|
|
ScoreData.init(displayContainer.width, headerY + displayContainer.height * 0.01f);
|
|
|
|
|
|
|
|
|
|
// song button background & graphics context
|
|
|
|
|
Image menuBackground = GameImage.MENU_BUTTON_BG.getImage();
|
|
|
|
|
|
|
|
|
|
// song button coordinates
|
|
|
|
|
buttonX = width * 0.6f;
|
|
|
|
|
buttonX = displayContainer.width * 0.6f;
|
|
|
|
|
//buttonY = headerY;
|
|
|
|
|
buttonWidth = menuBackground.getWidth();
|
|
|
|
|
buttonHeight = menuBackground.getHeight();
|
|
|
|
|
buttonOffset = (footerY - headerY - DIVIDER_LINE_WIDTH) / MAX_SONG_BUTTONS;
|
|
|
|
|
|
|
|
|
|
// search
|
|
|
|
|
int textFieldX = (int) (width * 0.7125f + Fonts.BOLD.getWidth("Search: "));
|
|
|
|
|
// TODO d reenable search box
|
|
|
|
|
/*
|
|
|
|
|
int textFieldX = (int) (displayContainer.width * 0.7125f + Fonts.BOLD.getWidth("Search: "));
|
|
|
|
|
int textFieldY = (int) (headerY + Fonts.BOLD.getLineHeight() / 2);
|
|
|
|
|
search = new TextField(
|
|
|
|
|
container, Fonts.BOLD, textFieldX, textFieldY,
|
|
|
|
|
(int) (width * 0.99f) - textFieldX, Fonts.BOLD.getLineHeight()
|
|
|
|
|
(int) (displayContainer.width * 0.99f) - textFieldX, Fonts.BOLD.getLineHeight()
|
|
|
|
|
);
|
|
|
|
|
search.setBackgroundColor(Color.transparent);
|
|
|
|
|
search.setBorderColor(Color.transparent);
|
|
|
|
|
search.setTextColor(Color.white);
|
|
|
|
|
search.setConsumeEvents(false);
|
|
|
|
|
search.setMaxLength(60);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// selection buttons
|
|
|
|
|
Image selectionMods = GameImage.SELECTION_MODS.getImage();
|
|
|
|
|
@@ -427,8 +431,8 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
if (selectButtonsWidth < 20) {
|
|
|
|
|
selectButtonsWidth = 100;
|
|
|
|
|
}
|
|
|
|
|
float selectX = width * 0.183f + selectButtonsWidth / 2f;
|
|
|
|
|
float selectY = height - selectButtonsHeight / 2f;
|
|
|
|
|
float selectX = displayContainer.width * 0.183f + selectButtonsWidth / 2f;
|
|
|
|
|
float selectY = displayContainer.height - selectButtonsHeight / 2f;
|
|
|
|
|
float selectOffset = selectButtonsWidth * 1.05f;
|
|
|
|
|
selectModsButton = new MenuButton(GameImage.SELECTION_MODS_OVERLAY.getImage(),
|
|
|
|
|
selectX, selectY);
|
|
|
|
|
@@ -449,33 +453,37 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
loader = new Animation(spr, 50);
|
|
|
|
|
|
|
|
|
|
// beatmap watch service listener
|
|
|
|
|
final StateBasedGame game_ = game;
|
|
|
|
|
BeatmapWatchService.addListener(new BeatmapWatchServiceListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void eventReceived(Kind<?> kind, Path child) {
|
|
|
|
|
if (!songFolderChanged && kind != StandardWatchEventKinds.ENTRY_MODIFY) {
|
|
|
|
|
songFolderChanged = true;
|
|
|
|
|
if (game_.getCurrentStateID() == Opsu.STATE_SONGMENU)
|
|
|
|
|
if (displayContainer.isInState(SongMenu.class)) {
|
|
|
|
|
UI.sendBarNotification("Changes in Songs folder detected. Hit F5 to refresh.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// star stream
|
|
|
|
|
starStream = new StarStream(width, (height - GameImage.STAR.getImage().getHeight()) / 2, -width, 0, MAX_STREAM_STARS);
|
|
|
|
|
starStream.setPositionSpread(height / 20f);
|
|
|
|
|
starStream = new StarStream(displayContainer.width, (displayContainer.height - GameImage.STAR.getImage().getHeight()) / 2, -displayContainer.width, 0, MAX_STREAM_STARS);
|
|
|
|
|
starStream.setPositionSpread(displayContainer.height / 20f);
|
|
|
|
|
starStream.setDirectionSpread(10f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void render(GameContainer container, StateBasedGame game, Graphics g)
|
|
|
|
|
throws SlickException {
|
|
|
|
|
public void render(Graphics g) {
|
|
|
|
|
super.render(g);
|
|
|
|
|
|
|
|
|
|
g.setBackground(Color.black);
|
|
|
|
|
|
|
|
|
|
int width = container.getWidth();
|
|
|
|
|
int height = container.getHeight();
|
|
|
|
|
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
|
|
|
|
boolean inDropdownMenu = sortMenu.contains(mouseX, mouseY);
|
|
|
|
|
int width = displayContainer.width;
|
|
|
|
|
int height = displayContainer.height;
|
|
|
|
|
int mouseX = displayContainer.mouseX;
|
|
|
|
|
int mouseY = displayContainer.mouseY;
|
|
|
|
|
|
|
|
|
|
// TODO d
|
|
|
|
|
//boolean inDropdownMenu = sortMenu.contains(mouseX, mouseY);
|
|
|
|
|
|
|
|
|
|
// background
|
|
|
|
|
if (focusNode != null) {
|
|
|
|
|
@@ -547,8 +555,11 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
g.clearClip();
|
|
|
|
|
|
|
|
|
|
// scroll bar
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
if (focusScores.length > MAX_SCORE_BUTTONS && ScoreData.areaContains(mouseX, mouseY) && !inDropdownMenu)
|
|
|
|
|
ScoreData.drawScrollbar(g, startScorePos.getPosition(), focusScores.length * ScoreData.getButtonOffset());
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// top/bottom bars
|
|
|
|
|
@@ -565,6 +576,8 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
Float position = MusicController.getBeatProgress();
|
|
|
|
|
if (position == null) // default to 60bpm
|
|
|
|
|
position = System.currentTimeMillis() % 1000 / 1000f;
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
if (footerLogoButton.contains(mouseX, mouseY, 0.25f) && !inDropdownMenu) {
|
|
|
|
|
// hovering over logo: stop pulsing
|
|
|
|
|
footerLogoButton.draw();
|
|
|
|
|
@@ -578,6 +591,7 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
ghostLogo.drawCentered(footerLogoButton.getX(), footerLogoButton.getY(), Colors.GHOST_LOGO);
|
|
|
|
|
Colors.GHOST_LOGO.a = oldGhostAlpha;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// header
|
|
|
|
|
if (focusNode != null) {
|
|
|
|
|
@@ -658,6 +672,8 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
// group tabs
|
|
|
|
|
BeatmapGroup currentGroup = BeatmapGroup.current();
|
|
|
|
|
BeatmapGroup hoverGroup = null;
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
if (!inDropdownMenu) {
|
|
|
|
|
for (BeatmapGroup group : BeatmapGroup.values()) {
|
|
|
|
|
if (group.contains(mouseX, mouseY)) {
|
|
|
|
|
@@ -666,6 +682,7 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
for (BeatmapGroup group : BeatmapGroup.VALUES_REVERSED) {
|
|
|
|
|
if (group != currentGroup)
|
|
|
|
|
group.draw(false, group == hoverGroup);
|
|
|
|
|
@@ -673,6 +690,8 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
currentGroup.draw(true, false);
|
|
|
|
|
|
|
|
|
|
// search
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
boolean searchEmpty = search.getText().isEmpty();
|
|
|
|
|
int searchX = search.getX(), searchY = search.getY();
|
|
|
|
|
float searchBaseX = width * 0.7f;
|
|
|
|
|
@@ -707,6 +726,7 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
|
|
|
|
|
// sorting options
|
|
|
|
|
sortMenu.render(container, g);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// reloading beatmaps
|
|
|
|
|
if (reloadThread != null) {
|
|
|
|
|
@@ -725,8 +745,10 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void update(GameContainer container, StateBasedGame game, int delta)
|
|
|
|
|
throws SlickException {
|
|
|
|
|
public void preRenderUpdate() {
|
|
|
|
|
super.preRenderUpdate();
|
|
|
|
|
|
|
|
|
|
int delta = displayContainer.delta;
|
|
|
|
|
UI.update(delta);
|
|
|
|
|
if (reloadThread == null)
|
|
|
|
|
MusicController.loopTrackIfEnded(true);
|
|
|
|
|
@@ -742,8 +764,9 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
MusicController.playThemeSong();
|
|
|
|
|
reloadThread = null;
|
|
|
|
|
}
|
|
|
|
|
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
|
|
|
|
boolean inDropdownMenu = sortMenu.contains(mouseX, mouseY);
|
|
|
|
|
int mouseX = displayContainer.mouseX;
|
|
|
|
|
int mouseY = displayContainer.mouseY;
|
|
|
|
|
boolean inDropdownMenu = false; // TODO d sortMenu.contains(mouseX, mouseY);
|
|
|
|
|
UI.getBackButton().hoverUpdate(delta, mouseX, mouseY);
|
|
|
|
|
selectModsButton.hoverUpdate(delta, mouseX, mouseY);
|
|
|
|
|
selectRandomButton.hoverUpdate(delta, mouseX, mouseY);
|
|
|
|
|
@@ -759,8 +782,8 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
if (focusNode != null) {
|
|
|
|
|
MenuState state = focusNode.getBeatmapSet().isFavorite() ?
|
|
|
|
|
MenuState.BEATMAP_FAVORITE : MenuState.BEATMAP;
|
|
|
|
|
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(state, focusNode);
|
|
|
|
|
game.enterState(Opsu.STATE_BUTTONMENU);
|
|
|
|
|
instanceContainer.provide(ButtonMenu.class).setMenuState(state, focusNode);
|
|
|
|
|
// TODO d displayContainer.switchState(ButtonMenu.class);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -782,6 +805,8 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
starStream.update(delta);
|
|
|
|
|
|
|
|
|
|
// search
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
search.setFocus(true);
|
|
|
|
|
searchTimer += delta;
|
|
|
|
|
if (searchTimer >= SEARCH_DELAY && reloadThread == null && beatmapMenuTimer == -1) {
|
|
|
|
|
@@ -827,6 +852,7 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
if (searchTransitionTimer > SEARCH_TRANSITION_TIME)
|
|
|
|
|
searchTransitionTimer = SEARCH_TRANSITION_TIME;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// scores
|
|
|
|
|
if (focusScores != null) {
|
|
|
|
|
@@ -862,9 +888,11 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// tooltips
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
if (sortMenu.baseContains(mouseX, mouseY))
|
|
|
|
|
UI.updateTooltip(delta, "Sort by...", false);
|
|
|
|
|
else if (focusScores != null && ScoreData.areaContains(mouseX, mouseY)) {
|
|
|
|
|
else */if (focusScores != null && ScoreData.areaContains(mouseX, mouseY)) {
|
|
|
|
|
int startScore = (int) (startScorePos.getPosition() / ScoreData.getButtonOffset());
|
|
|
|
|
int offset = (int) (-startScorePos.getPosition() + startScore * ScoreData.getButtonOffset());
|
|
|
|
|
int scoreButtons = Math.min(focusScores.length - startScore, MAX_SCORE_BUTTONS);
|
|
|
|
|
@@ -880,66 +908,58 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int getID() { return state; }
|
|
|
|
|
public boolean mousePressed(int button, int x, int y) {
|
|
|
|
|
if (button == Input.MOUSE_MIDDLE_BUTTON) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void mousePressed(int button, int x, int y) {
|
|
|
|
|
// check mouse button
|
|
|
|
|
if (button == Input.MOUSE_MIDDLE_BUTTON)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (isScrollingToFocusNode)
|
|
|
|
|
return;
|
|
|
|
|
if (isScrollingToFocusNode) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
songScrolling.pressed();
|
|
|
|
|
startScorePos.pressed();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void mouseReleased(int button, int x, int y) {
|
|
|
|
|
// check mouse button
|
|
|
|
|
if (button == Input.MOUSE_MIDDLE_BUTTON)
|
|
|
|
|
return;
|
|
|
|
|
public boolean mouseReleased(int button, int x, int y) {
|
|
|
|
|
if (button == Input.MOUSE_MIDDLE_BUTTON) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isScrollingToFocusNode)
|
|
|
|
|
return;
|
|
|
|
|
if (isScrollingToFocusNode) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
songScrolling.released();
|
|
|
|
|
startScorePos.released();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void mouseClicked(int button, int x, int y, int clickCount) {
|
|
|
|
|
// check mouse button
|
|
|
|
|
if (button == Input.MOUSE_MIDDLE_BUTTON)
|
|
|
|
|
return;
|
|
|
|
|
if (isInputBlocked()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// block input
|
|
|
|
|
if (isInputBlocked())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// back
|
|
|
|
|
if (UI.getBackButton().contains(x, y)) {
|
|
|
|
|
SoundController.playSound(SoundEffect.MENUBACK);
|
|
|
|
|
((MainMenu) game.getState(Opsu.STATE_MAINMENU)).reset();
|
|
|
|
|
game.enterState(Opsu.STATE_MAINMENU, new EasedFadeOutTransition(), new FadeInTransition());
|
|
|
|
|
return;
|
|
|
|
|
instanceContainer.provide(MainMenu.class).reset(); // TODO d why is this needed
|
|
|
|
|
displayContainer.switchState(MainMenu.class);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// selection buttons
|
|
|
|
|
if (selectModsButton.contains(x, y)) {
|
|
|
|
|
this.keyPressed(Input.KEY_F1, '\0');
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
} else if (selectRandomButton.contains(x, y)) {
|
|
|
|
|
this.keyPressed(Input.KEY_F2, '\0');
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
} else if (selectMapOptionsButton.contains(x, y)) {
|
|
|
|
|
this.keyPressed(Input.KEY_F3, '\0');
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
} else if (selectOptionsButton.contains(x, y)) {
|
|
|
|
|
SoundController.playSound(SoundEffect.MENUHIT);
|
|
|
|
|
game.enterState(Opsu.STATE_OPTIONSMENU, new EmptyTransition(), new FadeInTransition());
|
|
|
|
|
return;
|
|
|
|
|
// TODO d displayContainer.switchState(OptionsMenu.class);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// group tabs
|
|
|
|
|
@@ -954,7 +974,7 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
songInfo = null;
|
|
|
|
|
scoreMap = null;
|
|
|
|
|
focusScores = null;
|
|
|
|
|
search.setText("");
|
|
|
|
|
// TODO d search.setText("");
|
|
|
|
|
searchTimer = SEARCH_DELAY;
|
|
|
|
|
searchTransitionTimer = SEARCH_TRANSITION_TIME;
|
|
|
|
|
searchResultString = null;
|
|
|
|
|
@@ -965,17 +985,18 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
if (BeatmapSetList.get().size() < 1 && group.getEmptyMessage() != null)
|
|
|
|
|
UI.sendBarNotification(group.getEmptyMessage());
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (focusNode == null)
|
|
|
|
|
return;
|
|
|
|
|
if (focusNode == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// logo: start game
|
|
|
|
|
if (footerLogoButton.contains(x, y, 0.25f)) {
|
|
|
|
|
startGame();
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// song buttons
|
|
|
|
|
@@ -1014,7 +1035,7 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
if (button == Input.MOUSE_RIGHT_BUTTON)
|
|
|
|
|
beatmapMenuTimer = (node.index == expandedIndex) ? BEATMAP_MENU_DELAY * 4 / 5 : 0;
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// score buttons
|
|
|
|
|
@@ -1027,28 +1048,33 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
SoundController.playSound(SoundEffect.MENUHIT);
|
|
|
|
|
if (button != Input.MOUSE_RIGHT_BUTTON) {
|
|
|
|
|
// view score
|
|
|
|
|
GameData data = new GameData(focusScores[rank], container.getWidth(), container.getHeight());
|
|
|
|
|
((GameRanking) game.getState(Opsu.STATE_GAMERANKING)).setGameData(data);
|
|
|
|
|
game.enterState(Opsu.STATE_GAMERANKING, new EasedFadeOutTransition(), new FadeInTransition());
|
|
|
|
|
instanceContainer.provide(GameRanking.class).setGameData(new GameData(focusScores[rank], displayContainer.width, displayContainer.height));
|
|
|
|
|
// TODO d displayContainer.switchState(GameRanking.class);
|
|
|
|
|
} else {
|
|
|
|
|
// score management
|
|
|
|
|
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(MenuState.SCORE, focusScores[rank]);
|
|
|
|
|
game.enterState(Opsu.STATE_BUTTONMENU);
|
|
|
|
|
instanceContainer.provide(ButtonMenu.class).setMenuState(MenuState.SCORE, focusScores[rank]);
|
|
|
|
|
// TODO d displayContainer.switchState(ButtonMenu.class);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void keyPressed(int key, char c) {
|
|
|
|
|
public boolean keyPressed(int key, char c) {
|
|
|
|
|
// block input
|
|
|
|
|
if ((reloadThread != null && !(key == Input.KEY_ESCAPE || key == Input.KEY_F12)) || beatmapMenuTimer > -1 || isScrollingToFocusNode)
|
|
|
|
|
return;
|
|
|
|
|
if ((reloadThread != null && !(key == Input.KEY_ESCAPE || key == Input.KEY_F12)) || beatmapMenuTimer > -1 || isScrollingToFocusNode) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Input input = displayContainer.input;
|
|
|
|
|
|
|
|
|
|
switch (key) {
|
|
|
|
|
case Input.KEY_ESCAPE:
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
if (reloadThread != null) {
|
|
|
|
|
// beatmap reloading: stop parsing beatmaps by sending interrupt to BeatmapParser
|
|
|
|
|
reloadThread.interrupt();
|
|
|
|
|
@@ -1064,12 +1090,13 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
((MainMenu) game.getState(Opsu.STATE_MAINMENU)).reset();
|
|
|
|
|
game.enterState(Opsu.STATE_MAINMENU, new EasedFadeOutTransition(), new FadeInTransition());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
*/
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_F1:
|
|
|
|
|
SoundController.playSound(SoundEffect.MENUHIT);
|
|
|
|
|
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(MenuState.MODS);
|
|
|
|
|
game.enterState(Opsu.STATE_BUTTONMENU);
|
|
|
|
|
break;
|
|
|
|
|
instanceContainer.provide(ButtonMenu.class).setMenuState(MenuState.MODS);
|
|
|
|
|
// TODO d displayContainer.switchState(ButtonMenu.class);
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_F2:
|
|
|
|
|
if (focusNode == null)
|
|
|
|
|
break;
|
|
|
|
|
@@ -1089,25 +1116,25 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
randomStack.push(new SongNode(BeatmapSetList.get().getBaseNode(focusNode.index), focusNode.beatmapIndex));
|
|
|
|
|
setFocus(BeatmapSetList.get().getRandomNode(), -1, true, true);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_F3:
|
|
|
|
|
if (focusNode == null)
|
|
|
|
|
break;
|
|
|
|
|
SoundController.playSound(SoundEffect.MENUHIT);
|
|
|
|
|
MenuState state = focusNode.getBeatmapSet().isFavorite() ?
|
|
|
|
|
MenuState.BEATMAP_FAVORITE : MenuState.BEATMAP;
|
|
|
|
|
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(state, focusNode);
|
|
|
|
|
game.enterState(Opsu.STATE_BUTTONMENU);
|
|
|
|
|
break;
|
|
|
|
|
instanceContainer.provide(ButtonMenu.class).setMenuState(state, focusNode);
|
|
|
|
|
// TODO d displayContainer.switchState(ButtonMenu.class);
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_F5:
|
|
|
|
|
SoundController.playSound(SoundEffect.MENUHIT);
|
|
|
|
|
if (songFolderChanged)
|
|
|
|
|
reloadBeatmaps(false);
|
|
|
|
|
else {
|
|
|
|
|
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(MenuState.RELOAD);
|
|
|
|
|
game.enterState(Opsu.STATE_BUTTONMENU);
|
|
|
|
|
instanceContainer.provide(ButtonMenu.class).setMenuState(MenuState.RELOAD);
|
|
|
|
|
// TODO d displayContainer.switchState(ButtonMenu.class);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_DELETE:
|
|
|
|
|
if (focusNode == null)
|
|
|
|
|
break;
|
|
|
|
|
@@ -1115,31 +1142,31 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
SoundController.playSound(SoundEffect.MENUHIT);
|
|
|
|
|
MenuState ms = (focusNode.beatmapIndex == -1 || focusNode.getBeatmapSet().size() == 1) ?
|
|
|
|
|
MenuState.BEATMAP_DELETE_CONFIRM : MenuState.BEATMAP_DELETE_SELECT;
|
|
|
|
|
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(ms, focusNode);
|
|
|
|
|
game.enterState(Opsu.STATE_BUTTONMENU);
|
|
|
|
|
instanceContainer.provide(ButtonMenu.class).setMenuState(ms, focusNode);
|
|
|
|
|
// TODO d displayContainer.switchState(ButtonMenu.class);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_F7:
|
|
|
|
|
// TODO d
|
|
|
|
|
//Options.setNextFPS(container);
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_F10:
|
|
|
|
|
Options.toggleMouseDisabled();
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_F12:
|
|
|
|
|
Utils.takeScreenShot();
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_ENTER:
|
|
|
|
|
if (focusNode == null)
|
|
|
|
|
break;
|
|
|
|
|
startGame();
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_DOWN:
|
|
|
|
|
changeIndex(1);
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_UP:
|
|
|
|
|
changeIndex(-1);
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_RIGHT:
|
|
|
|
|
if (focusNode == null)
|
|
|
|
|
break;
|
|
|
|
|
@@ -1155,7 +1182,7 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
hoverIndex = oldHoverIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_LEFT:
|
|
|
|
|
if (focusNode == null)
|
|
|
|
|
break;
|
|
|
|
|
@@ -1171,24 +1198,26 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
hoverIndex = oldHoverIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_NEXT:
|
|
|
|
|
changeIndex(MAX_SONG_BUTTONS);
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_PRIOR:
|
|
|
|
|
changeIndex(-MAX_SONG_BUTTONS);
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
case Input.KEY_O:
|
|
|
|
|
if (input.isKeyDown(Input.KEY_LCONTROL) || input.isKeyDown(Input.KEY_RCONTROL)) {
|
|
|
|
|
game.enterState(Opsu.STATE_OPTIONSMENU, new EmptyTransition(), new FadeInTransition());
|
|
|
|
|
// TODO d displayContainer.switchState(OptionsMenu.class);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
// wait for user to finish typing
|
|
|
|
|
// TODO: accept all characters (current conditions are from TextField class)
|
|
|
|
|
if ((c > 31 && c < 127) || key == Input.KEY_BACK) {
|
|
|
|
|
searchTimer = 0;
|
|
|
|
|
int textLength = search.getText().length();
|
|
|
|
|
// TODO d
|
|
|
|
|
//int textLength = search.getText().length();
|
|
|
|
|
int textLength = 0;
|
|
|
|
|
if (lastSearchTextLength != textLength) {
|
|
|
|
|
if (key == Input.KEY_BACK) {
|
|
|
|
|
if (textLength == 0)
|
|
|
|
|
@@ -1198,10 +1227,13 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
lastSearchTextLength = textLength;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
@Override
|
|
|
|
|
public void mouseDragged(int oldx, int oldy, int newx, int newy) {
|
|
|
|
|
// block input
|
|
|
|
|
@@ -1229,18 +1261,20 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
else
|
|
|
|
|
songScrolling.dragged(-diff * multiplier);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void mouseWheelMoved(int newValue) {
|
|
|
|
|
// change volume
|
|
|
|
|
public boolean mouseWheelMoved(int newValue) {
|
|
|
|
|
Input input = displayContainer.input;
|
|
|
|
|
|
|
|
|
|
if (input.isKeyDown(Input.KEY_LALT) || input.isKeyDown(Input.KEY_RALT)) {
|
|
|
|
|
UI.changeVolume((newValue < 0) ? -1 : 1);
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// block input
|
|
|
|
|
if (isInputBlocked())
|
|
|
|
|
return;
|
|
|
|
|
if (isInputBlocked()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int shift = (newValue < 0) ? 1 : -1;
|
|
|
|
|
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
|
|
|
|
@@ -1252,13 +1286,14 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
// song buttons
|
|
|
|
|
else
|
|
|
|
|
changeIndex(shift);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void enter(GameContainer container, StateBasedGame game)
|
|
|
|
|
throws SlickException {
|
|
|
|
|
public void enter() {
|
|
|
|
|
super.enter();
|
|
|
|
|
|
|
|
|
|
UI.enter();
|
|
|
|
|
Display.setTitle(game.getTitle());
|
|
|
|
|
selectModsButton.resetHover();
|
|
|
|
|
selectRandomButton.resetHover();
|
|
|
|
|
selectMapOptionsButton.resetHover();
|
|
|
|
|
@@ -1276,8 +1311,9 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
songChangeTimer.setTime(songChangeTimer.getDuration());
|
|
|
|
|
musicIconBounceTimer.setTime(musicIconBounceTimer.getDuration());
|
|
|
|
|
starStream.clear();
|
|
|
|
|
sortMenu.activate();
|
|
|
|
|
sortMenu.reset();
|
|
|
|
|
// TODO d
|
|
|
|
|
//sortMenu.activate();
|
|
|
|
|
//sortMenu.reset();
|
|
|
|
|
|
|
|
|
|
// reset song stack
|
|
|
|
|
randomStack = new Stack<SongNode>();
|
|
|
|
|
@@ -1308,7 +1344,7 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
|
|
|
|
|
// reset game data
|
|
|
|
|
if (resetGame) {
|
|
|
|
|
((Game) game.getState(Opsu.STATE_GAME)).resetGameData();
|
|
|
|
|
instanceContainer.provide(Game.class).resetGameData();
|
|
|
|
|
|
|
|
|
|
// destroy extra Clips
|
|
|
|
|
MultiClip.destroyExtraClips();
|
|
|
|
|
@@ -1441,10 +1477,13 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void leave(GameContainer container, StateBasedGame game)
|
|
|
|
|
throws SlickException {
|
|
|
|
|
public void leave() {
|
|
|
|
|
super.leave();
|
|
|
|
|
// TODO d
|
|
|
|
|
/*
|
|
|
|
|
search.setFocus(false);
|
|
|
|
|
sortMenu.deactivate();
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -1569,9 +1608,9 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
|
|
|
|
|
// change the focus node
|
|
|
|
|
if (changeStartNode || (startNode.index == 0 && startNode.beatmapIndex == -1 && startNode.prev == null)) {
|
|
|
|
|
if (startNode == null || game.getCurrentStateID() != Opsu.STATE_SONGMENU)
|
|
|
|
|
if (startNode == null || displayContainer.isInState(SongMenu.class)) {
|
|
|
|
|
songScrolling.setPosition((node.index - 1) * buttonOffset);
|
|
|
|
|
else {
|
|
|
|
|
} else {
|
|
|
|
|
isScrollingToFocusNode = true;
|
|
|
|
|
songScrolling.setSpeedMultiplier(2f);
|
|
|
|
|
songScrolling.released();
|
|
|
|
|
@@ -1704,7 +1743,8 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
songInfo = null;
|
|
|
|
|
hoverOffset.setTime(0);
|
|
|
|
|
hoverIndex = null;
|
|
|
|
|
search.setText("");
|
|
|
|
|
// TODO d
|
|
|
|
|
//search.setText("");
|
|
|
|
|
searchTimer = SEARCH_DELAY;
|
|
|
|
|
searchTransitionTimer = SEARCH_TRANSITION_TIME;
|
|
|
|
|
searchResultString = null;
|
|
|
|
|
@@ -1785,17 +1825,17 @@ public class SongMenu extends BasicGameState {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// turn on "auto" mod if holding "ctrl" key
|
|
|
|
|
if (input.isKeyDown(Input.KEY_RCONTROL) || input.isKeyDown(Input.KEY_LCONTROL)) {
|
|
|
|
|
if (displayContainer.input.isKeyDown(Input.KEY_RCONTROL) || displayContainer.input.isKeyDown(Input.KEY_LCONTROL)) {
|
|
|
|
|
if (!GameMod.AUTO.isActive())
|
|
|
|
|
GameMod.AUTO.toggle(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SoundController.playSound(SoundEffect.MENUHIT);
|
|
|
|
|
MultiClip.destroyExtraClips();
|
|
|
|
|
Game gameState = (Game) game.getState(Opsu.STATE_GAME);
|
|
|
|
|
Game gameState = instanceContainer.provide(Game.class);
|
|
|
|
|
gameState.loadBeatmap(beatmap);
|
|
|
|
|
gameState.setRestart(Game.Restart.NEW);
|
|
|
|
|
gameState.setReplay(null);
|
|
|
|
|
game.enterState(Opsu.STATE_GAME, new EasedFadeOutTransition(), new FadeInTransition());
|
|
|
|
|
// TODO d displayContainer.switchState(Game.class);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|