/* * opsu! - an open-source osu! client * Copyright (C) 2014-2017 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.GameData; import itdelatrisu.opsu.Utils; /** * Health bar. * * @author peppy (ppy/osu-iPhone:OsuAppDelegate.m,OsuFunctions.h) */ public class Health { /** Maximum HP. */ public static final float HP_MAX = 200f; /** HP increase values. */ private static final float HP_50 = 0.4f, HP_100 = 2.2f, HP_300 = 6f, HP_100K = 10f, // 100-Katu HP_300K = 10f, // 300-Katu HP_300G = 14f, // Geki HP_MU = 6f, HP_SLIDER10 = 3f, HP_SLIDER30 = 4f, HP_SPINNERSPIN = 1.7f, HP_SPINNERBONUS = 2f; /** Current health. */ private float health; /** Displayed health (for animation, slightly behind health). */ private float healthDisplay; /** Uncapped health. */ private float healthUncapped; /** The HP drain rate (0:easy ~ 10:hard) */ private float hpDrainRate; /** The normal HP multiplier. */ private float hpMultiplierNormal; /** The combo-end HP multiplier. */ private float hpMultiplierComboEnd; /** Constructor. */ public Health() { reset(); } /** * Sets the health modifiers. * @param hpDrainRate the HP drain rate * @param hpMultiplierNormal the normal HP multiplier * @param hpMultiplierComboEnd the combo-end HP multiplier */ public void setModifiers(float hpDrainRate, float hpMultiplierNormal, float hpMultiplierComboEnd) { this.hpDrainRate = hpDrainRate; this.hpMultiplierNormal = hpMultiplierNormal; this.hpMultiplierComboEnd = hpMultiplierComboEnd; } /** * Updates displayed health based on a delta value. * @param delta the delta interval since the last call */ public void update(int delta) { float multiplier = delta / 32f; if (healthDisplay < health) healthDisplay = Utils.clamp(healthDisplay + (health - healthDisplay) * multiplier, 0f, health); else if (healthDisplay > health) { if (health < 10f) multiplier *= 10f; healthDisplay = Utils.clamp(healthDisplay - (healthDisplay - health) * multiplier, health, HP_MAX); } } /** Returns the current health percentage. */ public float getHealth() { return health / HP_MAX * 100f; } /** Returns the displayed health percentage. */ public float getHealthDisplay() { return healthDisplay / HP_MAX * 100f; } /** Returns the current health value. */ public float getRawHealth() { return health; } /** Returns the current uncapped health value. */ public float getUncappedRawHealth() { return healthUncapped; } /** Sets the current health value. */ public void setHealth(float value) { health = healthUncapped = value; } /** Changes the current health by the given value. */ public void changeHealth(float value) { health = Utils.clamp(health + value, 0f, HP_MAX); healthUncapped += value; } /** * Changes the current health value based on a hit. * @param type the hit type (HIT_* constants) */ public void changeHealthForHit(int type) { switch (type) { case GameData.HIT_MISS: changeHealth(Utils.mapDifficultyRange(hpDrainRate, -6, -25, -40)); break; case GameData.HIT_50: changeHealth(hpMultiplierNormal * Utils.mapDifficultyRange(hpDrainRate, HP_50 * 8, HP_50, HP_50)); break; case GameData.HIT_100: changeHealth(hpMultiplierNormal * Utils.mapDifficultyRange(hpDrainRate, HP_100 * 8, HP_100, HP_100)); break; case GameData.HIT_300: changeHealth(hpMultiplierNormal * HP_300); break; case GameData.HIT_100K: changeHealth(hpMultiplierComboEnd * HP_100K); break; case GameData.HIT_300K: changeHealth(hpMultiplierComboEnd * HP_300K); break; case GameData.HIT_300G: changeHealth(hpMultiplierComboEnd * HP_300G); break; case GameData.HIT_MU: changeHealth(hpMultiplierNormal * HP_MU); break; case GameData.HIT_SLIDER10: changeHealth(hpMultiplierNormal * HP_SLIDER10); break; case GameData.HIT_SLIDER30: changeHealth(hpMultiplierNormal * HP_SLIDER30); break; case GameData.HIT_SPINNERSPIN: changeHealth(hpMultiplierNormal * HP_SPINNERSPIN); break; case GameData.HIT_SPINNERBONUS: changeHealth(hpMultiplierNormal * HP_SPINNERBONUS); break; default: break; } } /** Resets health. */ public void reset() { health = healthDisplay = healthUncapped = HP_MAX; hpDrainRate = 5f; hpMultiplierNormal = hpMultiplierComboEnd = 1f; } }