Bunch of changes to NoteScriptEvent and death logic

This commit is contained in:
EliteMasterEric 2024-02-15 17:25:28 -05:00
parent 04b73dac9f
commit 5ec0939263
5 changed files with 55 additions and 23 deletions

View file

@ -106,12 +106,19 @@ class NoteScriptEvent extends ScriptEvent
*/ */
public var playSound(default, default):Bool; public var playSound(default, default):Bool;
/**
* A multiplier to the health gained or lost from this note.
* This affects both hits and misses. Remember that max health is 2.00.
*/
public var healthMulti:Float;
public function new(type:ScriptEventType, note:NoteSprite, comboCount:Int = 0, cancelable:Bool = false):Void public function new(type:ScriptEventType, note:NoteSprite, comboCount:Int = 0, cancelable:Bool = false):Void
{ {
super(type, cancelable); super(type, cancelable);
this.note = note; this.note = note;
this.comboCount = comboCount; this.comboCount = comboCount;
this.playSound = true; this.playSound = true;
this.healthMulti = 1.0;
} }
public override function toString():String public override function toString():String

View file

@ -4,16 +4,17 @@ import flixel.FlxG;
import flixel.FlxObject; import flixel.FlxObject;
import flixel.FlxSprite; import flixel.FlxSprite;
import flixel.sound.FlxSound; import flixel.sound.FlxSound;
import funkin.ui.story.StoryMenuState;
import flixel.util.FlxColor; import flixel.util.FlxColor;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
import funkin.graphics.FunkinSprite; import funkin.graphics.FunkinSprite;
import funkin.ui.MusicBeatSubState;
import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEvent;
import funkin.modding.events.ScriptEventDispatcher; import funkin.modding.events.ScriptEventDispatcher;
import funkin.play.character.BaseCharacter;
import funkin.play.PlayState; import funkin.play.PlayState;
import funkin.ui.freeplay.FreeplayState; import funkin.ui.freeplay.FreeplayState;
import funkin.play.character.BaseCharacter; import funkin.ui.MusicBeatSubState;
import funkin.ui.story.StoryMenuState;
import openfl.utils.Assets;
/** /**
* A substate which renders over the PlayState when the player dies. * A substate which renders over the PlayState when the player dies.
@ -148,6 +149,12 @@ class GameOverSubState extends MusicBeatSubState
Conductor.instance.update(0); Conductor.instance.update(0);
} }
public function resetCameraZoom():Void
{
// Apply camera zoom level from stage data.
FlxG.camera.zoom = PlayState?.instance?.currentStage?.camZoom ?? 1.0;
}
var hasStartedAnimation:Bool = false; var hasStartedAnimation:Bool = false;
override function update(elapsed:Float) override function update(elapsed:Float)
@ -295,7 +302,7 @@ class GameOverSubState extends MusicBeatSubState
* Starts the death music at the appropriate volume. * Starts the death music at the appropriate volume.
* @param startingVolume * @param startingVolume
*/ */
function startDeathMusic(?startingVolume:Float = 1, force:Bool = false):Void public function startDeathMusic(?startingVolume:Float = 1, force:Bool = false):Void
{ {
var musicPath = Paths.music('gameplay/gameover/gameOver' + musicSuffix); var musicPath = Paths.music('gameplay/gameover/gameOver' + musicSuffix);
if (isEnding) if (isEnding)
@ -320,7 +327,14 @@ class GameOverSubState extends MusicBeatSubState
public static function playBlueBalledSFX() public static function playBlueBalledSFX()
{ {
blueballed = true; blueballed = true;
FlxG.sound.play(Paths.sound('gameplay/gameover/fnf_loss_sfx' + blueBallSuffix)); if (Assets.exists(Paths.sound('gameplay/gameover/fnf_loss_sfx' + blueBallSuffix)))
{
FlxG.sound.play(Paths.sound('gameplay/gameover/fnf_loss_sfx' + blueBallSuffix));
}
else
{
FlxG.log.error('Missing blue ball sound effect: ' + Paths.sound('gameplay/gameover/fnf_loss_sfx' + blueBallSuffix));
}
} }
var playingJeffQuote:Bool = false; var playingJeffQuote:Bool = false;

View file

@ -903,6 +903,7 @@ class PlayState extends MusicBeatSubState
{ {
FlxG.watch.addQuick('bfAnim', currentStage.getBoyfriend().getCurrentAnimation()); FlxG.watch.addQuick('bfAnim', currentStage.getBoyfriend().getCurrentAnimation());
} }
FlxG.watch.addQuick('health', health);
// TODO: Add a song event for Handle GF dance speed. // TODO: Add a song event for Handle GF dance speed.
@ -1390,8 +1391,7 @@ class PlayState extends MusicBeatSubState
var event:ScriptEvent = new ScriptEvent(CREATE, false); var event:ScriptEvent = new ScriptEvent(CREATE, false);
ScriptEventDispatcher.callEvent(currentStage, event); ScriptEventDispatcher.callEvent(currentStage, event);
// Apply camera zoom level from stage data. resetCameraZoom();
defaultCameraZoom = currentStage.camZoom;
// Add the stage to the scene. // Add the stage to the scene.
this.add(currentStage); this.add(currentStage);
@ -1407,6 +1407,12 @@ class PlayState extends MusicBeatSubState
} }
} }
public function resetCameraZoom():Void
{
// Apply camera zoom level from stage data.
defaultCameraZoom = currentStage.camZoom;
}
/** /**
* Generates the character sprites and adds them to the stage. * Generates the character sprites and adds them to the stage.
*/ */
@ -1960,7 +1966,7 @@ class PlayState extends MusicBeatSubState
// Judge the miss. // Judge the miss.
// NOTE: This is what handles the scoring. // NOTE: This is what handles the scoring.
trace('Missed note! ${note.noteData}'); trace('Missed note! ${note.noteData}');
onNoteMiss(note); onNoteMiss(note, event.playSound, event.healthMulti);
note.handledMiss = true; note.handledMiss = true;
} }
@ -2111,7 +2117,7 @@ class PlayState extends MusicBeatSubState
// Calling event.cancelEvent() skips all the other logic! Neat! // Calling event.cancelEvent() skips all the other logic! Neat!
if (event.eventCanceled) return; if (event.eventCanceled) return;
popUpScore(note, input); popUpScore(note, input, event.healthMulti);
if (note.isHoldNote && note.holdNoteSprite != null) if (note.isHoldNote && note.holdNoteSprite != null)
{ {
@ -2125,15 +2131,11 @@ class PlayState extends MusicBeatSubState
* Called when a note leaves the screen and is considered missed by the player. * Called when a note leaves the screen and is considered missed by the player.
* @param note * @param note
*/ */
function onNoteMiss(note:NoteSprite):Void function onNoteMiss(note:NoteSprite, playSound:Bool = false, healthLossMulti:Float = 1.0):Void
{ {
// a MISS is when you let a note scroll past you!! // If we are here, we already CALLED the onNoteMiss script hook!
var event:NoteScriptEvent = new NoteScriptEvent(NOTE_MISS, note, Highscore.tallies.combo, true);
dispatchEvent(event);
// Calling event.cancelEvent() skips all the other logic! Neat!
if (event.eventCanceled) return;
health -= Constants.HEALTH_MISS_PENALTY; health -= Constants.HEALTH_MISS_PENALTY * healthLossMulti;
songScore -= 10; songScore -= 10;
if (!isPracticeMode) if (!isPracticeMode)
@ -2183,7 +2185,7 @@ class PlayState extends MusicBeatSubState
Highscore.tallies.combo = comboPopUps.displayCombo(0); Highscore.tallies.combo = comboPopUps.displayCombo(0);
} }
if (event.playSound) if (playSound)
{ {
vocals.playerVolume = 0; vocals.playerVolume = 0;
FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2));
@ -2310,7 +2312,7 @@ class PlayState extends MusicBeatSubState
/** /**
* Handles health, score, and rating popups when a note is hit. * Handles health, score, and rating popups when a note is hit.
*/ */
function popUpScore(daNote:NoteSprite, input:PreciseInputEvent):Void function popUpScore(daNote:NoteSprite, input:PreciseInputEvent, healthGainMulti:Float = 1.0):Void
{ {
vocals.playerVolume = 1; vocals.playerVolume = 1;
@ -2341,19 +2343,19 @@ class PlayState extends MusicBeatSubState
{ {
case 'sick': case 'sick':
Highscore.tallies.sick += 1; Highscore.tallies.sick += 1;
health += Constants.HEALTH_SICK_BONUS; health += Constants.HEALTH_SICK_BONUS * healthGainMulti;
isComboBreak = Constants.JUDGEMENT_SICK_COMBO_BREAK; isComboBreak = Constants.JUDGEMENT_SICK_COMBO_BREAK;
case 'good': case 'good':
Highscore.tallies.good += 1; Highscore.tallies.good += 1;
health += Constants.HEALTH_GOOD_BONUS; health += Constants.HEALTH_GOOD_BONUS * healthGainMulti;
isComboBreak = Constants.JUDGEMENT_GOOD_COMBO_BREAK; isComboBreak = Constants.JUDGEMENT_GOOD_COMBO_BREAK;
case 'bad': case 'bad':
Highscore.tallies.bad += 1; Highscore.tallies.bad += 1;
health += Constants.HEALTH_BAD_BONUS; health += Constants.HEALTH_BAD_BONUS * healthGainMulti;
isComboBreak = Constants.JUDGEMENT_BAD_COMBO_BREAK; isComboBreak = Constants.JUDGEMENT_BAD_COMBO_BREAK;
case 'shit': case 'shit':
Highscore.tallies.shit += 1; Highscore.tallies.shit += 1;
health += Constants.HEALTH_SHIT_BONUS; health += Constants.HEALTH_SHIT_BONUS * healthGainMulti;
isComboBreak = Constants.JUDGEMENT_SHIT_COMBO_BREAK; isComboBreak = Constants.JUDGEMENT_SHIT_COMBO_BREAK;
} }

View file

@ -305,9 +305,15 @@ class CharacterDataParser
icon = "darnell"; icon = "darnell";
case "senpai-angry": case "senpai-angry":
icon = "senpai"; icon = "senpai";
case "tankman" | "tankman-atlas":
icon = "tankmen";
} }
return Paths.image("freeplay/icons/" + icon + "pixel"); var path = Paths.image("freeplay/icons/" + icon + "pixel");
if (Assets.exists(path)) return path;
// TODO: Hardcode some additional behavior or a fallback.
return null;
} }
/** /**

View file

@ -397,15 +397,18 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements
this.characters.set('bf', character); this.characters.set('bf', character);
charData = _data.characters.bf; charData = _data.characters.bf;
character.flipX = !character.getDataFlipX(); character.flipX = !character.getDataFlipX();
character.name = 'bf';
character.initHealthIcon(false); character.initHealthIcon(false);
case GF: case GF:
this.characters.set('gf', character); this.characters.set('gf', character);
charData = _data.characters.gf; charData = _data.characters.gf;
character.flipX = character.getDataFlipX(); character.flipX = character.getDataFlipX();
character.name = 'gf';
case DAD: case DAD:
this.characters.set('dad', character); this.characters.set('dad', character);
charData = _data.characters.dad; charData = _data.characters.dad;
character.flipX = character.getDataFlipX(); character.flipX = character.getDataFlipX();
character.name = 'dad';
character.initHealthIcon(true); character.initHealthIcon(true);
default: default:
this.characters.set(character.characterId, character); this.characters.set(character.characterId, character);