/* * 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 . */ 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 beatmaps; /** * Constructor. * @param beatmaps the beatmaps in this set */ public BeatmapSet(ArrayList 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. *
    *
  • 0: {Artist} - {Title} [{Version}] *
  • 1: Mapped by {Creator} *
  • 2: Length: {} BPM: {} Objects: {} *
  • 3: Circles: {} Sliders: {} Spinners: {} *
  • 4: CS:{} HP:{} AR:{} OD:{} *
* @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%s", Math.min(beatmap.circleSize * multiplier, 10f), Math.min(beatmap.HPDrainRate * multiplier, 10f), Math.min(beatmap.approachRate * multiplier, 10f), Math.min(beatmap.overallDifficulty * multiplier, 10f), (beatmap.starRating >= 0) ? String.format(" Stars: %.2f", beatmap.starRating) : ""); 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 {@literal (=/==, >, >=, <, <=)} * @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; } }