Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions source/funkin/data/ClientPrefs.hx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class ClientPrefs

@saveVar public static var quants:Bool = false;

@:saveVar public static var hudStyle:String = 'NightmareVision';

// @saveVar public static var noteSkin:String = 'Vanilla';
@saveVar public static var comboOffset:Array<Int> = [0, 0, 0, 0];

Expand Down
293 changes: 293 additions & 0 deletions source/funkin/game/huds/ClassicHUD.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
package funkin.game.huds;

import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.FlxObject;
import flixel.util.FlxStringUtil;

import funkin.objects.Bar;
import funkin.objects.HealthIcon;


@:access(funkin.states.PlayState)
class ClassicHUD extends BaseHUD
{
var ratingGraphic:FlxSprite;
var ratingNumGroup:FlxTypedGroup<FlxSprite>;

var healthBar:Bar;
var iconP1:HealthIcon;
var iconP2:HealthIcon;
var scoreTxt:FlxText;

var pixelZoom:Float = 6; // idgaf

var ratingPrefix:String = "";
var ratingSuffix:String = '';
var comboPrefix:String = "";

var comboTween:Bool = true;
var _psychStyle = false;

var textDivider = '•';
var showRating:Bool = ClientPrefs.showRatings;
var showRatingNum:Bool = ClientPrefs.showRatings;
var showCombo:Bool = ClientPrefs.showRatings;
var updateIconPos:Bool = true;
var updateIconScale:Bool = true;
var comboOffsets:Null<Array<Int>> = null; // So u can overwrite the users combo offset if needed without messing with clientprefs

// TODO: Make combo shit change for week 6, the ground work is already there so incase someone else wants to come on in and mess w it.
override function init()
{
name = 'CLASSIC';

ratingPrefix = Paths.RATINGS_PREFIX;
comboPrefix = Paths.COMBO_PREFIX;

final healthGraphic = FunkinAssets.exists(Paths.mods('images/${Paths.UI_PREFIX}healthBar')) ? '${Paths.UI_PREFIX}healthBar' : 'UI/healthBar';

healthBar = new Bar(0, FlxG.height * (!ClientPrefs.downScroll ? 0.89 : 0.11), healthGraphic, function() return parent.health, parent.healthBounds.min, parent.healthBounds.max);
healthBar.screenCenter(X);
healthBar.leftToRight = false;
healthBar.scrollFactor.set();
healthBar.visible = !ClientPrefs.hideHud;
healthBar.alphaMultipler = ClientPrefs.healthBarAlpha;

reloadHealthBarColors();
add(healthBar);

iconP1 = new HealthIcon(parent.boyfriend.healthIcon, true);
iconP1.y = healthBar.y - 75;
iconP1.visible = !ClientPrefs.hideHud;
iconP1.alphaMultipler = ClientPrefs.healthBarAlpha;
add(iconP1);

iconP2 = new HealthIcon(parent.dad.healthIcon, false);
iconP2.y = healthBar.y - 75;
iconP2.visible = !ClientPrefs.hideHud;
iconP2.alphaMultipler = ClientPrefs.healthBarAlpha;
add(iconP2);

scoreTxt = new FlxText(healthBar.x + healthBar.width - 190, healthBar.y + 30, 0, "", 20);
scoreTxt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
add(scoreTxt);

ratingGraphic = new FlxSprite();
ratingGraphic.alpha = 0;
add(ratingGraphic);

ratingNumGroup = new FlxTypedGroup();
add(ratingNumGroup);

onUpdateScore(0, 0, 0);

parent.scripts.set('healthBar', healthBar);
parent.scripts.set('iconP1', iconP1);
parent.scripts.set('iconP2', iconP2);
parent.scripts.set('scoreTxt', scoreTxt);
parent.scripts.set('ratingPrefix', ratingPrefix);
parent.scripts.set('ratingSuffix', ratingSuffix);
parent.scripts.set('comboPrefix', comboPrefix);
parent.scripts.set('comboOffsets', comboOffsets);

if (comboOffsets == null)
{
comboOffsets = ClientPrefs.comboOffset;
}
}

override function onUpdateScore(score:Int = 0, accuracy:Float = 0, misses:Int = 0, missed:Bool = false)
{
final tempScore:String = 'Score: ${FlxStringUtil.formatMoney(score, false)}';
scoreTxt.text = '${tempScore}\n';
}

public function updateIconsPosition()
{
if (!updateIconPos) return;

final iconOffset:Int = 26;
if (!healthBar.leftToRight)
{
iconP1.x = healthBar.barCenter + (150 * iconP1.scale.x - 150) / 2 - iconOffset;
iconP2.x = healthBar.barCenter - (150 * iconP2.scale.x) / 2 - iconOffset * 2;
}
else
{
iconP1.x = healthBar.barCenter - (150 * iconP2.scale.x) / 2 - iconOffset * 2;
iconP2.x = healthBar.barCenter + (150 * iconP1.scale.x - 150) / 2 - iconOffset;
}
}

public function updateIconsScale(elapsed:Float)
{
if (!updateIconScale) return;

final mult:Float = MathUtil.decayLerp(iconP1.scale.x, 1, 18, elapsed);
iconP1.scale.set(mult, mult);
iconP1.updateHitbox();

final mult:Float = MathUtil.decayLerp(iconP2.scale.x, 1, 18, elapsed);
iconP2.scale.set(mult, mult);
iconP2.updateHitbox();

iconP1.origin.y = iconP2.origin.y = 0;
}

public function updateIconsAnimation()
{
iconP1.updateIconAnim(healthBar.percent * 0.01);
iconP2.updateIconAnim((100 - healthBar.percent) * 0.01);
}

public function reloadHealthBarColors()
{
var dad = parent.dad;
var boyfriend = parent.boyfriend;
if (!healthBar.leftToRight)
{
healthBar.setColors(0xFFFF0000, 0xFF66FF33);
}
else
{
healthBar.setColors(0xFF66FF33, 0xFFFF0000);
}
}

public function flipBar()
{
healthBar.leftToRight = !healthBar.leftToRight;
iconP1.flipX = !iconP1.flipX;
iconP2.flipX = !iconP2.flipX;
}

override function update(elapsed:Float)
{
super.update(elapsed);

updateIconsPosition();
updateIconsScale(elapsed);
updateIconsAnimation();
}

override function beatHit()
{
if (!updateIconScale) return;

iconP1.scale.set(1.2, 1.2);
iconP2.scale.set(1.2, 1.2);

iconP1.updateHitbox();
iconP2.updateHitbox();
}

override function onCharacterChange()
{
reloadHealthBarColors();
iconP1.changeIcon(parent.boyfriend.healthIcon);
iconP2.changeIcon(parent.dad.healthIcon);
}

override function onHealthChange(health:Float)
{
final newPercent:Null<Float> = FlxMath.remapToRange(FlxMath.bound(healthBar.valueFunction(), healthBar.bounds.min, healthBar.bounds.max), healthBar.bounds.min, healthBar.bounds.max, 0, 100);
healthBar.percent = (newPercent != null ? newPercent : 0);
}

override function popUpScore(daRating:funkin.game.Rating, combo:Int, note:funkin.objects.note.Note)
{
final ratingImage = daRating.image;

final posX = FlxG.width * 0.35;

if (ClientPrefs.hideHud) return;

parent.scripts.call('onPopUpScore', [note, daRating, ratingGraphic, ratingNumGroup]);

if (showRating)
{
FlxTween.cancelTweensOf(ratingGraphic, ['scale.x', 'scale.y', 'alpha']);
ratingGraphic.alpha = 1;
ratingGraphic.loadGraphic(Paths.image(ratingPrefix + ratingImage + ratingSuffix));
ratingGraphic.screenCenter();
ratingGraphic.x = posX - 40;
ratingGraphic.y -= 60;
ratingGraphic.x += comboOffsets[0];
ratingGraphic.y -= comboOffsets[1];

if (comboTween)
{
ratingGraphic.scale.set(0.785, 0.785);
FlxTween.tween(ratingGraphic.scale, {x: 0.7, y: 0.7}, 0.5, {ease: FlxEase.expoOut});
}
ratingGraphic.updateHitbox();
FlxTween.tween(ratingGraphic, {alpha: 0}, 0.5, {startDelay: Conductor.stepCrotchet * 0.01, ease: FlxEase.expoOut});
}

if (showRatingNum)
{
for (i in ratingNumGroup)
{
if (i.alive)
{
i.kill();
}
}

var seperatedScore:Array<Int> = [];

if (combo >= 1000)
{
seperatedScore.push(Math.floor(combo / 1000) % 10);
}
seperatedScore.push(Math.floor(combo / 100) % 10);
seperatedScore.push(Math.floor(combo / 10) % 10);
seperatedScore.push(combo % 10);

var daLoop:Int = 0;
for (i in seperatedScore)
{
var numScore:FlxSprite = ratingNumGroup.recycle(FlxSprite);
FlxTween.cancelTweensOf(numScore);

numScore.loadGraphic(Paths.image(comboPrefix + 'num' + Std.int(i) + ratingSuffix));
numScore.alpha = 1;
numScore.screenCenter();
numScore.x = posX + (43 * daLoop) - 90;
numScore.y += 80;
numScore.x += comboOffsets[2];
numScore.y -= comboOffsets[3];

if (comboTween)
{
numScore.scale.set(0.6, 0.6);
FlxTween.cancelTweensOf(numScore, ['scale.x', 'scale.y']);
FlxTween.tween(numScore.scale, {x: 0.5, y: 0.5}, 0.5, {ease: FlxEase.expoOut});
}
numScore.updateHitbox();
ratingNumGroup.add(numScore);
FlxTween.tween(numScore, {alpha: 0}, 0.5, {startDelay: Conductor.stepCrotchet * 0.01, ease: FlxEase.expoOut});

daLoop++;
}
}

parent.scripts.call('onPopUpScorePost', [note, daRating, ratingGraphic, ratingNumGroup]);
}

override function cachePopUpScore()
{
var ratings = ["sick", "good", "bad", "shit"];
if (ClientPrefs.useEpicRankings) ratings.push('epic');

for (rating in ratings)
{
ratingGraphic.loadGraphic(Paths.image('$ratingPrefix$rating$ratingSuffix'));
}

for (i in 0...10)
{
Paths.image('${comboPrefix}num$i$ratingSuffix');
}
}
}
7 changes: 7 additions & 0 deletions source/funkin/game/huds/PsychHUD.hx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class PsychHUD extends BaseHUD
var comboPrefix:String = "";

