Continuation of 53c79c5
- created a BeatmapSet class.
Moved the strictly beatmap-related parts of BeatmapSetNode into a new BeatmapSet class. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
250f7acc93
commit
ee5bc4b616
|
@ -80,7 +80,7 @@ public enum SongSort {
|
||||||
private static class TitleOrder implements Comparator<BeatmapSetNode> {
|
private static class TitleOrder implements Comparator<BeatmapSetNode> {
|
||||||
@Override
|
@Override
|
||||||
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
||||||
return v.beatmaps.get(0).title.compareToIgnoreCase(w.beatmaps.get(0).title);
|
return v.getBeatmapSet().get(0).title.compareToIgnoreCase(w.getBeatmapSet().get(0).title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ public enum SongSort {
|
||||||
private static class ArtistOrder implements Comparator<BeatmapSetNode> {
|
private static class ArtistOrder implements Comparator<BeatmapSetNode> {
|
||||||
@Override
|
@Override
|
||||||
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
||||||
return v.beatmaps.get(0).artist.compareToIgnoreCase(w.beatmaps.get(0).artist);
|
return v.getBeatmapSet().get(0).artist.compareToIgnoreCase(w.getBeatmapSet().get(0).artist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public enum SongSort {
|
||||||
private static class CreatorOrder implements Comparator<BeatmapSetNode> {
|
private static class CreatorOrder implements Comparator<BeatmapSetNode> {
|
||||||
@Override
|
@Override
|
||||||
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
||||||
return v.beatmaps.get(0).creator.compareToIgnoreCase(w.beatmaps.get(0).creator);
|
return v.getBeatmapSet().get(0).creator.compareToIgnoreCase(w.getBeatmapSet().get(0).creator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ public enum SongSort {
|
||||||
private static class BPMOrder implements Comparator<BeatmapSetNode> {
|
private static class BPMOrder implements Comparator<BeatmapSetNode> {
|
||||||
@Override
|
@Override
|
||||||
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
||||||
return Integer.compare(v.beatmaps.get(0).bpmMax, w.beatmaps.get(0).bpmMax);
|
return Integer.compare(v.getBeatmapSet().get(0).bpmMax, w.getBeatmapSet().get(0).bpmMax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,11 +122,13 @@ public enum SongSort {
|
||||||
@Override
|
@Override
|
||||||
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
public int compare(BeatmapSetNode v, BeatmapSetNode w) {
|
||||||
int vMax = 0, wMax = 0;
|
int vMax = 0, wMax = 0;
|
||||||
for (Beatmap beatmap : v.beatmaps) {
|
for (int i = 0, size = v.getBeatmapSet().size(); i < size; i++) {
|
||||||
|
Beatmap beatmap = v.getBeatmapSet().get(i);
|
||||||
if (beatmap.endTime > vMax)
|
if (beatmap.endTime > vMax)
|
||||||
vMax = beatmap.endTime;
|
vMax = beatmap.endTime;
|
||||||
}
|
}
|
||||||
for (Beatmap beatmap : w.beatmaps) {
|
for (int i = 0, size = w.getBeatmapSet().size(); i < size; i++) {
|
||||||
|
Beatmap beatmap = w.getBeatmapSet().get(i);
|
||||||
if (beatmap.endTime > wMax)
|
if (beatmap.endTime > wMax)
|
||||||
wMax = beatmap.endTime;
|
wMax = beatmap.endTime;
|
||||||
}
|
}
|
||||||
|
|
178
src/itdelatrisu/opsu/beatmap/BeatmapSet.java
Normal file
178
src/itdelatrisu/opsu/beatmap/BeatmapSet.java
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
/*
|
||||||
|
* opsu! - an open-source osu! client
|
||||||
|
* Copyright (C) 2014, 2015 Jeffrey Han
|
||||||
|
*
|
||||||
|
* opsu! is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* opsu! is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package itdelatrisu.opsu.beatmap;
|
||||||
|
|
||||||
|
import itdelatrisu.opsu.GameMod;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data type containing all beatmaps in a beatmap set.
|
||||||
|
*/
|
||||||
|
public class BeatmapSet {
|
||||||
|
/** List of associated beatmaps. */
|
||||||
|
private ArrayList<Beatmap> beatmaps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param beatmaps the beatmaps in this set
|
||||||
|
*/
|
||||||
|
public BeatmapSet(ArrayList<Beatmap> beatmaps) {
|
||||||
|
this.beatmaps = beatmaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of elements.
|
||||||
|
*/
|
||||||
|
public int size() { return beatmaps.size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the beatmap at the given index.
|
||||||
|
* @param index the beatmap index
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
*/
|
||||||
|
public Beatmap get(int index) { return beatmaps.get(index); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the beatmap at the given index.
|
||||||
|
* @param index the beatmap index
|
||||||
|
* @return the removed beatmap
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
*/
|
||||||
|
public Beatmap remove(int index) { return beatmaps.remove(index); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of strings containing beatmap information.
|
||||||
|
* <ul>
|
||||||
|
* <li>0: {Artist} - {Title} [{Version}]
|
||||||
|
* <li>1: Mapped by {Creator}
|
||||||
|
* <li>2: Length: {} BPM: {} Objects: {}
|
||||||
|
* <li>3: Circles: {} Sliders: {} Spinners: {}
|
||||||
|
* <li>4: CS:{} HP:{} AR:{} OD:{}
|
||||||
|
* </ul>
|
||||||
|
* @param index the beatmap index
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
*/
|
||||||
|
public String[] getInfo(int index) {
|
||||||
|
Beatmap beatmap = beatmaps.get(index);
|
||||||
|
float speedModifier = GameMod.getSpeedMultiplier();
|
||||||
|
long endTime = (long) (beatmap.endTime / speedModifier);
|
||||||
|
int bpmMin = (int) (beatmap.bpmMin * speedModifier);
|
||||||
|
int bpmMax = (int) (beatmap.bpmMax * speedModifier);
|
||||||
|
float multiplier = GameMod.getDifficultyMultiplier();
|
||||||
|
String[] info = new String[5];
|
||||||
|
info[0] = beatmap.toString();
|
||||||
|
info[1] = String.format("Mapped by %s", beatmap.creator);
|
||||||
|
info[2] = String.format("Length: %d:%02d BPM: %s Objects: %d",
|
||||||
|
TimeUnit.MILLISECONDS.toMinutes(endTime),
|
||||||
|
TimeUnit.MILLISECONDS.toSeconds(endTime) -
|
||||||
|
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(endTime)),
|
||||||
|
(bpmMax <= 0) ? "--" : ((bpmMin == bpmMax) ? bpmMin : String.format("%d-%d", bpmMin, bpmMax)),
|
||||||
|
(beatmap.hitObjectCircle + beatmap.hitObjectSlider + beatmap.hitObjectSpinner));
|
||||||
|
info[3] = String.format("Circles: %d Sliders: %d Spinners: %d",
|
||||||
|
beatmap.hitObjectCircle, beatmap.hitObjectSlider, beatmap.hitObjectSpinner);
|
||||||
|
info[4] = String.format("CS:%.1f HP:%.1f AR:%.1f OD:%.1f",
|
||||||
|
Math.min(beatmap.circleSize * multiplier, 10f),
|
||||||
|
Math.min(beatmap.HPDrainRate * multiplier, 10f),
|
||||||
|
Math.min(beatmap.approachRate * multiplier, 10f),
|
||||||
|
Math.min(beatmap.overallDifficulty * multiplier, 10f));
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a formatted string for the beatmap set:
|
||||||
|
* "Artist - Title"
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
Beatmap beatmap = beatmaps.get(0);
|
||||||
|
return String.format("%s - %s", beatmap.getArtist(), beatmap.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the beatmap set matches a given search query.
|
||||||
|
* @param query the search term
|
||||||
|
* @return true if title, artist, creator, source, version, or tag matches query
|
||||||
|
*/
|
||||||
|
public boolean matches(String query) {
|
||||||
|
// search: title, artist, creator, source, version, tags (first beatmap)
|
||||||
|
Beatmap beatmap = beatmaps.get(0);
|
||||||
|
if (beatmap.title.toLowerCase().contains(query) ||
|
||||||
|
beatmap.titleUnicode.toLowerCase().contains(query) ||
|
||||||
|
beatmap.artist.toLowerCase().contains(query) ||
|
||||||
|
beatmap.artistUnicode.toLowerCase().contains(query) ||
|
||||||
|
beatmap.creator.toLowerCase().contains(query) ||
|
||||||
|
beatmap.source.toLowerCase().contains(query) ||
|
||||||
|
beatmap.version.toLowerCase().contains(query) ||
|
||||||
|
beatmap.tags.contains(query))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// search: version, tags (remaining beatmaps)
|
||||||
|
for (int i = 1; i < beatmaps.size(); i++) {
|
||||||
|
beatmap = beatmaps.get(i);
|
||||||
|
if (beatmap.version.toLowerCase().contains(query) ||
|
||||||
|
beatmap.tags.contains(query))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the beatmap set matches a given condition.
|
||||||
|
* @param type the condition type (ar, cs, od, hp, bpm, length)
|
||||||
|
* @param operator the operator (=/==, >, >=, <, <=)
|
||||||
|
* @param value the value
|
||||||
|
* @return true if the condition is met
|
||||||
|
*/
|
||||||
|
public boolean matches(String type, String operator, float value) {
|
||||||
|
for (Beatmap beatmap : beatmaps) {
|
||||||
|
// get value
|
||||||
|
float v;
|
||||||
|
switch (type) {
|
||||||
|
case "ar": v = beatmap.approachRate; break;
|
||||||
|
case "cs": v = beatmap.circleSize; break;
|
||||||
|
case "od": v = beatmap.overallDifficulty; break;
|
||||||
|
case "hp": v = beatmap.HPDrainRate; break;
|
||||||
|
case "bpm": v = beatmap.bpmMax; break;
|
||||||
|
case "length": v = beatmap.endTime / 1000; break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get operator
|
||||||
|
boolean met;
|
||||||
|
switch (operator) {
|
||||||
|
case "=":
|
||||||
|
case "==": met = (v == value); break;
|
||||||
|
case ">": met = (v > value); break;
|
||||||
|
case ">=": met = (v >= value); break;
|
||||||
|
case "<": met = (v < value); break;
|
||||||
|
case "<=": met = (v <= value); break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (met)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -109,7 +109,8 @@ public class BeatmapSetList {
|
||||||
* @return the new BeatmapSetNode
|
* @return the new BeatmapSetNode
|
||||||
*/
|
*/
|
||||||
public BeatmapSetNode addSongGroup(ArrayList<Beatmap> beatmaps) {
|
public BeatmapSetNode addSongGroup(ArrayList<Beatmap> beatmaps) {
|
||||||
BeatmapSetNode node = new BeatmapSetNode(beatmaps);
|
BeatmapSet beatmapSet = new BeatmapSet(beatmaps);
|
||||||
|
BeatmapSetNode node = new BeatmapSetNode(beatmapSet);
|
||||||
parsedNodes.add(node);
|
parsedNodes.add(node);
|
||||||
mapCount += beatmaps.size();
|
mapCount += beatmaps.size();
|
||||||
|
|
||||||
|
@ -152,10 +153,10 @@ public class BeatmapSetList {
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove all node references
|
// remove all node references
|
||||||
Beatmap beatmap = node.beatmaps.get(0);
|
Beatmap beatmap = node.getBeatmapSet().get(0);
|
||||||
nodes.remove(index);
|
nodes.remove(index);
|
||||||
parsedNodes.remove(eCur);
|
parsedNodes.remove(eCur);
|
||||||
mapCount -= node.beatmaps.size();
|
mapCount -= node.getBeatmapSet().size();
|
||||||
if (beatmap.beatmapSetID > 0)
|
if (beatmap.beatmapSetID > 0)
|
||||||
MSIDdb.remove(beatmap.beatmapSetID);
|
MSIDdb.remove(beatmap.beatmapSetID);
|
||||||
|
|
||||||
|
@ -168,7 +169,7 @@ public class BeatmapSetList {
|
||||||
} else if (expandedIndex > index) {
|
} else if (expandedIndex > index) {
|
||||||
expandedIndex--;
|
expandedIndex--;
|
||||||
BeatmapSetNode expandedNode = expandedStartNode;
|
BeatmapSetNode expandedNode = expandedStartNode;
|
||||||
for (int i = 0, size = expandedNode.beatmaps.size();
|
for (int i = 0, size = expandedNode.getBeatmapSet().size();
|
||||||
i < size && expandedNode != null;
|
i < size && expandedNode != null;
|
||||||
i++, expandedNode = expandedNode.next)
|
i++, expandedNode = expandedNode.next)
|
||||||
expandedNode.index = expandedIndex;
|
expandedNode.index = expandedIndex;
|
||||||
|
@ -210,8 +211,8 @@ public class BeatmapSetList {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// last song in group?
|
// last song in group?
|
||||||
int size = node.beatmaps.size();
|
int size = node.getBeatmapSet().size();
|
||||||
if (node.beatmaps.size() == 1)
|
if (size == 1)
|
||||||
return deleteSongGroup(node);
|
return deleteSongGroup(node);
|
||||||
|
|
||||||
// reset indices
|
// reset indices
|
||||||
|
@ -222,7 +223,7 @@ public class BeatmapSetList {
|
||||||
expandedNode.beatmapIndex--;
|
expandedNode.beatmapIndex--;
|
||||||
|
|
||||||
// remove song reference
|
// remove song reference
|
||||||
Beatmap beatmap = node.beatmaps.remove(node.beatmapIndex);
|
Beatmap beatmap = node.getBeatmapSet().remove(node.beatmapIndex);
|
||||||
mapCount--;
|
mapCount--;
|
||||||
|
|
||||||
// re-link nodes
|
// re-link nodes
|
||||||
|
@ -314,11 +315,11 @@ public class BeatmapSetList {
|
||||||
expandedStartNode = expandedEndNode = null;
|
expandedStartNode = expandedEndNode = null;
|
||||||
|
|
||||||
// create new nodes
|
// create new nodes
|
||||||
ArrayList<Beatmap> beatmaps = node.beatmaps;
|
BeatmapSet beatmapSet = node.getBeatmapSet();
|
||||||
BeatmapSetNode prevNode = node.prev;
|
BeatmapSetNode prevNode = node.prev;
|
||||||
BeatmapSetNode nextNode = node.next;
|
BeatmapSetNode nextNode = node.next;
|
||||||
for (int i = 0, size = node.beatmaps.size(); i < size; i++) {
|
for (int i = 0, size = beatmapSet.size(); i < size; i++) {
|
||||||
BeatmapSetNode newNode = new BeatmapSetNode(beatmaps);
|
BeatmapSetNode newNode = new BeatmapSetNode(beatmapSet);
|
||||||
newNode.index = index;
|
newNode.index = index;
|
||||||
newNode.beatmapIndex = i;
|
newNode.beatmapIndex = i;
|
||||||
newNode.prev = node;
|
newNode.prev = node;
|
||||||
|
@ -443,14 +444,14 @@ public class BeatmapSetList {
|
||||||
String operator = condOperator.remove();
|
String operator = condOperator.remove();
|
||||||
float value = condValue.remove();
|
float value = condValue.remove();
|
||||||
for (BeatmapSetNode node : parsedNodes) {
|
for (BeatmapSetNode node : parsedNodes) {
|
||||||
if (node.matches(type, operator, value))
|
if (node.getBeatmapSet().matches(type, operator, value))
|
||||||
nodes.add(node);
|
nodes.add(node);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// normal term
|
// normal term
|
||||||
String term = terms.remove();
|
String term = terms.remove();
|
||||||
for (BeatmapSetNode node : parsedNodes) {
|
for (BeatmapSetNode node : parsedNodes) {
|
||||||
if (node.matches(term))
|
if (node.getBeatmapSet().matches(term))
|
||||||
nodes.add(node);
|
nodes.add(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,7 +467,7 @@ public class BeatmapSetList {
|
||||||
Iterator<BeatmapSetNode> nodeIter = nodes.iterator();
|
Iterator<BeatmapSetNode> nodeIter = nodes.iterator();
|
||||||
while (nodeIter.hasNext()) {
|
while (nodeIter.hasNext()) {
|
||||||
BeatmapSetNode node = nodeIter.next();
|
BeatmapSetNode node = nodeIter.next();
|
||||||
if (!node.matches(term))
|
if (!node.getBeatmapSet().matches(term))
|
||||||
nodeIter.remove();
|
nodeIter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -484,7 +485,7 @@ public class BeatmapSetList {
|
||||||
Iterator<BeatmapSetNode> nodeIter = nodes.iterator();
|
Iterator<BeatmapSetNode> nodeIter = nodes.iterator();
|
||||||
while (nodeIter.hasNext()) {
|
while (nodeIter.hasNext()) {
|
||||||
BeatmapSetNode node = nodeIter.next();
|
BeatmapSetNode node = nodeIter.next();
|
||||||
if (!node.matches(type, operator, value))
|
if (!node.getBeatmapSet().matches(type, operator, value))
|
||||||
nodeIter.remove();
|
nodeIter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,40 +20,42 @@ package itdelatrisu.opsu.beatmap;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GameData.Grade;
|
import itdelatrisu.opsu.GameData.Grade;
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
import itdelatrisu.opsu.GameMod;
|
|
||||||
import itdelatrisu.opsu.Options;
|
import itdelatrisu.opsu.Options;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
import org.newdawn.slick.Image;
|
import org.newdawn.slick.Image;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node in an BeatmapSetList representing a group of beatmaps.
|
* Node in an BeatmapSetList representing a beatmap set.
|
||||||
*/
|
*/
|
||||||
public class BeatmapSetNode {
|
public class BeatmapSetNode {
|
||||||
/** List of associated beatmaps. */
|
/** The associated beatmap set. */
|
||||||
public ArrayList<Beatmap> beatmaps;
|
private BeatmapSet beatmapSet;
|
||||||
|
|
||||||
/** Index of this node. */
|
|
||||||
public int index = 0;
|
|
||||||
|
|
||||||
/** Index of the selected beatmap (-1 if not focused). */
|
/** Index of the selected beatmap (-1 if not focused). */
|
||||||
public int beatmapIndex = -1;
|
public int beatmapIndex = -1;
|
||||||
|
|
||||||
|
/** Index of this node. */
|
||||||
|
public int index = 0;
|
||||||
|
|
||||||
/** Links to other nodes. */
|
/** Links to other nodes. */
|
||||||
public BeatmapSetNode prev, next;
|
public BeatmapSetNode prev, next;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param beatmaps the beatmaps in this group
|
* @param beatmapSet the beatmap set
|
||||||
*/
|
*/
|
||||||
public BeatmapSetNode(ArrayList<Beatmap> beatmaps) {
|
public BeatmapSetNode(BeatmapSet beatmapSet) {
|
||||||
this.beatmaps = beatmaps;
|
this.beatmapSet = beatmapSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the associated beatmap set.
|
||||||
|
* @return the beatmap set
|
||||||
|
*/
|
||||||
|
public BeatmapSet getBeatmapSet() { return beatmapSet; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the button.
|
* Draws the button.
|
||||||
* @param x the x coordinate
|
* @param x the x coordinate
|
||||||
|
@ -77,10 +79,10 @@ public class BeatmapSetNode {
|
||||||
textColor = Color.white;
|
textColor = Color.white;
|
||||||
} else
|
} else
|
||||||
bgColor = Utils.COLOR_BLUE_BUTTON;
|
bgColor = Utils.COLOR_BLUE_BUTTON;
|
||||||
beatmap = beatmaps.get(beatmapIndex);
|
beatmap = beatmapSet.get(beatmapIndex);
|
||||||
} else {
|
} else {
|
||||||
bgColor = Utils.COLOR_ORANGE_BUTTON;
|
bgColor = Utils.COLOR_ORANGE_BUTTON;
|
||||||
beatmap = beatmaps.get(0);
|
beatmap = beatmapSet.get(0);
|
||||||
}
|
}
|
||||||
bg.draw(x, y, bgColor);
|
bg.draw(x, y, bgColor);
|
||||||
|
|
||||||
|
@ -102,49 +104,17 @@ public class BeatmapSetNode {
|
||||||
Utils.FONT_MEDIUM.drawString(cx, cy, beatmap.getTitle(), textColor);
|
Utils.FONT_MEDIUM.drawString(cx, cy, beatmap.getTitle(), textColor);
|
||||||
Utils.FONT_DEFAULT.drawString(cx, cy + Utils.FONT_MEDIUM.getLineHeight() - 2,
|
Utils.FONT_DEFAULT.drawString(cx, cy + Utils.FONT_MEDIUM.getLineHeight() - 2,
|
||||||
String.format("%s // %s", beatmap.getArtist(), beatmap.creator), textColor);
|
String.format("%s // %s", beatmap.getArtist(), beatmap.creator), textColor);
|
||||||
if (expanded || beatmaps.size() == 1)
|
if (expanded || beatmapSet.size() == 1)
|
||||||
Utils.FONT_BOLD.drawString(cx, cy + Utils.FONT_MEDIUM.getLineHeight() + Utils.FONT_DEFAULT.getLineHeight() - 4,
|
Utils.FONT_BOLD.drawString(cx, cy + Utils.FONT_MEDIUM.getLineHeight() + Utils.FONT_DEFAULT.getLineHeight() - 4,
|
||||||
beatmap.version, textColor);
|
beatmap.version, textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of strings containing song information.
|
* Returns an array of strings containing beatmap information for the
|
||||||
* <ul>
|
* selected beatmap, or null if none selected.
|
||||||
* <li>0: {Artist} - {Title} [{Version}]
|
* @see BeatmapSet#getInfo(int)
|
||||||
* <li>1: Mapped by {Creator}
|
|
||||||
* <li>2: Length: {} BPM: {} Objects: {}
|
|
||||||
* <li>3: Circles: {} Sliders: {} Spinners: {}
|
|
||||||
* <li>4: CS:{} HP:{} AR:{} OD:{}
|
|
||||||
* </ul>
|
|
||||||
*/
|
*/
|
||||||
public String[] getInfo() {
|
public String[] getInfo() { return (beatmapIndex < 0) ? null : beatmapSet.getInfo(beatmapIndex); }
|
||||||
if (beatmapIndex < 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Beatmap beatmap = beatmaps.get(beatmapIndex);
|
|
||||||
float speedModifier = GameMod.getSpeedMultiplier();
|
|
||||||
long endTime = (long) (beatmap.endTime / speedModifier);
|
|
||||||
int bpmMin = (int) (beatmap.bpmMin * speedModifier);
|
|
||||||
int bpmMax = (int) (beatmap.bpmMax * speedModifier);
|
|
||||||
float multiplier = GameMod.getDifficultyMultiplier();
|
|
||||||
String[] info = new String[5];
|
|
||||||
info[0] = beatmap.toString();
|
|
||||||
info[1] = String.format("Mapped by %s", beatmap.creator);
|
|
||||||
info[2] = String.format("Length: %d:%02d BPM: %s Objects: %d",
|
|
||||||
TimeUnit.MILLISECONDS.toMinutes(endTime),
|
|
||||||
TimeUnit.MILLISECONDS.toSeconds(endTime) -
|
|
||||||
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(endTime)),
|
|
||||||
(bpmMax <= 0) ? "--" : ((bpmMin == bpmMax) ? bpmMin : String.format("%d-%d", bpmMin, bpmMax)),
|
|
||||||
(beatmap.hitObjectCircle + beatmap.hitObjectSlider + beatmap.hitObjectSpinner));
|
|
||||||
info[3] = String.format("Circles: %d Sliders: %d Spinners: %d",
|
|
||||||
beatmap.hitObjectCircle, beatmap.hitObjectSlider, beatmap.hitObjectSpinner);
|
|
||||||
info[4] = String.format("CS:%.1f HP:%.1f AR:%.1f OD:%.1f",
|
|
||||||
Math.min(beatmap.circleSize * multiplier, 10f),
|
|
||||||
Math.min(beatmap.HPDrainRate * multiplier, 10f),
|
|
||||||
Math.min(beatmap.approachRate * multiplier, 10f),
|
|
||||||
Math.min(beatmap.overallDifficulty * multiplier, 10f));
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a formatted string for the beatmap at {@code beatmapIndex}:
|
* Returns a formatted string for the beatmap at {@code beatmapIndex}:
|
||||||
|
@ -154,78 +124,8 @@ public class BeatmapSetNode {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (beatmapIndex == -1)
|
if (beatmapIndex == -1)
|
||||||
return String.format("%s - %s", beatmaps.get(0).getArtist(), beatmaps.get(0).getTitle());
|
return beatmapSet.toString();
|
||||||
else
|
else
|
||||||
return beatmaps.get(beatmapIndex).toString();
|
return beatmapSet.get(beatmapIndex).toString();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the node matches a given search query.
|
|
||||||
* @param query the search term
|
|
||||||
* @return true if title, artist, creator, source, version, or tag matches query
|
|
||||||
*/
|
|
||||||
public boolean matches(String query) {
|
|
||||||
Beatmap beatmap = beatmaps.get(0);
|
|
||||||
|
|
||||||
// search: title, artist, creator, source, version, tags (first beatmap)
|
|
||||||
if (beatmap.title.toLowerCase().contains(query) ||
|
|
||||||
beatmap.titleUnicode.toLowerCase().contains(query) ||
|
|
||||||
beatmap.artist.toLowerCase().contains(query) ||
|
|
||||||
beatmap.artistUnicode.toLowerCase().contains(query) ||
|
|
||||||
beatmap.creator.toLowerCase().contains(query) ||
|
|
||||||
beatmap.source.toLowerCase().contains(query) ||
|
|
||||||
beatmap.version.toLowerCase().contains(query) ||
|
|
||||||
beatmap.tags.contains(query))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// search: version, tags (remaining beatmaps)
|
|
||||||
for (int i = 1; i < beatmaps.size(); i++) {
|
|
||||||
beatmap = beatmaps.get(i);
|
|
||||||
if (beatmap.version.toLowerCase().contains(query) ||
|
|
||||||
beatmap.tags.contains(query))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the node matches a given condition.
|
|
||||||
* @param type the condition type (ar, cs, od, hp, bpm, length)
|
|
||||||
* @param operator the operator (=/==, >, >=, <, <=)
|
|
||||||
* @param value the value
|
|
||||||
* @return true if the condition is met
|
|
||||||
*/
|
|
||||||
public boolean matches(String type, String operator, float value) {
|
|
||||||
for (Beatmap beatmap : beatmaps) {
|
|
||||||
// get value
|
|
||||||
float v;
|
|
||||||
switch (type) {
|
|
||||||
case "ar": v = beatmap.approachRate; break;
|
|
||||||
case "cs": v = beatmap.circleSize; break;
|
|
||||||
case "od": v = beatmap.overallDifficulty; break;
|
|
||||||
case "hp": v = beatmap.HPDrainRate; break;
|
|
||||||
case "bpm": v = beatmap.bpmMax; break;
|
|
||||||
case "length": v = beatmap.endTime / 1000; break;
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get operator
|
|
||||||
boolean met;
|
|
||||||
switch (operator) {
|
|
||||||
case "=":
|
|
||||||
case "==": met = (v == value); break;
|
|
||||||
case ">": met = (v > value); break;
|
|
||||||
case ">=": met = (v >= value); break;
|
|
||||||
case "<": met = (v < value); break;
|
|
||||||
case "<=": met = (v <= value); break;
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (met)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -461,7 +461,7 @@ public class ButtonMenu extends BasicGameState {
|
||||||
public void click(GameContainer container, StateBasedGame game) {
|
public void click(GameContainer container, StateBasedGame game) {
|
||||||
SoundController.playSound(SoundEffect.MENUHIT);
|
SoundController.playSound(SoundEffect.MENUHIT);
|
||||||
BeatmapSetNode node = ((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).getNode();
|
BeatmapSetNode node = ((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).getNode();
|
||||||
MenuState ms = (node.beatmapIndex == -1 || node.beatmaps.size() == 1) ?
|
MenuState ms = (node.beatmapIndex == -1 || node.getBeatmapSet().size() == 1) ?
|
||||||
MenuState.BEATMAP_DELETE_CONFIRM : MenuState.BEATMAP_DELETE_SELECT;
|
MenuState.BEATMAP_DELETE_CONFIRM : MenuState.BEATMAP_DELETE_SELECT;
|
||||||
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(ms, node);
|
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(ms, node);
|
||||||
game.enterState(Opsu.STATE_BUTTONMENU);
|
game.enterState(Opsu.STATE_BUTTONMENU);
|
||||||
|
|
|
@ -606,7 +606,7 @@ public class MainMenu extends BasicGameState {
|
||||||
BeatmapSetNode node = menu.setFocus(BeatmapSetList.get().getRandomNode(), -1, true, false);
|
BeatmapSetNode node = menu.setFocus(BeatmapSetList.get().getRandomNode(), -1, true, false);
|
||||||
boolean sameAudio = false;
|
boolean sameAudio = false;
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
sameAudio = MusicController.getBeatmap().audioFilename.equals(node.beatmaps.get(0).audioFilename);
|
sameAudio = MusicController.getBeatmap().audioFilename.equals(node.getBeatmapSet().get(0).audioFilename);
|
||||||
if (!isTheme && !sameAudio)
|
if (!isTheme && !sameAudio)
|
||||||
previous.add(node.index);
|
previous.add(node.index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,7 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
// background
|
// background
|
||||||
if (focusNode != null) {
|
if (focusNode != null) {
|
||||||
Beatmap focusNodeBeatmap = focusNode.beatmaps.get(focusNode.beatmapIndex);
|
Beatmap focusNodeBeatmap = focusNode.getBeatmapSet().get(focusNode.beatmapIndex);
|
||||||
if (!focusNodeBeatmap.drawBG(width, height, 1.0f, true))
|
if (!focusNodeBeatmap.drawBG(width, height, 1.0f, true))
|
||||||
GameImage.PLAYFIELD.getImage().draw();
|
GameImage.PLAYFIELD.getImage().draw();
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ public class SongMenu extends BasicGameState {
|
||||||
if (songInfo == null) {
|
if (songInfo == null) {
|
||||||
songInfo = focusNode.getInfo();
|
songInfo = focusNode.getInfo();
|
||||||
if (Options.useUnicodeMetadata()) { // load glyphs
|
if (Options.useUnicodeMetadata()) { // load glyphs
|
||||||
Beatmap beatmap = focusNode.beatmaps.get(0);
|
Beatmap beatmap = focusNode.getBeatmapSet().get(0);
|
||||||
Utils.loadGlyphs(Utils.FONT_LARGE, beatmap.titleUnicode, beatmap.artistUnicode);
|
Utils.loadGlyphs(Utils.FONT_LARGE, beatmap.titleUnicode, beatmap.artistUnicode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,7 +437,7 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
// scroll bar
|
// scroll bar
|
||||||
if (focusNode != null) {
|
if (focusNode != null) {
|
||||||
int focusNodes = focusNode.beatmaps.size();
|
int focusNodes = focusNode.getBeatmapSet().size();
|
||||||
int totalNodes = BeatmapSetList.get().size() + focusNodes - 1;
|
int totalNodes = BeatmapSetList.get().size() + focusNodes - 1;
|
||||||
if (totalNodes > MAX_SONG_BUTTONS) {
|
if (totalNodes > MAX_SONG_BUTTONS) {
|
||||||
int startIndex = startNode.index;
|
int startIndex = startNode.index;
|
||||||
|
@ -782,7 +782,7 @@ public class SongMenu extends BasicGameState {
|
||||||
break;
|
break;
|
||||||
if (input.isKeyDown(Input.KEY_RSHIFT) || input.isKeyDown(Input.KEY_LSHIFT)) {
|
if (input.isKeyDown(Input.KEY_RSHIFT) || input.isKeyDown(Input.KEY_LSHIFT)) {
|
||||||
SoundController.playSound(SoundEffect.MENUHIT);
|
SoundController.playSound(SoundEffect.MENUHIT);
|
||||||
MenuState ms = (focusNode.beatmapIndex == -1 || focusNode.beatmaps.size() == 1) ?
|
MenuState ms = (focusNode.beatmapIndex == -1 || focusNode.getBeatmapSet().size() == 1) ?
|
||||||
MenuState.BEATMAP_DELETE_CONFIRM : MenuState.BEATMAP_DELETE_SELECT;
|
MenuState.BEATMAP_DELETE_CONFIRM : MenuState.BEATMAP_DELETE_SELECT;
|
||||||
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(ms, focusNode);
|
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(ms, focusNode);
|
||||||
game.enterState(Opsu.STATE_BUTTONMENU);
|
game.enterState(Opsu.STATE_BUTTONMENU);
|
||||||
|
@ -838,7 +838,7 @@ public class SongMenu extends BasicGameState {
|
||||||
BeatmapSetNode oldStartNode = startNode;
|
BeatmapSetNode oldStartNode = startNode;
|
||||||
float oldHoverOffset = hoverOffset;
|
float oldHoverOffset = hoverOffset;
|
||||||
int oldHoverIndex = hoverIndex;
|
int oldHoverIndex = hoverIndex;
|
||||||
setFocus(prev, (prev.index == focusNode.index) ? 0 : prev.beatmaps.size() - 1, false, true);
|
setFocus(prev, (prev.index == focusNode.index) ? 0 : prev.getBeatmapSet().size() - 1, false, true);
|
||||||
if (startNode == oldStartNode) {
|
if (startNode == oldStartNode) {
|
||||||
hoverOffset = oldHoverOffset;
|
hoverOffset = oldHoverOffset;
|
||||||
hoverIndex = oldHoverIndex;
|
hoverIndex = oldHoverIndex;
|
||||||
|
@ -982,7 +982,7 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
// reload scores
|
// reload scores
|
||||||
if (focusNode != null) {
|
if (focusNode != null) {
|
||||||
scoreMap = ScoreDB.getMapSetScores(focusNode.beatmaps.get(focusNode.beatmapIndex));
|
scoreMap = ScoreDB.getMapSetScores(focusNode.getBeatmapSet().get(focusNode.beatmapIndex));
|
||||||
focusScores = getScoreDataForNode(focusNode, true);
|
focusScores = getScoreDataForNode(focusNode, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,7 +995,7 @@ public class SongMenu extends BasicGameState {
|
||||||
case BEATMAP: // clear all scores
|
case BEATMAP: // clear all scores
|
||||||
if (stateActionNode == null || stateActionNode.beatmapIndex == -1)
|
if (stateActionNode == null || stateActionNode.beatmapIndex == -1)
|
||||||
break;
|
break;
|
||||||
Beatmap beatmap = stateActionNode.beatmaps.get(stateActionNode.beatmapIndex);
|
Beatmap beatmap = stateActionNode.getBeatmapSet().get(stateActionNode.beatmapIndex);
|
||||||
ScoreDB.deleteScore(beatmap);
|
ScoreDB.deleteScore(beatmap);
|
||||||
if (stateActionNode == focusNode) {
|
if (stateActionNode == focusNode) {
|
||||||
focusScores = null;
|
focusScores = null;
|
||||||
|
@ -1006,7 +1006,7 @@ public class SongMenu extends BasicGameState {
|
||||||
if (stateActionScore == null)
|
if (stateActionScore == null)
|
||||||
break;
|
break;
|
||||||
ScoreDB.deleteScore(stateActionScore);
|
ScoreDB.deleteScore(stateActionScore);
|
||||||
scoreMap = ScoreDB.getMapSetScores(focusNode.beatmaps.get(focusNode.beatmapIndex));
|
scoreMap = ScoreDB.getMapSetScores(focusNode.getBeatmapSet().get(focusNode.beatmapIndex));
|
||||||
focusScores = getScoreDataForNode(focusNode, true);
|
focusScores = getScoreDataForNode(focusNode, true);
|
||||||
startScore = 0;
|
startScore = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -1191,7 +1191,7 @@ public class SongMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check beatmapIndex bounds
|
// check beatmapIndex bounds
|
||||||
int length = node.beatmaps.size();
|
int length = node.getBeatmapSet().size();
|
||||||
if (beatmapIndex < 0 || beatmapIndex > length - 1) // set a random index
|
if (beatmapIndex < 0 || beatmapIndex > length - 1) // set a random index
|
||||||
beatmapIndex = (int) (Math.random() * length);
|
beatmapIndex = (int) (Math.random() * length);
|
||||||
|
|
||||||
|
@ -1199,7 +1199,7 @@ public class SongMenu extends BasicGameState {
|
||||||
if (changeStartNode || (startNode.index == 0 && startNode.beatmapIndex == -1 && startNode.prev == null))
|
if (changeStartNode || (startNode.index == 0 && startNode.beatmapIndex == -1 && startNode.prev == null))
|
||||||
startNode = node;
|
startNode = node;
|
||||||
focusNode = BeatmapSetList.get().getNode(node, beatmapIndex);
|
focusNode = BeatmapSetList.get().getNode(node, beatmapIndex);
|
||||||
Beatmap beatmap = focusNode.beatmaps.get(focusNode.beatmapIndex);
|
Beatmap beatmap = focusNode.getBeatmapSet().get(focusNode.beatmapIndex);
|
||||||
MusicController.play(beatmap, false, preview);
|
MusicController.play(beatmap, false, preview);
|
||||||
|
|
||||||
// load scores
|
// load scores
|
||||||
|
@ -1221,7 +1221,7 @@ public class SongMenu extends BasicGameState {
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
changeIndex(val);
|
changeIndex(val);
|
||||||
} else if (startNode.index > focusNode.index) {
|
} else if (startNode.index > focusNode.index) {
|
||||||
val = focusNode.index - focusNode.beatmaps.size() + focusNode.beatmapIndex - startNode.index + 1;
|
val = focusNode.index - focusNode.getBeatmapSet().size() + focusNode.beatmapIndex - startNode.index + 1;
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
changeIndex(val);
|
changeIndex(val);
|
||||||
}
|
}
|
||||||
|
@ -1291,7 +1291,7 @@ public class SongMenu extends BasicGameState {
|
||||||
if (scoreMap == null || scoreMap.isEmpty() || node.beatmapIndex == -1) // node not expanded
|
if (scoreMap == null || scoreMap.isEmpty() || node.beatmapIndex == -1) // node not expanded
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Beatmap beatmap = node.beatmaps.get(node.beatmapIndex);
|
Beatmap beatmap = node.getBeatmapSet().get(node.beatmapIndex);
|
||||||
ScoreData[] scores = scoreMap.get(beatmap.version);
|
ScoreData[] scores = scoreMap.get(beatmap.version);
|
||||||
if (scores == null || scores.length < 1) // no scores
|
if (scores == null || scores.length < 1) // no scores
|
||||||
return null;
|
return null;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user