Added options for global fixed difficulty settings (CS, HP, AR, OD).

- Added a new tab in Game Options screen containing the values.

Other changes:
- Corrected "Hard Rock" difficulty modifiers.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2014-07-05 01:24:01 -04:00
parent 06f8dae037
commit 83f13a8879
3 changed files with 176 additions and 37 deletions

View File

@ -213,7 +213,7 @@ public enum GameImage {
/**
* Returns whether or not the image has been scaled.
*/
public boolean isScaled() { return (skinImage != null) ? false : scaled; }
public boolean isScaled() { return (skinImage != null) ? false : scaled; }
/**
* Sets the scaled status of the image.

View File

@ -810,18 +810,31 @@ public class Game extends BasicGameState {
*/
private void setMapModifiers() {
try {
// map-based properties, so re-initialize each game
// map-based properties, re-initialized each game
float circleSize = osu.circleSize;
float approachRate = osu.approachRate;
float overallDifficulty = osu.overallDifficulty;
float HPDrainRate = osu.HPDrainRate;
if (Options.isModActive(Options.MOD_HARD_ROCK)) { // hard rock modifiers
circleSize = Math.max(circleSize - 1, 0);
approachRate = Math.min(approachRate + 3, 10);
overallDifficulty = Math.min(overallDifficulty + 3, 10);
HPDrainRate = Math.min(HPDrainRate + 3, 10);
// fixed difficulty overrides
if (Options.getFixedCS() > 0f)
circleSize = Options.getFixedCS();
if (Options.getFixedAR() > 0f)
approachRate = Options.getFixedAR();
if (Options.getFixedOD() > 0f)
overallDifficulty = Options.getFixedOD();
if (Options.getFixedHP() > 0f)
HPDrainRate = Options.getFixedHP();
// hard rock modifiers
if (Options.isModActive(Options.MOD_HARD_ROCK)) {
circleSize = Math.min(circleSize * 1.4f, 10);
approachRate = Math.min(approachRate * 1.4f, 10);
overallDifficulty = Math.min(overallDifficulty * 1.4f, 10);
HPDrainRate = Math.min(HPDrainRate * 1.4f, 10);
}
// initialize objects
Circle.init(container, circleSize);
Slider.init(container, circleSize, osu);
Spinner.init(container);

View File

@ -130,7 +130,11 @@ public class Options extends BasicGameState {
SHOW_PERFECT_HIT,
BACKGROUND_DIM,
FORCE_DEFAULT_PLAYFIELD,
IGNORE_BEATMAP_SKINS;
IGNORE_BEATMAP_SKINS,
FIXED_CS,
FIXED_HP,
FIXED_AR,
FIXED_OD;
};
/**
@ -140,7 +144,8 @@ public class Options extends BasicGameState {
TAB_DISPLAY = 0,
TAB_MUSIC = 1,
TAB_GAMEPLAY = 2,
TAB_MAX = 3; // not a tab
TAB_CUSTOM = 3,
TAB_MAX = 4; // not a tab
/**
* Option tab names.
@ -148,7 +153,8 @@ public class Options extends BasicGameState {
private static final String[] TAB_NAMES = {
"Display",
"Music",
"Gameplay"
"Gameplay",
"Custom"
};
/**
@ -196,12 +202,22 @@ public class Options extends BasicGameState {
GameOption.SHOW_PERFECT_HIT
};
/**
* Custom options.
*/
private static final GameOption[] customOptions = {
GameOption.FIXED_CS,
GameOption.FIXED_HP,
GameOption.FIXED_AR,
GameOption.FIXED_OD
};
/**
* Max number of options displayed on one screen.
*/
private static int maxOptionsScreen = Math.max(
Math.max(displayOptions.length, musicOptions.length),
gameplayOptions.length);
Math.max(gameplayOptions.length, customOptions.length));
/**
* Screen resolutions.
@ -318,6 +334,13 @@ public class Options extends BasicGameState {
*/
private static boolean ignoreBeatmapSkins = false;
/**
* Fixed difficulty overrides.
*/
private static float
fixedCS = 0f, fixedHP = 0f,
fixedAR = 0f, fixedOD = 0f;
/**
* Game option coordinate modifiers (for drawing).
*/
@ -351,9 +374,11 @@ public class Options extends BasicGameState {
// option tabs
Image tab = Utils.getTabImage();
int subtextWidth = Utils.FONT_DEFAULT.getWidth("Click or drag an option to change it.");
float tabX = (width / 50) + (tab.getWidth() / 2f);
float tabY = 15 + Utils.FONT_XLARGE.getHeight() + (tab.getHeight() / 2f);
float tabOffset = tab.getWidth() * 0.85f;
float tabOffset = (float) Math.min(tab.getWidth(),
((width - subtextWidth - tab.getWidth()) / 2) / TAB_MAX);
for (int i = 0; i < optionTabs.length; i++)
optionTabs[i] = new GUIMenuButton(tab, tabX + (i * tabOffset), tabY);
@ -424,6 +449,10 @@ public class Options extends BasicGameState {
for (int i = 0; i < gameplayOptions.length; i++)
drawOption(gameplayOptions[i], i);
break;
case TAB_CUSTOM:
for (int i = 0; i < customOptions.length; i++)
drawOption(customOptions[i], i);
break;
}
// option tabs
@ -580,46 +609,72 @@ public class Options extends BasicGameState {
// options (drag only)
switch (getClickedOption(oldy)) {
case MUSIC_VOLUME:
musicVolume += diff;
if (musicVolume < 0)
musicVolume = 0;
else if (musicVolume > 100)
musicVolume = 100;
musicVolume = getBoundedValue(musicVolume, diff, 0, 100);
container.setMusicVolume(getMusicVolume());
break;
case EFFECT_VOLUME:
effectVolume += diff;
if (effectVolume < 0)
effectVolume = 0;
else if (effectVolume > 100)
effectVolume = 100;
effectVolume = getBoundedValue(effectVolume, diff, 0, 100);
break;
case HITSOUND_VOLUME:
hitSoundVolume += diff;
if (hitSoundVolume < 0)
hitSoundVolume = 0;
else if (hitSoundVolume > 100)
hitSoundVolume = 100;
hitSoundVolume = getBoundedValue(hitSoundVolume, diff, 0, 100);
break;
case MUSIC_OFFSET:
musicOffset += diff;
if (musicOffset < -500)
musicOffset = -500;
else if (musicOffset > 500)
musicOffset = 500;
musicOffset = getBoundedValue(musicOffset, diff, -500, 500);
break;
case BACKGROUND_DIM:
backgroundDim += diff;
if (backgroundDim < 0)
backgroundDim = 0;
else if (backgroundDim > 100)
backgroundDim = 100;
backgroundDim = getBoundedValue(backgroundDim, diff, 0, 100);
break;
case FIXED_CS:
fixedCS = getBoundedValue(fixedCS, diff / 10f, 0f, 10f);
break;
case FIXED_HP:
fixedHP = getBoundedValue(fixedHP, diff / 10f, 0f, 10f);
break;
case FIXED_AR:
fixedAR = getBoundedValue(fixedAR, diff / 10f, 0f, 10f);
break;
case FIXED_OD:
fixedOD = getBoundedValue(fixedOD, diff / 10f, 0f, 10f);
break;
default:
break;
}
}
/**
* Returns a bounded value for when an option is dragged.
* @param var the initial value
* @param diff the value change
* @param min the minimum value
* @param max the maximum value
* @return the bounded value
*/
private int getBoundedValue(int var, int diff, int min, int max) {
int val = var + diff;
if (val < min)
val = min;
else if (val > max)
val = max;
return val;
}
/**
* Returns a bounded value for when an option is dragged.
* @param var the initial value
* @param diff the value change
* @param min the minimum value
* @param max the maximum value
* @return the bounded value
*/
private float getBoundedValue(float var, float diff, float min, float max) {
float val = var + diff;
if (val < min)
val = min;
else if (val > max)
val = max;
return val;
}
@Override
public void keyPressed(int key, char c) {
switch (key) {
@ -755,6 +810,30 @@ public class Options extends BasicGameState {
"Whether to show perfect hit result bursts (300s, slider ticks)."
);
break;
case FIXED_CS:
drawOption(pos, "Fixed Circle Size (CS)",
(fixedCS == 0f) ? "Disabled" : String.format("%.1f", fixedCS),
"Determines the size of circles and sliders."
);
break;
case FIXED_HP:
drawOption(pos, "Fixed HP Drain Rate (HP)",
(fixedHP == 0f) ? "Disabled" : String.format("%.1f", fixedHP),
"Determines the rate at which health decreases."
);
break;
case FIXED_AR:
drawOption(pos, "Fixed Approach Rate (AR)",
(fixedAR == 0f) ? "Disabled" : String.format("%.1f", fixedAR),
"Determines how long hit circles stay on the screen."
);
break;
case FIXED_OD:
drawOption(pos, "Fixed Overall Difficulty (OD)",
(fixedOD == 0f) ? "Disabled" : String.format("%.1f", fixedOD),
"Determines the time window for hit results."
);
break;
default:
break;
}
@ -806,6 +885,9 @@ public class Options extends BasicGameState {
if (index < gameplayOptions.length)
option = gameplayOptions[index];
break;
case TAB_CUSTOM:
if (index < customOptions.length)
option = customOptions[index];
}
return option;
}
@ -942,6 +1024,30 @@ public class Options extends BasicGameState {
*/
public static boolean isBeatmapSkinIgnored() { return ignoreBeatmapSkins; }
/**
* Returns the fixed circle size override, if any.
* @return the CS value (0, 10], 0 if disabled
*/
public static float getFixedCS() { return fixedCS; }
/**
* Returns the fixed HP drain rate override, if any.
* @return the HP value (0, 10], 0 if disabled
*/
public static float getFixedHP() { return fixedHP; }
/**
* Returns the fixed approach rate override, if any.
* @return the AR value (0, 10], 0 if disabled
*/
public static float getFixedAR() { return fixedAR; }
/**
* Returns the fixed overall difficulty override, if any.
* @return the OD value (0, 10], 0 if disabled
*/
public static float getFixedOD() { return fixedOD; }
/**
* Returns the current beatmap directory.
* If invalid, this will attempt to search for the directory,
@ -1078,6 +1184,18 @@ public class Options extends BasicGameState {
case "PerfectHit":
showPerfectHit = Boolean.parseBoolean(value);
break;
case "FixedCS":
fixedCS = Float.parseFloat(value);
break;
case "FixedHP":
fixedHP = Float.parseFloat(value);
break;
case "FixedAR":
fixedAR = Float.parseFloat(value);
break;
case "FixedOD":
fixedOD = Float.parseFloat(value);
break;
}
}
} catch (IOException e) {
@ -1145,6 +1263,14 @@ public class Options extends BasicGameState {
writer.newLine();
writer.write(String.format("PerfectHit = %b", showPerfectHit));
writer.newLine();
writer.write(String.format("FixedCS = %.1f", fixedCS));
writer.newLine();
writer.write(String.format("FixedHP = %.1f", fixedHP));
writer.newLine();
writer.write(String.format("FixedAR = %.1f", fixedAR));
writer.newLine();
writer.write(String.format("FixedOD = %.1f", fixedOD));
writer.newLine();
writer.close();
} catch (IOException e) {
Log.error(String.format("Failed to write to file '%s'.", OPTIONS_FILE.getAbsolutePath()), e);