1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2024-11-09 00:04:42 +00:00

Script-driven stages are done!

This commit is contained in:
Eric Myllyoja 2022-02-25 02:02:06 -05:00
parent c0c1fb482f
commit a0f285e319
5 changed files with 126 additions and 33 deletions

View file

@ -833,6 +833,9 @@ class PlayState extends MusicBeatState
curStage.addCharacter(boyfriend, BF);
curStage.addCharacter(gf, GF);
curStage.addCharacter(dad, DAD);
// Redo z-indexes.
curStage.refresh();
}
else
{
@ -2910,18 +2913,6 @@ class PlayState extends MusicBeatState
startedMoving = false;
}
function lightningStrikeShit():Void
{
FlxG.sound.play(Paths.soundRandom('thunder_', 1, 2));
halloweenBG.animation.play('lightning');
lightningStrikeBeat = curBeat;
lightningOffset = FlxG.random.int(8, 24);
boyfriend.playAnim('scared', true);
gf.playAnim('scared', true);
}
override function stepHit()
{
super.stepHit();
@ -2930,10 +2921,13 @@ class PlayState extends MusicBeatState
{
resyncVocals();
}
}
var lightningStrikeBeat:Int = 0;
var lightningOffset:Int = 8;
if (curStage != null)
{
// We're using Eric's stage handler. The stage should know that a beat has been hit.
curStage.onStepHit(curBeat);
}
}
override function beatHit()
{
@ -3078,10 +3072,11 @@ class PlayState extends MusicBeatState
tankWatchtower.dance();
}
// if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset)
// {
// lightningStrikeShit();
// }
if (curStage != null)
{
// We're using Eric's stage handler. The stage should know that a beat has been hit.
curStage.onBeatHit(curBeat);
}
}
var curLight:Int = 0;

View file

@ -85,6 +85,9 @@ class PolymodHandler
// Parsing rules for various data formats.
parseRules: buildParseRules(),
// Parse hxc files and register the scripted classes in them.
useScriptedClasses: true,
});
if (loadedModList == null)
@ -140,6 +143,7 @@ class PolymodHandler
output.addType("txt", TextFileFormat.LINES);
// Ensure script files have merge support.
output.addType("hscript", TextFileFormat.PLAINTEXT);
output.addType("hxs", TextFileFormat.PLAINTEXT);
// You can specify the format of a specific file, with file extension.
// output.addFile("data/introText.txt", TextFileFormat.LINES)

View file

@ -10,8 +10,8 @@ import modding.IHook;
* In the meantime though, I want to get stages working just with JSON.
* -Eric
*/
// @:hscriptClass
// class ScriptedStage extends Stage implements IHook
// {
// // No body needed for this class, it's magic ;)
// }
@:hscriptClass
class ScriptedStage extends Stage implements IHook
{
// No body needed for this class, it's magic ;)
}

View file

