Game mod refactoring.
- Created "GameMod" enum to handle all mod-related actions and store all related data. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
d5b7ff3516
commit
7a187c4e4f
|
@ -15,6 +15,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
|
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package itdelatrisu.opsu;
|
package itdelatrisu.opsu;
|
||||||
|
|
||||||
import itdelatrisu.opsu.states.Options;
|
import itdelatrisu.opsu.states.Options;
|
||||||
|
@ -150,6 +151,7 @@ public enum GameImage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
* @param filename the image file name
|
||||||
*/
|
*/
|
||||||
GameImage(String filename) {
|
GameImage(String filename) {
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
|
|
172
src/itdelatrisu/opsu/GameMod.java
Normal file
172
src/itdelatrisu/opsu/GameMod.java
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* opsu! - an open-source osu! client
|
||||||
|
* Copyright (C) 2014 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;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.newdawn.slick.Image;
|
||||||
|
import org.newdawn.slick.SlickException;
|
||||||
|
import org.newdawn.slick.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game mods.
|
||||||
|
*/
|
||||||
|
public enum GameMod {
|
||||||
|
NO_FAIL (0, "selection-mod-nofail.png"),
|
||||||
|
HARD_ROCK (1, "selection-mod-hardrock.png"),
|
||||||
|
SUDDEN_DEATH (2, "selection-mod-suddendeath.png"),
|
||||||
|
SPUN_OUT (3, "selection-mod-spunout.png"),
|
||||||
|
AUTO (4, "selection-mod-autoplay.png");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ID of the mod (used for positioning).
|
||||||
|
*/
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file name of the mod image.
|
||||||
|
*/
|
||||||
|
private String filename;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not this mod is active.
|
||||||
|
*/
|
||||||
|
private boolean active = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The button containing the mod image (displayed in Options screen).
|
||||||
|
*/
|
||||||
|
private GUIMenuButton button;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total number of mods.
|
||||||
|
*/
|
||||||
|
private static final int size = GameMod.values().length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the total number of game mods.
|
||||||
|
* @return the number of mods
|
||||||
|
*/
|
||||||
|
public static int size() { return size; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of GameMod objects in reverse order.
|
||||||
|
* @return all game mods in reverse order
|
||||||
|
*/
|
||||||
|
public static GameMod[] valuesReversed() {
|
||||||
|
GameMod[] mods = GameMod.values();
|
||||||
|
Collections.reverse(Arrays.asList(mods));
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param id the ID of the mod (for positioning).
|
||||||
|
* @param filename the image file name
|
||||||
|
*/
|
||||||
|
GameMod(int id, String filename) {
|
||||||
|
this.id = id;
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the game mod.
|
||||||
|
* @param width the container width
|
||||||
|
* @param height the container height
|
||||||
|
*/
|
||||||
|
public void init(int width, int height) {
|
||||||
|
try {
|
||||||
|
// create and scale image
|
||||||
|
Image img = new Image(filename);
|
||||||
|
float scale = (height * 0.12f) / img.getHeight();
|
||||||
|
img = img.getScaledCopy(scale);
|
||||||
|
|
||||||
|
// find coordinates
|
||||||
|
float offsetX = img.getWidth() * 1.5f;
|
||||||
|
float x = (width / 2f) - (offsetX * size / 2.75f);
|
||||||
|
float y = (height * 0.8f) + (img.getHeight() / 2);
|
||||||
|
|
||||||
|
// create button
|
||||||
|
img.setAlpha(0.5f);
|
||||||
|
this.button = new GUIMenuButton(img, x + (offsetX * id), y);
|
||||||
|
} catch (SlickException e) {
|
||||||
|
Log.error(String.format("Failed to initialize game mod '%s'.", this), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the active status of the mod.
|
||||||
|
* @param checkInverse if true, perform checks for mutual exclusivity
|
||||||
|
*/
|
||||||
|
public void toggle(boolean checkInverse) {
|
||||||
|
button.getImage().setAlpha(active ? 0.5f : 1.0f);
|
||||||
|
active = !active;
|
||||||
|
|
||||||
|
if (checkInverse) {
|
||||||
|
if (AUTO.isActive()) {
|
||||||
|
if (this == AUTO) {
|
||||||
|
if (SPUN_OUT.isActive())
|
||||||
|
SPUN_OUT.toggle(false);
|
||||||
|
if (SUDDEN_DEATH.isActive())
|
||||||
|
SUDDEN_DEATH.toggle(false);
|
||||||
|
} else if (this == SPUN_OUT || this == SUDDEN_DEATH) {
|
||||||
|
if (active)
|
||||||
|
toggle(false);
|
||||||
|
}
|
||||||
|
} else if (SUDDEN_DEATH.isActive() && NO_FAIL.isActive()) {
|
||||||
|
if (this == SUDDEN_DEATH)
|
||||||
|
NO_FAIL.toggle(false);
|
||||||
|
else
|
||||||
|
SUDDEN_DEATH.toggle(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the mod is active.
|
||||||
|
* @return true if active
|
||||||
|
*/
|
||||||
|
public boolean isActive() { return active; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the image associated with the mod.
|
||||||
|
* @return the associated image
|
||||||
|
*/
|
||||||
|
public Image getImage() { return button.getImage(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the mod ID.
|
||||||
|
* @return the mod ID
|
||||||
|
*/
|
||||||
|
public int getID() { return id; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the game mod.
|
||||||
|
*/
|
||||||
|
public void draw() { button.draw(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the coordinates are within the image bounds.
|
||||||
|
* @param x the x coordinate
|
||||||
|
* @param y the y coordinate
|
||||||
|
* @return true if within bounds
|
||||||
|
*/
|
||||||
|
public boolean contains(float x, float y) { return button.contains(x, y); }
|
||||||
|
}
|
|
@ -503,13 +503,13 @@ public class GameScore {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mod icons
|
// mod icons
|
||||||
if ((firstObject && trackPosition < firstObjectTime) || Options.isModActive(Options.MOD_AUTO)) {
|
if ((firstObject && trackPosition < firstObjectTime) || GameMod.AUTO.isActive()) {
|
||||||
int modWidth = Options.getModImage(0).getWidth();
|
int modWidth = GameMod.AUTO.getImage().getWidth();
|
||||||
float modX = (width * 0.98f) - modWidth;
|
float modX = (width * 0.98f) - modWidth;
|
||||||
for (int i = Options.MOD_MAX - 1, modCount = 0; i >= 0; i--) {
|
int modCount = 0;
|
||||||
if (Options.isModActive(i)) {
|
for (GameMod mod : GameMod.valuesReversed()) {
|
||||||
Image modImage = Options.getModImage(i);
|
if (mod.isActive()) {
|
||||||
modImage.draw(
|
mod.getImage().draw(
|
||||||
modX - (modCount * (modWidth / 2f)),
|
modX - (modCount * (modWidth / 2f)),
|
||||||
symbolHeight + circleDiameter + 10
|
symbolHeight + circleDiameter + 10
|
||||||
);
|
);
|
||||||
|
@ -702,9 +702,7 @@ public class GameScore {
|
||||||
* If "No Fail" or "Auto" mods are active, this will always return true.
|
* If "No Fail" or "Auto" mods are active, this will always return true.
|
||||||
*/
|
*/
|
||||||
public boolean isAlive() {
|
public boolean isAlive() {
|
||||||
return (health > 0f ||
|
return (health > 0f || GameMod.NO_FAIL.isActive() || GameMod.AUTO.isActive());
|
||||||
Options.isModActive(Options.MOD_NO_FAIL) ||
|
|
||||||
Options.isModActive(Options.MOD_AUTO));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -816,7 +814,7 @@ public class GameScore {
|
||||||
if (combo >= 20)
|
if (combo >= 20)
|
||||||
SoundController.playSound(SoundController.SOUND_COMBOBREAK);
|
SoundController.playSound(SoundController.SOUND_COMBOBREAK);
|
||||||
combo = 0;
|
combo = 0;
|
||||||
if (Options.isModActive(Options.MOD_SUDDEN_DEATH))
|
if (GameMod.SUDDEN_DEATH.isActive())
|
||||||
health = 0f;
|
health = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,11 +904,11 @@ public class GameScore {
|
||||||
|
|
||||||
// game mod score multipliers
|
// game mod score multipliers
|
||||||
float modMultiplier = 1f;
|
float modMultiplier = 1f;
|
||||||
if (Options.isModActive(Options.MOD_NO_FAIL))
|
if (GameMod.NO_FAIL.isActive())
|
||||||
modMultiplier *= 0.5f;
|
modMultiplier *= 0.5f;
|
||||||
if (Options.isModActive(Options.MOD_HARD_ROCK))
|
if (GameMod.HARD_ROCK.isActive())
|
||||||
modMultiplier *= 1.06f;
|
modMultiplier *= 1.06f;
|
||||||
if (Options.isModActive(Options.MOD_SPUN_OUT))
|
if (GameMod.SPUN_OUT.isActive())
|
||||||
modMultiplier *= 0.9f;
|
modMultiplier *= 0.9f;
|
||||||
// not implemented:
|
// not implemented:
|
||||||
// EASY (0.5x), HALF_TIME (0.3x),
|
// EASY (0.5x), HALF_TIME (0.3x),
|
||||||
|
|
|
@ -130,6 +130,9 @@ public class Utils {
|
||||||
container.getInput().enableKeyRepeat();
|
container.getInput().enableKeyRepeat();
|
||||||
container.setAlwaysRender(true);
|
container.setAlwaysRender(true);
|
||||||
|
|
||||||
|
int width = container.getWidth();
|
||||||
|
int height = container.getHeight();
|
||||||
|
|
||||||
// set the cursor
|
// set the cursor
|
||||||
try {
|
try {
|
||||||
// hide the native cursor
|
// hide the native cursor
|
||||||
|
@ -141,7 +144,6 @@ public class Utils {
|
||||||
loadCursor();
|
loadCursor();
|
||||||
|
|
||||||
// create fonts
|
// create fonts
|
||||||
int height = container.getHeight();
|
|
||||||
float fontBase;
|
float fontBase;
|
||||||
if (height <= 600)
|
if (height <= 600)
|
||||||
fontBase = 9f;
|
fontBase = 9f;
|
||||||
|
@ -161,8 +163,12 @@ public class Utils {
|
||||||
FONT_SMALL = new TrueTypeFont(font.deriveFont(fontBase), false);
|
FONT_SMALL = new TrueTypeFont(font.deriveFont(fontBase), false);
|
||||||
|
|
||||||
// set default game images
|
// set default game images
|
||||||
for (GameImage o : GameImage.values())
|
for (GameImage img : GameImage.values())
|
||||||
o.setDefaultImage();
|
img.setDefaultImage();
|
||||||
|
|
||||||
|
// initialize game mods
|
||||||
|
for (GameMod mod : GameMod.values())
|
||||||
|
mod.init(width, height);
|
||||||
|
|
||||||
// tab image
|
// tab image
|
||||||
tab = new Image("selection-tab.png");
|
tab = new Image("selection-tab.png");
|
||||||
|
|
|
@ -19,12 +19,12 @@
|
||||||
package itdelatrisu.opsu.objects;
|
package itdelatrisu.opsu.objects;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
|
import itdelatrisu.opsu.GameMod;
|
||||||
import itdelatrisu.opsu.GameScore;
|
import itdelatrisu.opsu.GameScore;
|
||||||
import itdelatrisu.opsu.MusicController;
|
import itdelatrisu.opsu.MusicController;
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.states.Game;
|
import itdelatrisu.opsu.states.Game;
|
||||||
import itdelatrisu.opsu.states.Options;
|
|
||||||
|
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
import org.newdawn.slick.GameContainer;
|
import org.newdawn.slick.GameContainer;
|
||||||
|
@ -161,7 +161,7 @@ public class Circle {
|
||||||
public boolean update(boolean overlap) {
|
public boolean update(boolean overlap) {
|
||||||
int trackPosition = MusicController.getPosition();
|
int trackPosition = MusicController.getPosition();
|
||||||
int[] hitResultOffset = game.getHitResultOffsets();
|
int[] hitResultOffset = game.getHitResultOffsets();
|
||||||
boolean isAutoMod = Options.isModActive(Options.MOD_AUTO);
|
boolean isAutoMod = GameMod.AUTO.isActive();
|
||||||
|
|
||||||
if (overlap || trackPosition > hitObject.time + hitResultOffset[GameScore.HIT_50]) {
|
if (overlap || trackPosition > hitObject.time + hitResultOffset[GameScore.HIT_50]) {
|
||||||
if (isAutoMod) // "auto" mod: catch any missed notes due to lag
|
if (isAutoMod) // "auto" mod: catch any missed notes due to lag
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
package itdelatrisu.opsu.objects;
|
package itdelatrisu.opsu.objects;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
|
import itdelatrisu.opsu.GameMod;
|
||||||
import itdelatrisu.opsu.GameScore;
|
import itdelatrisu.opsu.GameScore;
|
||||||
import itdelatrisu.opsu.MusicController;
|
import itdelatrisu.opsu.MusicController;
|
||||||
import itdelatrisu.opsu.OsuFile;
|
import itdelatrisu.opsu.OsuFile;
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.states.Game;
|
import itdelatrisu.opsu.states.Game;
|
||||||
import itdelatrisu.opsu.states.Options;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
@ -497,7 +497,7 @@ public class Slider {
|
||||||
int trackPosition = MusicController.getPosition();
|
int trackPosition = MusicController.getPosition();
|
||||||
int[] hitResultOffset = game.getHitResultOffsets();
|
int[] hitResultOffset = game.getHitResultOffsets();
|
||||||
int lastIndex = hitObject.sliderX.length - 1;
|
int lastIndex = hitObject.sliderX.length - 1;
|
||||||
boolean isAutoMod = Options.isModActive(Options.MOD_AUTO);
|
boolean isAutoMod = GameMod.AUTO.isActive();
|
||||||
|
|
||||||
if (!sliderClicked) {
|
if (!sliderClicked) {
|
||||||
// start circle time passed
|
// start circle time passed
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
package itdelatrisu.opsu.objects;
|
package itdelatrisu.opsu.objects;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
|
import itdelatrisu.opsu.GameMod;
|
||||||
import itdelatrisu.opsu.GameScore;
|
import itdelatrisu.opsu.GameScore;
|
||||||
import itdelatrisu.opsu.MusicController;
|
import itdelatrisu.opsu.MusicController;
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
import itdelatrisu.opsu.SoundController;
|
import itdelatrisu.opsu.SoundController;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.states.Game;
|
import itdelatrisu.opsu.states.Game;
|
||||||
import itdelatrisu.opsu.states.Options;
|
|
||||||
|
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
import org.newdawn.slick.GameContainer;
|
import org.newdawn.slick.GameContainer;
|
||||||
|
@ -154,8 +154,7 @@ public class Spinner {
|
||||||
int result;
|
int result;
|
||||||
float ratio = rotations / rotationsNeeded;
|
float ratio = rotations / rotationsNeeded;
|
||||||
if (ratio >= 1.0f ||
|
if (ratio >= 1.0f ||
|
||||||
Options.isModActive(Options.MOD_AUTO) ||
|
GameMod.AUTO.isActive() || GameMod.SPUN_OUT.isActive()) {
|
||||||
Options.isModActive(Options.MOD_SPUN_OUT)) {
|
|
||||||
result = GameScore.HIT_300;
|
result = GameScore.HIT_300;
|
||||||
SoundController.playSound(SoundController.SOUND_SPINNEROSU);
|
SoundController.playSound(SoundController.SOUND_SPINNEROSU);
|
||||||
} else if (ratio >= 0.8f)
|
} else if (ratio >= 0.8f)
|
||||||
|
@ -190,12 +189,12 @@ public class Spinner {
|
||||||
}
|
}
|
||||||
|
|
||||||
// spin automatically (TODO: correct rotation angles)
|
// spin automatically (TODO: correct rotation angles)
|
||||||
if (Options.isModActive(Options.MOD_AUTO)) {
|
if (GameMod.AUTO.isActive()) {
|
||||||
// "auto" mod (fast)
|
// "auto" mod (fast)
|
||||||
score.changeHealth(delta / 200f); // maintain health (TODO)
|
score.changeHealth(delta / 200f); // maintain health (TODO)
|
||||||
rotate(delta / 20f);
|
rotate(delta / 20f);
|
||||||
return false;
|
return false;
|
||||||
} else if (Options.isModActive(Options.MOD_SPUN_OUT)) {
|
} else if (GameMod.SPUN_OUT.isActive()) {
|
||||||
// "spun out" mod (slow)
|
// "spun out" mod (slow)
|
||||||
score.changeHealth(delta / 200f); // maintain health (TODO)
|
score.changeHealth(delta / 200f); // maintain health (TODO)
|
||||||
rotate(delta / 32f);
|
rotate(delta / 32f);
|
||||||
|
|
|
@ -20,6 +20,7 @@ package itdelatrisu.opsu.states;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GUIMenuButton;
|
import itdelatrisu.opsu.GUIMenuButton;
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
|
import itdelatrisu.opsu.GameMod;
|
||||||
import itdelatrisu.opsu.GameScore;
|
import itdelatrisu.opsu.GameScore;
|
||||||
import itdelatrisu.opsu.MusicController;
|
import itdelatrisu.opsu.MusicController;
|
||||||
import itdelatrisu.opsu.Opsu;
|
import itdelatrisu.opsu.Opsu;
|
||||||
|
@ -295,7 +296,7 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Options.isModActive(Options.MOD_AUTO))
|
if (GameMod.AUTO.isActive())
|
||||||
GameImage.UNRANKED.getImage().drawCentered(width / 2, height * 0.077f);
|
GameImage.UNRANKED.getImage().drawCentered(width / 2, height * 0.077f);
|
||||||
Utils.drawFPS();
|
Utils.drawFPS();
|
||||||
Utils.drawCursor();
|
Utils.drawCursor();
|
||||||
|
@ -382,7 +383,7 @@ public class Game extends BasicGameState {
|
||||||
// draw OsuHitObjectResult objects
|
// draw OsuHitObjectResult objects
|
||||||
score.drawHitResults(trackPosition);
|
score.drawHitResults(trackPosition);
|
||||||
|
|
||||||
if (Options.isModActive(Options.MOD_AUTO))
|
if (GameMod.AUTO.isActive())
|
||||||
GameImage.UNRANKED.getImage().drawCentered(width / 2, height * 0.077f);
|
GameImage.UNRANKED.getImage().drawCentered(width / 2, height * 0.077f);
|
||||||
|
|
||||||
// returning from pause screen
|
// returning from pause screen
|
||||||
|
@ -494,7 +495,7 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pause game if focus lost
|
// pause game if focus lost
|
||||||
if (!container.hasFocus() && !Options.isModActive(Options.MOD_AUTO)) {
|
if (!container.hasFocus() && !GameMod.AUTO.isActive()) {
|
||||||
if (pauseTime < 0) {
|
if (pauseTime < 0) {
|
||||||
pausedMouseX = input.getMouseX();
|
pausedMouseX = input.getMouseX();
|
||||||
pausedMouseY = input.getMouseY();
|
pausedMouseY = input.getMouseY();
|
||||||
|
@ -551,7 +552,7 @@ public class Game extends BasicGameState {
|
||||||
int trackPosition = MusicController.getPosition();
|
int trackPosition = MusicController.getPosition();
|
||||||
if (pauseTime < 0 && breakTime <= 0 &&
|
if (pauseTime < 0 && breakTime <= 0 &&
|
||||||
trackPosition >= osu.objects[0].time &&
|
trackPosition >= osu.objects[0].time &&
|
||||||
!Options.isModActive(Options.MOD_AUTO)) {
|
!GameMod.AUTO.isActive()) {
|
||||||
pausedMouseX = input.getMouseX();
|
pausedMouseX = input.getMouseX();
|
||||||
pausedMouseY = input.getMouseY();
|
pausedMouseY = input.getMouseY();
|
||||||
pausePulse = 0f;
|
pausePulse = 0f;
|
||||||
|
@ -662,7 +663,7 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// "auto" mod: ignore user actions
|
// "auto" mod: ignore user actions
|
||||||
if (Options.isModActive(Options.MOD_AUTO))
|
if (GameMod.AUTO.isActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// circles
|
// circles
|
||||||
|
@ -883,8 +884,8 @@ public class Game extends BasicGameState {
|
||||||
if (Options.getFixedHP() > 0f)
|
if (Options.getFixedHP() > 0f)
|
||||||
HPDrainRate = Options.getFixedHP();
|
HPDrainRate = Options.getFixedHP();
|
||||||
|
|
||||||
// hard rock modifiers
|
// "Hard Rock" modifiers
|
||||||
if (Options.isModActive(Options.MOD_HARD_ROCK)) {
|
if (GameMod.HARD_ROCK.isActive()) {
|
||||||
circleSize = Math.min(circleSize * 1.4f, 10);
|
circleSize = Math.min(circleSize * 1.4f, 10);
|
||||||
approachRate = Math.min(approachRate * 1.4f, 10);
|
approachRate = Math.min(approachRate * 1.4f, 10);
|
||||||
overallDifficulty = Math.min(overallDifficulty * 1.4f, 10);
|
overallDifficulty = Math.min(overallDifficulty * 1.4f, 10);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package itdelatrisu.opsu.states;
|
package itdelatrisu.opsu.states;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GUIMenuButton;
|
import itdelatrisu.opsu.GUIMenuButton;
|
||||||
|
import itdelatrisu.opsu.GameMod;
|
||||||
import itdelatrisu.opsu.GameScore;
|
import itdelatrisu.opsu.GameScore;
|
||||||
import itdelatrisu.opsu.MusicController;
|
import itdelatrisu.opsu.MusicController;
|
||||||
import itdelatrisu.opsu.Opsu;
|
import itdelatrisu.opsu.Opsu;
|
||||||
|
@ -107,11 +108,11 @@ public class GameRanking extends BasicGameState {
|
||||||
score.drawRankingElements(g, width, height);
|
score.drawRankingElements(g, width, height);
|
||||||
|
|
||||||
// game mods
|
// game mods
|
||||||
for (int i = Options.MOD_MAX - 1; i >= 0; i--) {
|
for (GameMod mod : GameMod.valuesReversed()) {
|
||||||
if (Options.isModActive(i)) {
|
if (mod.isActive()) {
|
||||||
Image modImage = Options.getModImage(i);
|
Image modImage = mod.getImage();
|
||||||
modImage.draw(
|
modImage.draw(
|
||||||
(width * 0.75f) + ((i - (Options.MOD_MAX / 2)) * modImage.getWidth() / 3f),
|
(width * 0.75f) + ((mod.getID() - (GameMod.size() / 2)) * modImage.getWidth() / 3f),
|
||||||
height / 2f
|
height / 2f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package itdelatrisu.opsu.states;
|
package itdelatrisu.opsu.states;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GUIMenuButton;
|
import itdelatrisu.opsu.GUIMenuButton;
|
||||||
|
import itdelatrisu.opsu.GameMod;
|
||||||
import itdelatrisu.opsu.Opsu;
|
import itdelatrisu.opsu.Opsu;
|
||||||
import itdelatrisu.opsu.SoundController;
|
import itdelatrisu.opsu.SoundController;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
|
@ -95,27 +96,6 @@ public class Options extends BasicGameState {
|
||||||
*/
|
*/
|
||||||
private static File skinDir;
|
private static File skinDir;
|
||||||
|
|
||||||
/**
|
|
||||||
* Game mods.
|
|
||||||
*/
|
|
||||||
public static final int
|
|
||||||
MOD_NO_FAIL = 0,
|
|
||||||
MOD_HARD_ROCK = 1,
|
|
||||||
MOD_SUDDEN_DEATH = 2,
|
|
||||||
MOD_SPUN_OUT = 3,
|
|
||||||
MOD_AUTO = 4,
|
|
||||||
MOD_MAX = 5; // not a mod
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether a mod is active (indexed by MOD_* constants).
|
|
||||||
*/
|
|
||||||
private static boolean[] modsActive;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mod buttons.
|
|
||||||
*/
|
|
||||||
private static GUIMenuButton[] modButtons;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Game options.
|
* Game options.
|
||||||
*/
|
*/
|
||||||
|
@ -417,37 +397,6 @@ public class Options extends BasicGameState {
|
||||||
((width - subtextWidth - tab.getWidth()) / 2) / TAB_MAX);
|
((width - subtextWidth - tab.getWidth()) / 2) / TAB_MAX);
|
||||||
for (int i = 0; i < optionTabs.length; i++)
|
for (int i = 0; i < optionTabs.length; i++)
|
||||||
optionTabs[i] = new GUIMenuButton(tab, tabX + (i * tabOffset), tabY);
|
optionTabs[i] = new GUIMenuButton(tab, tabX + (i * tabOffset), tabY);
|
||||||
|
|
||||||
// game mods
|
|
||||||
modsActive = new boolean[MOD_MAX];
|
|
||||||
modButtons = new GUIMenuButton[MOD_MAX];
|
|
||||||
Image noFailImage = new Image("selection-mod-nofail.png");
|
|
||||||
float modScale = (height * 0.12f) / noFailImage.getHeight();
|
|
||||||
noFailImage = noFailImage.getScaledCopy(modScale);
|
|
||||||
float modButtonOffsetX = noFailImage.getWidth() * 1.5f;
|
|
||||||
float modButtonX = (width / 2f) - (modButtonOffsetX * modButtons.length / 2.75f);
|
|
||||||
float modButtonY = (height * 0.8f) + (noFailImage.getHeight() / 2);
|
|
||||||
modButtons[MOD_NO_FAIL] = new GUIMenuButton(
|
|
||||||
noFailImage, modButtonX, modButtonY
|
|
||||||
);
|
|
||||||
modButtons[MOD_HARD_ROCK] = new GUIMenuButton(
|
|
||||||
new Image("selection-mod-hardrock.png").getScaledCopy(modScale),
|
|
||||||
modButtonX + modButtonOffsetX, modButtonY
|
|
||||||
);
|
|
||||||
modButtons[MOD_SUDDEN_DEATH] = new GUIMenuButton(
|
|
||||||
new Image("selection-mod-suddendeath.png").getScaledCopy(modScale),
|
|
||||||
modButtonX + (modButtonOffsetX * 2), modButtonY
|
|
||||||
);
|
|
||||||
modButtons[MOD_SPUN_OUT] = new GUIMenuButton(
|
|
||||||
new Image("selection-mod-spunout.png").getScaledCopy(modScale),
|
|
||||||
modButtonX + (modButtonOffsetX * 3), modButtonY
|
|
||||||
);
|
|
||||||
modButtons[MOD_AUTO] = new GUIMenuButton(
|
|
||||||
new Image("selection-mod-autoplay.png").getScaledCopy(modScale),
|
|
||||||
modButtonX + (modButtonOffsetX * 4), modButtonY
|
|
||||||
);
|
|
||||||
for (int i = 0; i < modButtons.length; i++)
|
|
||||||
modButtons[i].getImage().setAlpha(0.5f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -508,8 +457,8 @@ public class Options extends BasicGameState {
|
||||||
|
|
||||||
// game mods
|
// game mods
|
||||||
Utils.FONT_LARGE.drawString(width / 30, height * 0.8f, "Game Mods:", Color.white);
|
Utils.FONT_LARGE.drawString(width / 30, height * 0.8f, "Game Mods:", Color.white);
|
||||||
for (int i = 0; i < modButtons.length; i++)
|
for (GameMod mod : GameMod.values())
|
||||||
modButtons[i].draw();
|
mod.draw();
|
||||||
|
|
||||||
Utils.getBackButton().draw();
|
Utils.getBackButton().draw();
|
||||||
|
|
||||||
|
@ -551,26 +500,11 @@ public class Options extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// game mods
|
// game mods
|
||||||
for (int i = 0; i < modButtons.length; i++) {
|
for (GameMod mod : GameMod.values()) {
|
||||||
if (modButtons[i].contains(x, y)) {
|
if (mod.contains(x, y)) {
|
||||||
boolean prev = modsActive[i];
|
boolean prevState = mod.isActive();
|
||||||
toggleMod(i);
|
mod.toggle(true);
|
||||||
|
if (mod.isActive() != prevState)
|
||||||
// mutually exclusive mods
|
|
||||||
if (modsActive[MOD_AUTO]) {
|
|
||||||
if (i == MOD_AUTO) {
|
|
||||||
if (modsActive[MOD_SPUN_OUT])
|
|
||||||
toggleMod(MOD_SPUN_OUT);
|
|
||||||
if (modsActive[MOD_SUDDEN_DEATH])
|
|
||||||
toggleMod(MOD_SUDDEN_DEATH);
|
|
||||||
} else if (i == MOD_SPUN_OUT || i == MOD_SUDDEN_DEATH) {
|
|
||||||
if (modsActive[i])
|
|
||||||
toggleMod(i);
|
|
||||||
}
|
|
||||||
} else if (modsActive[MOD_SUDDEN_DEATH] && modsActive[MOD_NO_FAIL])
|
|
||||||
toggleMod((i == MOD_SUDDEN_DEATH) ? MOD_NO_FAIL : MOD_SUDDEN_DEATH);
|
|
||||||
|
|
||||||
if (modsActive[i] != prev)
|
|
||||||
SoundController.playSound(SoundController.SOUND_MENUCLICK);
|
SoundController.playSound(SoundController.SOUND_MENUCLICK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -961,30 +895,6 @@ public class Options extends BasicGameState {
|
||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles the active status of a game mod.
|
|
||||||
* Note that this does not perform checks for mutual exclusivity.
|
|
||||||
* @param mod the game mod (MOD_* constants)
|
|
||||||
*/
|
|
||||||
private static void toggleMod(int mod) {
|
|
||||||
modButtons[mod].getImage().setAlpha(modsActive[mod] ? 0.5f : 1.0f);
|
|
||||||
modsActive[mod] = !modsActive[mod];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not a game mod is active.
|
|
||||||
* @param mod the game mod (MOD_* constants)
|
|
||||||
* @return true if the mod is active
|
|
||||||
*/
|
|
||||||
public static boolean isModActive(int mod) { return modsActive[mod]; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the image associated with a game mod.
|
|
||||||
* @param mod the game mod (MOD_* constants)
|
|
||||||
* @return the associated image
|
|
||||||
*/
|
|
||||||
public static Image getModImage(int mod) { return modButtons[mod].getImage(); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the target frame rate.
|
* Returns the target frame rate.
|
||||||
* @return the target FPS
|
* @return the target FPS
|
||||||
|
|
Loading…
Reference in New Issue
Block a user