var comboTween:Bool = true;
var _psychStyle = false;

var textDivider = '•';
var showRating:Bool = ClientPrefs.showRatings;
Expand All @@ -37,6 +38,12 @@ class PsychHUD extends BaseHUD
var updateIconScale:Bool = true;
var comboOffsets:Null<Array<Int>> = null; // So u can overwrite the users combo offset if needed without messing with clientprefs

public function new(parent, ?psychStyle:Bool = false)
{
super(parent);
_psychStyle = psychStyle;
}

// TODO: Make combo shit change for week 6, the ground work is already there so incase someone else wants to come on in and mess w it.
override function init()
{
Expand Down
14 changes: 13 additions & 1 deletion source/funkin/states/PlayState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ class PlayState extends MusicBeatState
notes = new FlxTypedGroup<Note>();
add(notes);

playHUD = new funkin.game.huds.PsychHUD(this);
playHUD = getHUD();
insert(members.indexOf(playFields), playHUD); // Data told me to do this
playHUD.cameras = [camHUD];

Expand Down Expand Up @@ -920,6 +920,18 @@ class PlayState extends MusicBeatState

var splashLayering:Array<Dynamic> = [];

public function getHUD():BaseHUD
{
final style = ClientPrefs.hudStyle;
switch (style)
{
default:
return new funkin.game.huds.PsychHUD(this, style == 'Psych');
case 'Classic':
return new funkin.game.huds.ClassicHUD(this);
}
}

public function generatePlayfields()
{
if (generatedFields) return;
Expand Down
3 changes: 3 additions & 0 deletions source/funkin/states/options/VisualsUISubState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class VisualsUISubState extends BaseOptionsMenu
var option:Option = new Option('Hide HUD', 'If checked, hides most HUD elements.', 'hideHud', 'bool', false);
addOption(option);

var option:Option = new Option('HUD Style:', "What style should the HUD use?", 'hudStyle', 'string', 'NightmareVision', ['NightmareVision', 'Classic']);
addOption(option);

var option:Option = new Option('Show Ratings', 'If checked, rating graphics will appear on your HUD.', 'showRatings', 'bool', true);
addOption(option);

Expand Down