@ -1,6 +1,5 @@
package play.stage;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.group.FlxSpriteGroup;
import flixel.util.FlxSort;
@ -23,7 +22,7 @@ class Stage extends FlxSpriteGroup implements IHook
public var camZoom:Float = 1.0;
var namedProps:Map<String, FlxObject> = new Map<String, FlxObject>();
var namedProps:Map<String, FlxSprite> = new Map<String, FlxSprite>();
var characters:Map<String, Character> = new Map<String, Character>();
/**
@ -55,8 +54,20 @@ class Stage extends FlxSpriteGroup implements IHook
for (dataProp in _data.props)
{
trace(' Placing prop: ${dataProp.name} (${dataProp.assetPath})');
var imagePath = Paths.image(dataProp.assetPath);
var propSprite = new FlxSprite().loadGraphic(imagePath);
var isAnimated = dataProp.animations.length > 0;
var propSprite = new FlxSprite();
if (isAnimated)
{
// Initalize sprite frames.
propSprite.frames = Paths.getSparrowAtlas(dataProp.assetPath);
}
else
{
// Initalize static sprite.
propSprite.loadGraphic(Paths.image(dataProp.assetPath));
}
if (Std.isOfType(dataProp.scale, Array))
{
@ -107,6 +118,36 @@ class Stage extends FlxSpriteGroup implements IHook
sort(SortUtil.byZIndex, FlxSort.ASCENDING);
}
/**
* A function that gets called every frame.
* @param elapsed The number of
*/
public function onUpdate(elapsed:Float):Void
{
// Override me in your scripted stage to perform custom behavior!
}
/**
* A function that gets called once per step in the song.
* @param curStep The current step number.
*/
public function onStepHit(curStep:Int):Void
{
// Override me in your scripted stage to perform custom behavior!
}
/**
* A function that gets called once per beat in the song (once every four steps).
* @param curStep The current beat number.
*/
public function onBeatHit(curBeat:Int):Void
{
// Override me in your scripted stage to perform custom behavior!
}
/**
* Used by the PlayState to add a character to the stage.
*/
public function addCharacter(character:Character, charType:CharacterType)
{
// Apply position and z-index.
@ -135,6 +176,11 @@ class Stage extends FlxSpriteGroup implements IHook
this.add(character);
}
/**
* Retrieves a given character from the stage.
* @param id
* @return Character
*/
public function getCharacter(id:String):Character
{
return this.characters.get(id);
@ -142,17 +188,27 @@ class Stage extends FlxSpriteGroup implements IHook
public function getBoyfriend():Character
{
return this.characters.get("bf");
return getCharacter('bf');
}
public function getGirlfriend():Character
{
return this.characters.get("gf");
return getCharacter('gf');
}
public function getDad():Character
{
return this.characters.get("dad");
return getCharacter('dad');
}
/**
* Retrieve a specific prop by the name assigned in the JSON file.
* @param name The name of the prop to retrieve.
* @return The corresponding FlxSprite.
*/
public function getNamedProp(name:String):FlxSprite
{
return this.namedProps.get(name);
}
public function cleanup()

View file

@ -21,19 +21,57 @@ class StageDataParser
static final stageCache:Map<String, Stage> = new Map<String, Stage>();
static final DEFAULT_STAGE_ID = 'UNKNOWN';
/**
* Parses and preloads the game's stage data and scripts when the game starts.
*
* If you want to force stages to be reloaded, you can just call this function again.
*/
public static function loadStageCache():Void
{
stageCache.clear();
trace("Loading stage cache...");
//
// SCRIPTED STAGES
//
var scriptedStageClassNames:Array<String> = ScriptedStage.listScriptClasses();
trace(' Instantiating ${scriptedStageClassNames.length} scripted stages...');
for (stageCls in scriptedStageClassNames)
{
var stage:Stage = ScriptedStage.init(stageCls, DEFAULT_STAGE_ID);
if (stage != null)
{
trace(' Loaded scripted stage: ${stage.stageName}');
stageCache.set(stage.stageId, stage);
}
else
{
trace(' Failed to instantiate scripted stage class: ${stageCls}');
}
}
//
// UNSCRIPTED STAGES
//
var stageIdList:Array<String> = DataAssets.listDataFilesInPath('stages/');
for (stageId in stageIdList)
var unscriptedStageIds:Array<String> = stageIdList.filter(function(stageId:String):Bool
{
return !stageCache.exists(stageId);
});
trace(' Instantiating ${unscriptedStageIds.length} non-scripted stages...');
for (stageId in unscriptedStageIds)
{
var stage:Stage = new Stage(stageId);
if (stage != null)
{
trace(' Loaded stage data: ${stage.stageName}');
trace(' Loaded stage data: ${stage.stageName}');
stageCache.set(stageId, stage);
}
}
trace(' Successfully loaded ${Lambda.count(stageCache)} stages.');
}