void OsuCircle::onClickEvent(std::vector<OsuBeatmap::CLICK> &clicks) { if (m_bFinished) return; const Vector2 cursorPos = m_beatmap->getCursorPos(); const Vector2 pos = m_beatmap->osuCoords2Pixels(m_vRawPos); const float cursorDelta = (cursorPos - pos).length(); if (cursorDelta < m_beatmap->getHitcircleDiameter()/2.0f) { // note blocking & shake if (m_bBlocked) { m_fShakeAnimation = engine->getTime() + osu_circle_shake_duration.getFloat(); return; // ignore click event completely } const long delta = (long)clicks[0].musicPos - (long)m_iTime; OsuScore::HIT result = OsuGameRules::getHitResult(delta, m_beatmap); if (result != OsuScore::HIT::HIT_NULL) { const float targetDelta = cursorDelta / (m_beatmap->getHitcircleDiameter()/2.0f); const float targetAngle = rad2deg(atan2(cursorPos.y - pos.y, cursorPos.x - pos.x)); m_beatmap->consumeClickEvent(); onHit(result, delta, targetDelta, targetAngle); } } }
void OsuCircle::drawCircle(Graphics *g, OsuSkin *skin, Vector2 pos, float hitcircleDiameter, float numberScale, float overlapScale, int number, int colorCounter, int colorOffset, float approachScale, float alpha, float numberAlpha, bool drawNumber, bool overrideHDApproachCircle) { if (alpha <= 0.0f || !osu_draw_circles.getBool()) return; rainbowNumber = number; rainbowColorCounter = colorCounter; Color comboColor = skin->getComboColorForCounter(colorCounter, colorOffset); comboColor = COLOR(255, (int)(COLOR_GET_Ri(comboColor)*osu_circle_color_saturation.getFloat()), (int)(COLOR_GET_Gi(comboColor)*osu_circle_color_saturation.getFloat()), (int)(COLOR_GET_Bi(comboColor)*osu_circle_color_saturation.getFloat())); // approach circle ///drawApproachCircle(g, skin, pos, comboColor, hitcircleDiameter, approachScale, alpha, modHD, overrideHDApproachCircle); // they are now drawn separately in draw2() // circle const float circleImageScale = hitcircleDiameter / (128.0f * (skin->isHitCircle2x() ? 2.0f : 1.0f)); comboColor = skin->getComboColorForCounter(colorCounter, colorOffset); drawHitCircle(g, skin->getHitCircle(), pos, comboColor, circleImageScale, alpha); // overlay const float circleOverlayImageScale = hitcircleDiameter / skin->getHitCircleOverlay2()->getSizeBaseRaw().x; if (!skin->getHitCircleOverlayAboveNumber()) drawHitCircleOverlay(g, skin->getHitCircleOverlay2(), pos, circleOverlayImageScale, alpha); // number if (drawNumber) drawHitCircleNumber(g, skin, numberScale, overlapScale, pos, number, numberAlpha); // overlay if (skin->getHitCircleOverlayAboveNumber()) drawHitCircleOverlay(g, skin->getHitCircleOverlay2(), pos, circleOverlayImageScale, alpha); }
void OsuCircle::drawApproachCircle(Graphics *g, OsuSkin *skin, Vector2 pos, Color comboColor, float hitcircleDiameter, float approachScale, float alpha, bool modHD, bool overrideHDApproachCircle) { if ((!modHD || overrideHDApproachCircle) && osu_draw_approach_circles.getBool() && !OsuGameRules::osu_mod_mafham.getBool()) { g->setColor(comboColor); if (osu_circle_rainbow.getBool()) { float frequency = 0.3f; float time = engine->getTime()*20; char red1 = std::sin(frequency*time + 0 + rainbowNumber*rainbowColorCounter) * 127 + 128; char green1 = std::sin(frequency*time + 2 + rainbowNumber*rainbowColorCounter) * 127 + 128; char blue1 = std::sin(frequency*time + 4 + rainbowNumber*rainbowColorCounter) * 127 + 128; g->setColor(COLOR(255, red1, green1, blue1)); } g->setAlpha(alpha*osu_approach_circle_alpha_multiplier.getFloat()); if (approachScale > 1.0f) { const float approachCircleImageScale = hitcircleDiameter / (128.0f * (skin->isApproachCircle2x() ? 2.0f : 1.0f)); g->pushTransform(); g->scale(approachCircleImageScale*approachScale, approachCircleImageScale*approachScale); g->translate(pos.x, pos.y); g->drawImage(skin->getApproachCircle()); g->popTransform(); } } }
void OsuCircle::draw(Graphics *g) { OsuHitObject::draw(g); // draw hit animation if (m_fHitAnimation > 0.0f && m_fHitAnimation != 1.0f && !m_beatmap->getOsu()->getModHD()) { float alpha = 1.0f - m_fHitAnimation; float scale = m_fHitAnimation; scale = -scale*(scale-2.0f); // quad out scale const bool drawNumber = m_beatmap->getSkin()->getVersion() > 1.0f ? false : true; g->pushTransform(); g->scale((1.0f+scale*OsuGameRules::osu_circle_fade_out_scale.getFloat()), (1.0f+scale*OsuGameRules::osu_circle_fade_out_scale.getFloat())); { m_beatmap->getSkin()->getHitCircleOverlay2()->setAnimationTimeOffset(!m_beatmap->isInMafhamRenderChunk() ? m_iTime - m_iApproachTime : m_beatmap->getCurMusicPosWithOffsets()); drawCircle(g, m_beatmap, m_vRawPos, m_iComboNumber, m_iColorCounter, m_iColorOffset, 1.0f, alpha, alpha, drawNumber); } g->popTransform(); } if (m_bFinished || (!m_bVisible && !m_bWaiting)) // special case needed for when we are past this objects time, but still within not-miss range, because we still need to draw the object return; // draw circle const bool hd = m_beatmap->getOsu()->getModHD(); Vector2 shakeCorrectedPos = m_vRawPos; if (engine->getTime() < m_fShakeAnimation && !m_beatmap->isInMafhamRenderChunk()) // handle note blocking shaking { float smooth = 1.0f - ((m_fShakeAnimation - engine->getTime()) / osu_circle_shake_duration.getFloat()); // goes from 0 to 1 if (smooth < 0.5f) smooth = smooth / 0.5f; else smooth = (1.0f - smooth) / 0.5f; // (now smooth goes from 0 to 1 to 0 linearly) smooth = -smooth*(smooth-2); // quad out smooth = -smooth*(smooth-2); // quad out twice shakeCorrectedPos.x += std::sin(engine->getTime()*120) * smooth * osu_circle_shake_strength.getFloat(); } m_beatmap->getSkin()->getHitCircleOverlay2()->setAnimationTimeOffset(!m_beatmap->isInMafhamRenderChunk() ? m_iTime - m_iApproachTime : m_beatmap->getCurMusicPosWithOffsets()); drawCircle(g, m_beatmap, shakeCorrectedPos, m_iComboNumber, m_iColorCounter, m_iColorOffset, m_bWaiting && !hd ? 1.0f : m_fApproachScale, m_bWaiting && !hd ? 1.0f : m_fAlpha, m_bWaiting && !hd ? 1.0f : m_fAlpha, true, m_bOverrideHDApproachCircle); }
void OsuCircle::drawApproachCircle(Graphics *g, OsuBeatmapStandard *beatmap, Vector2 rawPos, int number, int colorCounter, int colorOffset, float approachScale, float alpha, bool overrideHDApproachCircle) { rainbowNumber = number; rainbowColorCounter = colorCounter; Color comboColor = beatmap->getSkin()->getComboColorForCounter(colorCounter, colorOffset); comboColor = COLOR(255, (int)(COLOR_GET_Ri(comboColor)*osu_circle_color_saturation.getFloat()), (int)(COLOR_GET_Gi(comboColor)*osu_circle_color_saturation.getFloat()), (int)(COLOR_GET_Bi(comboColor)*osu_circle_color_saturation.getFloat())); drawApproachCircle(g, beatmap->getSkin(), beatmap->osuCoords2Pixels(rawPos), comboColor, beatmap->getHitcircleDiameter(), approachScale, alpha, beatmap->getOsu()->getModHD(), overrideHDApproachCircle); }