mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-04-11 06:45:06 +00:00
Scripted stages are done (weeks 1-7)
This commit is contained in:
parent
d50a82cdf6
commit
b19478cd1e
10
.vscode/launch.json
vendored
10
.vscode/launch.json
vendored
|
@ -1,16 +1,6 @@
|
||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
|
||||||
// Launch in browser
|
|
||||||
"name": "HTML5 Debug",
|
|
||||||
"type": "chrome",
|
|
||||||
"request": "launch",
|
|
||||||
"url": "http://127.0.0.1:3001",
|
|
||||||
"sourceMaps": true,
|
|
||||||
"webRoot": "${workspaceFolder}",
|
|
||||||
"preLaunchTask": "debug: html"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
// Launch in native/CPP
|
// Launch in native/CPP
|
||||||
"name": "Lime",
|
"name": "Lime",
|
||||||
|
|
|
@ -125,7 +125,7 @@
|
||||||
<haxelib name="flixel-ui" />
|
<haxelib name="flixel-ui" />
|
||||||
<!--haxelib name="newgrounds" unless="switch"/> -->
|
<!--haxelib name="newgrounds" unless="switch"/> -->
|
||||||
<haxelib name="faxe" if='switch'/>
|
<haxelib name="faxe" if='switch'/>
|
||||||
<haxelib name="polymod" if="desktop"/>
|
<haxelib name="polymod" />
|
||||||
<haxelib name="firetongue" />
|
<haxelib name="firetongue" />
|
||||||
|
|
||||||
<!-- <haxelib name="colyseus"/> -->
|
<!-- <haxelib name="colyseus"/> -->
|
||||||
|
@ -184,8 +184,9 @@
|
||||||
<!--Enable this for Nape release builds for a serious peformance improvement-->
|
<!--Enable this for Nape release builds for a serious peformance improvement-->
|
||||||
<haxedef name="NAPE_RELEASE_BUILD" unless="debug" />
|
<haxedef name="NAPE_RELEASE_BUILD" unless="debug" />
|
||||||
|
|
||||||
<haxeflag name="--no-traces" unless="debug" />
|
<haxeflag name="-no-traces" unless="debug" />
|
||||||
<haxeflag name="--dce full" if="release" />
|
<!-- HScript relies heavily on Reflection, which means we can't use DCE. -->
|
||||||
|
<haxeflag name="--dce no" />
|
||||||
<haxedef name="HXCPP_CHECK_POINTER" />
|
<haxedef name="HXCPP_CHECK_POINTER" />
|
||||||
<haxedef name="HXCPP_STACK_LINE" />
|
<haxedef name="HXCPP_STACK_LINE" />
|
||||||
|
|
||||||
|
@ -203,6 +204,7 @@
|
||||||
took me a while to get this working but turns out the classname comes SECOND
|
took me a while to get this working but turns out the classname comes SECOND
|
||||||
-->
|
-->
|
||||||
<haxeflag name="--macro" value="addMetadata('@:build(util.macro.FlxMacro.buildFlxBasic())', 'flixel.FlxBasic')" />
|
<haxeflag name="--macro" value="addMetadata('@:build(util.macro.FlxMacro.buildFlxBasic())', 'flixel.FlxBasic')" />
|
||||||
|
<haxeflag name="--macro" value="include('modding.base')" />
|
||||||
|
|
||||||
<!-- <haxedef name="SKIP_TO_PLAYSTATE" if="debug" /> -->
|
<!-- <haxedef name="SKIP_TO_PLAYSTATE" if="debug" /> -->
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package;
|
package;
|
||||||
|
|
||||||
|
import Note.NoteData;
|
||||||
|
import SongLoad.SwagSong;
|
||||||
import Section.SwagSection;
|
import Section.SwagSection;
|
||||||
import flixel.FlxSprite;
|
import flixel.FlxSprite;
|
||||||
import flixel.animation.FlxBaseAnimation;
|
import flixel.animation.FlxBaseAnimation;
|
||||||
|
@ -19,7 +21,7 @@ class Character extends FlxSprite
|
||||||
|
|
||||||
public var holdTimer:Float = 0;
|
public var holdTimer:Float = 0;
|
||||||
|
|
||||||
public var animationNotes:Array<Dynamic> = [];
|
public var animationNotes:Array<NoteData> = [];
|
||||||
|
|
||||||
public function new(x:Float, y:Float, ?character:String = "bf", ?isPlayer:Bool = false)
|
public function new(x:Float, y:Float, ?character:String = "bf", ?isPlayer:Bool = false)
|
||||||
{
|
{
|
||||||
|
@ -584,27 +586,25 @@ class Character extends FlxSprite
|
||||||
|
|
||||||
public function loadMappedAnims()
|
public function loadMappedAnims()
|
||||||
{
|
{
|
||||||
var swagshit = SongLoad.loadFromJson('picospeaker', 'stress');
|
var swagshit:SwagSong = SongLoad.loadFromJson('stress', 'stress');
|
||||||
|
|
||||||
var notes = swagshit.extraNotes.get('picospeaker');
|
var notes:Array<SwagSection> = swagshit.noteMap.get('picospeaker');
|
||||||
|
|
||||||
for (section in notes)
|
for (section in notes)
|
||||||
{
|
{
|
||||||
for (idk in section.sectionNotes)
|
for (noteData in section.sectionNotes)
|
||||||
{
|
{
|
||||||
animationNotes.push(idk);
|
animationNotes.push(noteData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TankmenBG.animationNotes = animationNotes;
|
|
||||||
|
|
||||||
trace(animationNotes);
|
trace(animationNotes);
|
||||||
animationNotes.sort(sortAnims);
|
animationNotes.sort(sortAnims);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortAnims(val1:Array<Dynamic>, val2:Array<Dynamic>):Int
|
function sortAnims(val1:NoteData, val2:NoteData):Int
|
||||||
{
|
{
|
||||||
return FlxSort.byValues(FlxSort.ASCENDING, val1[0], val2[0]);
|
return FlxSort.byValues(FlxSort.ASCENDING, val1.strumTime, val2.strumTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
function quickAnimAdd(name:String, prefix:String)
|
function quickAnimAdd(name:String, prefix:String)
|
||||||
|
@ -659,13 +659,13 @@ class Character extends FlxSprite
|
||||||
// for pico??
|
// for pico??
|
||||||
if (animationNotes.length > 0)
|
if (animationNotes.length > 0)
|
||||||
{
|
{
|
||||||
if (Conductor.songPosition > animationNotes[0][0])
|
if (Conductor.songPosition > animationNotes[0].strumTime)
|
||||||
{
|
{
|
||||||
trace('played shoot anim' + animationNotes[0][1]);
|
trace('played shoot anim' + animationNotes[0].noteData);
|
||||||
|
|
||||||
var shootAnim:Int = 1;
|
var shootAnim:Int = 1;
|
||||||
|
|
||||||
if (animationNotes[0][1] >= 2)
|
if ((cast animationNotes[0].noteData) >= 2)
|
||||||
shootAnim = 3;
|
shootAnim = 3;
|
||||||
|
|
||||||
shootAnim += FlxG.random.int(0, 1);
|
shootAnim += FlxG.random.int(0, 1);
|
||||||
|
|
|
@ -98,9 +98,11 @@ class Main extends Sprite
|
||||||
#if debug
|
#if debug
|
||||||
fpsCounter = new FPS(10, 3, 0xFFFFFF);
|
fpsCounter = new FPS(10, 3, 0xFFFFFF);
|
||||||
addChild(fpsCounter);
|
addChild(fpsCounter);
|
||||||
|
#if !html5
|
||||||
memoryCounter = new MemoryCounter(10, 13, 0xFFFFFF);
|
memoryCounter = new MemoryCounter(10, 13, 0xFFFFFF);
|
||||||
addChild(memoryCounter);
|
addChild(memoryCounter);
|
||||||
#end
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
video = new Video();
|
video = new Video();
|
||||||
|
|
|
@ -10,9 +10,7 @@ import ui.PreferencesMenu;
|
||||||
|
|
||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
#if polymod
|
|
||||||
import polymod.format.ParseRules.TargetSignatureElement;
|
import polymod.format.ParseRules.TargetSignatureElement;
|
||||||
#end
|
|
||||||
|
|
||||||
class Note extends FlxSprite
|
class Note extends FlxSprite
|
||||||
{
|
{
|
||||||
|
|
|
@ -111,8 +111,6 @@ class PlayState extends MusicBeatState
|
||||||
|
|
||||||
var foregroundSprites:FlxTypedGroup<BGSprite>;
|
var foregroundSprites:FlxTypedGroup<BGSprite>;
|
||||||
|
|
||||||
var tankmanRun:FlxTypedGroup<TankmenBG>;
|
|
||||||
|
|
||||||
var talking:Bool = true;
|
var talking:Bool = true;
|
||||||
var songScore:Int = 0;
|
var songScore:Int = 0;
|
||||||
var scoreTxt:FlxText;
|
var scoreTxt:FlxText;
|
||||||
|
@ -429,13 +427,13 @@ class PlayState extends MusicBeatState
|
||||||
|
|
||||||
switch (curStageId)
|
switch (curStageId)
|
||||||
{
|
{
|
||||||
case 'limo':
|
case 'limoRide':
|
||||||
gfVersion = 'gf-car';
|
gfVersion = 'gf-car';
|
||||||
case 'mall' | 'mallEvil':
|
case 'mallXmas' | 'mallEvil':
|
||||||
gfVersion = 'gf-christmas';
|
gfVersion = 'gf-christmas';
|
||||||
case 'school' | 'schoolEvil':
|
case 'school' | 'schoolEvil':
|
||||||
gfVersion = 'gf-pixel';
|
gfVersion = 'gf-pixel';
|
||||||
case 'tank':
|
case 'tankmanBattlefield':
|
||||||
gfVersion = 'gf-tankmen';
|
gfVersion = 'gf-tankmen';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,23 +453,6 @@ class PlayState extends MusicBeatState
|
||||||
case 'pico-speaker':
|
case 'pico-speaker':
|
||||||
gf.x -= 50;
|
gf.x -= 50;
|
||||||
gf.y -= 200;
|
gf.y -= 200;
|
||||||
|
|
||||||
var tempTankman:TankmenBG = new TankmenBG(20, 500, true);
|
|
||||||
tempTankman.strumTime = 10;
|
|
||||||
tempTankman.resetShit(20, 600, true);
|
|
||||||
tankmanRun.add(tempTankman);
|
|
||||||
|
|
||||||
for (i in 0...TankmenBG.animationNotes.length)
|
|
||||||
{
|
|
||||||
if (FlxG.random.bool(16))
|
|
||||||
{
|
|
||||||
var tankman:TankmenBG = tankmanRun.recycle(TankmenBG);
|
|
||||||
// new TankmenBG(500, 200 + FlxG.random.int(50, 100), TankmenBG.animationNotes[i][1] < 2);
|
|
||||||
tankman.strumTime = TankmenBG.animationNotes[i][0];
|
|
||||||
tankman.resetShit(500, 200 + FlxG.random.int(50, 100), TankmenBG.animationNotes[i][1] < 2);
|
|
||||||
tankmanRun.add(tankman);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dad = new Character(100, 100, SONG.player2);
|
dad = new Character(100, 100, SONG.player2);
|
||||||
|
@ -2020,7 +2001,11 @@ class PlayState extends MusicBeatState
|
||||||
curStage.onNoteMiss(daNote);
|
curStage.onNoteMiss(daNote);
|
||||||
}
|
}
|
||||||
health -= 0.0775;
|
health -= 0.0775;
|
||||||
|
// Practice mode doesn't mute the vocals on miss.
|
||||||
|
if (!practiceMode)
|
||||||
|
{
|
||||||
vocals.volume = 0;
|
vocals.volume = 0;
|
||||||
|
}
|
||||||
killCombo();
|
killCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2512,8 +2497,12 @@ class PlayState extends MusicBeatState
|
||||||
if (!practiceMode)
|
if (!practiceMode)
|
||||||
songScore -= 10;
|
songScore -= 10;
|
||||||
|
|
||||||
|
// Practice mode doesn't mute the vocals on miss.
|
||||||
|
if (!practiceMode)
|
||||||
|
{
|
||||||
vocals.volume = 0;
|
vocals.volume = 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));
|
||||||
|
}
|
||||||
|
|
||||||
/* boyfriend.stunned = true;
|
/* boyfriend.stunned = true;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ class StoryMenuState extends MusicBeatState
|
||||||
{
|
{
|
||||||
var scoreText:FlxText;
|
var scoreText:FlxText;
|
||||||
|
|
||||||
var weekData:Array<Dynamic> = [
|
var weekData:Array<Array<String>> = [
|
||||||
['Tutorial'],
|
['Tutorial'],
|
||||||
['Bopeebo', 'Fresh', 'Dadbattle'],
|
['Bopeebo', 'Fresh', 'Dadbattle'],
|
||||||
['Spookeez', 'South', "Monster"],
|
['Spookeez', 'South', "Monster"],
|
||||||
|
@ -430,11 +430,10 @@ class StoryMenuState extends MusicBeatState
|
||||||
// grpWeekCharacters.members[0].updateHitbox();
|
// grpWeekCharacters.members[0].updateHitbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
var stringThing:Array<String> = weekData[curWeek];
|
var trackNames:Array<String> = weekData[curWeek];
|
||||||
|
for (i in trackNames)
|
||||||
for (i in stringThing)
|
|
||||||
{
|
{
|
||||||
txtTracklist.text += "\n" + i;
|
txtTracklist.text += '\n${i}';
|
||||||
}
|
}
|
||||||
|
|
||||||
txtTracklist.text = txtTracklist.text.toUpperCase();
|
txtTracklist.text = txtTracklist.text.toUpperCase();
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
package;
|
|
||||||
|
|
||||||
import flixel.FlxSprite;
|
|
||||||
import haxe.display.Display.Package;
|
|
||||||
|
|
||||||
class TankmenBG extends FlxSprite
|
|
||||||
{
|
|
||||||
public static var animationNotes:Array<Dynamic> = [];
|
|
||||||
|
|
||||||
public var strumTime:Float = 0;
|
|
||||||
public var goingRight:Bool = false;
|
|
||||||
public var tankSpeed:Float = 0.7;
|
|
||||||
|
|
||||||
public var endingOffset:Float;
|
|
||||||
|
|
||||||
public function new(x:Float, y:Float, isGoingRight:Bool)
|
|
||||||
{
|
|
||||||
super(x, y);
|
|
||||||
|
|
||||||
// makeGraphic(200, 200);
|
|
||||||
|
|
||||||
frames = Paths.getSparrowAtlas('tankmanKilled1');
|
|
||||||
antialiasing = true;
|
|
||||||
animation.addByPrefix('run', 'tankman running', 24, true);
|
|
||||||
animation.addByPrefix('shot', 'John Shot ' + FlxG.random.int(1, 2), 24, false);
|
|
||||||
|
|
||||||
animation.play('run');
|
|
||||||
animation.curAnim.curFrame = FlxG.random.int(0, animation.curAnim.numFrames - 1);
|
|
||||||
|
|
||||||
updateHitbox();
|
|
||||||
|
|
||||||
setGraphicSize(Std.int(width * 0.8));
|
|
||||||
updateHitbox();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resetShit(x:Float, y:Float, isGoingRight:Bool)
|
|
||||||
{
|
|
||||||
setPosition(x, y);
|
|
||||||
goingRight = isGoingRight;
|
|
||||||
endingOffset = FlxG.random.float(50, 200);
|
|
||||||
tankSpeed = FlxG.random.float(0.6, 1);
|
|
||||||
|
|
||||||
if (goingRight)
|
|
||||||
flipX = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
override function update(elapsed:Float)
|
|
||||||
{
|
|
||||||
super.update(elapsed);
|
|
||||||
|
|
||||||
if (x >= FlxG.width * 1.2 || x <= FlxG.width * -0.5)
|
|
||||||
visible = false;
|
|
||||||
else
|
|
||||||
visible = true;
|
|
||||||
|
|
||||||
if (animation.curAnim.name == 'run')
|
|
||||||
{
|
|
||||||
var endDirection:Float = (FlxG.width * 0.74) + endingOffset;
|
|
||||||
|
|
||||||
if (goingRight)
|
|
||||||
{
|
|
||||||
endDirection = (FlxG.width * 0.02) - endingOffset;
|
|
||||||
|
|
||||||
x = (endDirection + (Conductor.songPosition - strumTime) * tankSpeed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x = (endDirection - (Conductor.songPosition - strumTime) * tankSpeed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Conductor.songPosition > strumTime)
|
|
||||||
{
|
|
||||||
// kill();
|
|
||||||
animation.play('shot');
|
|
||||||
|
|
||||||
if (goingRight)
|
|
||||||
{
|
|
||||||
offset.y = 200;
|
|
||||||
offset.x = 300;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animation.curAnim.name == 'shot' && animation.curAnim.curFrame >= animation.curAnim.frames.length - 1)
|
|
||||||
{
|
|
||||||
kill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -351,17 +351,6 @@ class TitleState extends MusicBeatState
|
||||||
FlxG.switchState(new CutsceneAnimTestState());
|
FlxG.switchState(new CutsceneAnimTestState());
|
||||||
#end
|
#end
|
||||||
|
|
||||||
/*
|
|
||||||
if (FlxG.keys.justPressed.R)
|
|
||||||
{
|
|
||||||
#if polymod
|
|
||||||
polymod.Polymod.init({modRoot: "mods", dirs: ['introMod']});
|
|
||||||
trace('reinitialized');
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (FlxG.sound.music != null)
|
if (FlxG.sound.music != null)
|
||||||
Conductor.songPosition = FlxG.sound.music.time;
|
Conductor.songPosition = FlxG.sound.music.time;
|
||||||
if (FlxG.keys.justPressed.F)
|
if (FlxG.keys.justPressed.F)
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
BF: 770, 450
|
|
||||||
GF: 400, 130
|
|
||||||
DD: 100, 100
|
|
|
@ -1,8 +1,6 @@
|
||||||
package modding;
|
package modding;
|
||||||
|
|
||||||
#if polymod
|
|
||||||
import polymod.hscript.HScriptable;
|
import polymod.hscript.HScriptable;
|
||||||
#end
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add this interface to a class to make it a scriptable object.
|
* Add this interface to a class to make it a scriptable object.
|
||||||
|
@ -12,4 +10,4 @@ import polymod.hscript.HScriptable;
|
||||||
// ALL of these values are added to ALL scripts in the child classes.
|
// ALL of these values are added to ALL scripts in the child classes.
|
||||||
context: [FlxG, FlxSprite, Math, Paths, Std]
|
context: [FlxG, FlxSprite, Math, Paths, Std]
|
||||||
})
|
})
|
||||||
interface IHook #if polymod extends HScriptable #end {}
|
interface IHook extends HScriptable {}
|
||||||
|
|
71
source/modding/PolymodErrorHandler.hx
Normal file
71
source/modding/PolymodErrorHandler.hx
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
package modding;
|
||||||
|
|
||||||
|
import polymod.Polymod;
|
||||||
|
|
||||||
|
class PolymodErrorHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Show a popup with the given text.
|
||||||
|
* This displays a system popup, it WILL interrupt the game.
|
||||||
|
* Make sure to only use this when it's important, like when there's a script error.
|
||||||
|
*
|
||||||
|
* @param name The name at the top of the popup.
|
||||||
|
* @param desc The body text of the popup.
|
||||||
|
*/
|
||||||
|
public static function showAlert(name:String, desc:String):Void
|
||||||
|
{
|
||||||
|
lime.app.Application.current.window.alert(desc, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onPolymodError(error:PolymodError):Void
|
||||||
|
{
|
||||||
|
// Perform an action based on the error code.
|
||||||
|
switch (error.code)
|
||||||
|
{
|
||||||
|
case MOD_LOAD_PREPARE:
|
||||||
|
logInfo('[POLYMOD]: ${error.message}');
|
||||||
|
case MOD_LOAD_DONE:
|
||||||
|
logInfo('[POLYMOD]: ${error.message}');
|
||||||
|
case MISSING_ICON:
|
||||||
|
logWarn('[POLYMOD]: A mod is missing an icon. Please add one.');
|
||||||
|
case SCRIPT_PARSE_ERROR:
|
||||||
|
// A syntax error when parsing a script.
|
||||||
|
logError('[POLYMOD]: ${error.message}');
|
||||||
|
showAlert('Polymod Script Parsing Error', error.message);
|
||||||
|
case SCRIPT_EXCEPTION:
|
||||||
|
// A runtime error when running a script.
|
||||||
|
logError('[POLYMOD]: ${error.message}');
|
||||||
|
showAlert('Polymod Script Execution Error', error.message);
|
||||||
|
case SCRIPT_CLASS_NOT_FOUND:
|
||||||
|
// A scripted class tried to reference an unknown superclass.
|
||||||
|
logError('[POLYMOD]: ${error.message}');
|
||||||
|
showAlert('Polymod Script Parsing Error', error.message);
|
||||||
|
default:
|
||||||
|
// Log the message based on its severity.
|
||||||
|
switch (error.severity)
|
||||||
|
{
|
||||||
|
case NOTICE:
|
||||||
|
logInfo('[POLYMOD]: ${error.message}');
|
||||||
|
case WARNING:
|
||||||
|
logWarn('[POLYMOD]: ${error.message}');
|
||||||
|
case ERROR:
|
||||||
|
logError('[POLYMOD]: ${error.message}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static function logInfo(message:String):Void
|
||||||
|
{
|
||||||
|
trace('[INFO ] ${message}');
|
||||||
|
}
|
||||||
|
|
||||||
|
static function logError(message:String):Void
|
||||||
|
{
|
||||||
|
trace('[ERROR] ${message}');
|
||||||
|
}
|
||||||
|
|
||||||
|
static function logWarn(message:String):Void
|
||||||
|
{
|
||||||
|
trace('[WARN ] ${message}');
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,11 @@
|
||||||
package modding;
|
package modding;
|
||||||
|
|
||||||
#if polymod
|
|
||||||
import polymod.Polymod.ModMetadata;
|
import polymod.Polymod.ModMetadata;
|
||||||
import polymod.Polymod;
|
import polymod.Polymod;
|
||||||
import polymod.backends.OpenFLBackend;
|
import polymod.backends.OpenFLBackend;
|
||||||
import polymod.backends.PolymodAssets.PolymodAssetType;
|
import polymod.backends.PolymodAssets.PolymodAssetType;
|
||||||
import polymod.format.ParseRules.LinesParseFormat;
|
import polymod.format.ParseRules.LinesParseFormat;
|
||||||
import polymod.format.ParseRules.TextFileFormat;
|
import polymod.format.ParseRules.TextFileFormat;
|
||||||
#end
|
|
||||||
|
|
||||||
class PolymodHandler
|
class PolymodHandler
|
||||||
{
|
{
|
||||||
|
@ -29,12 +27,8 @@ class PolymodHandler
|
||||||
*/
|
*/
|
||||||
public static function loadAllMods()
|
public static function loadAllMods()
|
||||||
{
|
{
|
||||||
#if polymod
|
|
||||||
trace("Initializing Polymod (using all mods)...");
|
trace("Initializing Polymod (using all mods)...");
|
||||||
loadModsById(getAllModIds());
|
loadModsById(getAllModIds());
|
||||||
#else
|
|
||||||
trace("Polymod not initialized; not supported on this platform.");
|
|
||||||
#end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,17 +37,12 @@ class PolymodHandler
|
||||||
public static function loadNoMods()
|
public static function loadNoMods()
|
||||||
{
|
{
|
||||||
// We still need to configure the debug print calls etc.
|
// We still need to configure the debug print calls etc.
|
||||||
#if polymod
|
|
||||||
trace("Initializing Polymod (using no mods)...");
|
trace("Initializing Polymod (using no mods)...");
|
||||||
loadModsById([]);
|
loadModsById([]);
|
||||||
#else
|
|
||||||
trace("Polymod not initialized; not supported on this platform.");
|
|
||||||
#end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function loadModsById(ids:Array<String>)
|
public static function loadModsById(ids:Array<String>)
|
||||||
{
|
{
|
||||||
#if polymod
|
|
||||||
if (ids.length == 0)
|
if (ids.length == 0)
|
||||||
{
|
{
|
||||||
trace('You attempted to load zero mods.');
|
trace('You attempted to load zero mods.');
|
||||||
|
@ -72,7 +61,7 @@ class PolymodHandler
|
||||||
// The current version of our API.
|
// The current version of our API.
|
||||||
apiVersion: API_VERSION,
|
apiVersion: API_VERSION,
|
||||||
// Call this function any time an error occurs.
|
// Call this function any time an error occurs.
|
||||||
errorCallback: onPolymodError,
|
errorCallback: PolymodErrorHandler.onPolymodError,
|
||||||
// Enforce semantic version patterns for each mod.
|
// Enforce semantic version patterns for each mod.
|
||||||
// modVersions: null,
|
// modVersions: null,
|
||||||
// A map telling Polymod what the asset type is for unfamiliar file extensions.
|
// A map telling Polymod what the asset type is for unfamiliar file extensions.
|
||||||
|
@ -107,7 +96,9 @@ class PolymodHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
for (mod in loadedModList)
|
for (mod in loadedModList)
|
||||||
|
{
|
||||||
trace(' * ${mod.title} v${mod.modVersion} [${mod.id}]');
|
trace(' * ${mod.title} v${mod.modVersion} [${mod.id}]');
|
||||||
|
}
|
||||||
|
|
||||||
#if debug
|
#if debug
|
||||||
var fileList = Polymod.listModFiles("IMAGE");
|
var fileList = Polymod.listModFiles("IMAGE");
|
||||||
|
@ -130,12 +121,8 @@ class PolymodHandler
|
||||||
for (item in fileList)
|
for (item in fileList)
|
||||||
trace(' * $item');
|
trace(' * $item');
|
||||||
#end
|
#end
|
||||||
#else
|
|
||||||
trace("[POLYMOD] Mods are not supported on this platform.");
|
|
||||||
#end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if polymod
|
|
||||||
static function buildParseRules():polymod.format.ParseRules
|
static function buildParseRules():polymod.format.ParseRules
|
||||||
{
|
{
|
||||||
var output = polymod.format.ParseRules.getDefault();
|
var output = polymod.format.ParseRules.getDefault();
|
||||||
|
@ -160,42 +147,12 @@ class PolymodHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function onPolymodError(error:PolymodError):Void
|
public static function getAllMods():Array<ModMetadata>
|
||||||
{
|
{
|
||||||
// Perform an action based on the error code.
|
|
||||||
switch (error.code)
|
|
||||||
{
|
|
||||||
case MOD_LOAD_PREPARE:
|
|
||||||
trace('[POLYMOD] ${error.message}');
|
|
||||||
case MOD_LOAD_DONE:
|
|
||||||
trace('[POLYMOD] ${error.message}');
|
|
||||||
case MISSING_ICON:
|
|
||||||
trace('[POLYMOD] A mod is missing an icon. Please add one.');
|
|
||||||
default:
|
|
||||||
// Log the message based on its severity.
|
|
||||||
switch (error.severity)
|
|
||||||
{
|
|
||||||
case NOTICE:
|
|
||||||
trace('[POLYMOD] ${error.message}');
|
|
||||||
case WARNING:
|
|
||||||
trace('[POLYMOD] ${error.message}');
|
|
||||||
case ERROR:
|
|
||||||
trace('[POLYMOD] ${error.message}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
|
|
||||||
public static function getAllMods()
|
|
||||||
{
|
|
||||||
#if polymod
|
|
||||||
trace('Scanning the mods folder...');
|
trace('Scanning the mods folder...');
|
||||||
var modMetadata = Polymod.scan(MOD_FOLDER);
|
var modMetadata = Polymod.scan(MOD_FOLDER);
|
||||||
trace('Found ${modMetadata.length} mods when scanning.');
|
trace('Found ${modMetadata.length} mods when scanning.');
|
||||||
return modMetadata;
|
return modMetadata;
|
||||||
#else
|
|
||||||
return new Array<Dynamic>();
|
|
||||||
#end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAllModIds():Array<String>
|
public static function getAllModIds():Array<String>
|
||||||
|
|
5
source/modding/base/README.md
Normal file
5
source/modding/base/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# modding.base
|
||||||
|
|
||||||
|
This package is used to allow modders to create scripted classes which extend these base classes.
|
||||||
|
For example, one script can extend FlxSprite and another can call `ScriptedFlxSprite.init('ClassName')`.
|
||||||
|
Most of these scripted class stubs are not used by the game itself, so this package has been explicitly marked to be ignored by DCE.
|
10
source/modding/base/ScriptedFlxSprite.hx
Normal file
10
source/modding/base/ScriptedFlxSprite.hx
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package modding.base;
|
||||||
|
|
||||||
|
import flixel.FlxSprite;
|
||||||
|
import modding.IHook;
|
||||||
|
|
||||||
|
@:hscriptClass
|
||||||
|
class ScriptedFlxSprite extends FlxSprite implements IHook
|
||||||
|
{
|
||||||
|
// No body needed for this class, it's magic ;)
|
||||||
|
}
|
10
source/modding/base/ScriptedFlxSpriteGroup.hx
Normal file
10
source/modding/base/ScriptedFlxSpriteGroup.hx
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package modding.base;
|
||||||
|
|
||||||
|
import flixel.group.FlxSpriteGroup;
|
||||||
|
import modding.IHook;
|
||||||
|
|
||||||
|
@:hscriptClass
|
||||||
|
class ScriptedFlxSpriteGroup extends FlxSpriteGroup implements IHook
|
||||||
|
{
|
||||||
|
// No body needed for this class, it's magic ;)
|
||||||
|
}
|
12
source/modding/base/ScriptedFlxState.hx
Normal file
12
source/modding/base/ScriptedFlxState.hx
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package modding.base;
|
||||||
|
|
||||||
|
import flixel.FlxState;
|
||||||
|
import modding.IHook;
|
||||||
|
|
||||||
|
// TODO: Polymod is having trouble with this one.
|
||||||
|
// Maybe there's a type parameter that's nested too much?
|
||||||
|
// @:hscriptClass
|
||||||
|
// class ScriptedFlxState extends FlxState implements IHook
|
||||||
|
// {
|
||||||
|
// // No body needed for this class, it's magic ;)
|
||||||
|
// }
|
12
source/modding/base/ScriptedFlxSubState.hx
Normal file
12
source/modding/base/ScriptedFlxSubState.hx
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package modding.base;
|
||||||
|
|
||||||
|
import flixel.FlxSubState;
|
||||||
|
import modding.IHook;
|
||||||
|
|
||||||
|
// TODO: Polymod is having trouble with this one.
|
||||||
|
// Maybe there's a type parameter that's nested too much?
|
||||||
|
// @:hscriptClass
|
||||||
|
// class ScriptedFlxSubState extends FlxSubState implements IHook
|
||||||
|
// {
|
||||||
|
// // No body needed for this class, it's magic ;)
|
||||||
|
// }
|
10
source/play/stage/ScriptedBopper.hx
Normal file
10
source/play/stage/ScriptedBopper.hx
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package play.stage;
|
||||||
|
|
||||||
|
import modding.IHook;
|
||||||
|
|
||||||
|
@:hscriptClass
|
||||||
|
@:keep
|
||||||
|
class ScriptedBopper extends Bopper implements IHook
|
||||||
|
{
|
||||||
|
// No body needed for this class, it's magic ;)
|
||||||
|
}
|
|
@ -2,14 +2,6 @@ package play.stage;
|
||||||
|
|
||||||
import modding.IHook;
|
import modding.IHook;
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: Turns out one of the few edge case that scripted classes are broken with,
|
|
||||||
* that being generic classes with a constrained type argument, applies to FlxSpriteGroup.
|
|
||||||
* Will have to find a fix for the issue before stages can have scripting enabled.
|
|
||||||
*
|
|
||||||
* In the meantime though, I want to get stages working just with JSON.
|
|
||||||
* -Eric
|
|
||||||
*/
|
|
||||||
@:hscriptClass
|
@:hscriptClass
|
||||||
class ScriptedStage extends Stage implements IHook
|
class ScriptedStage extends Stage implements IHook
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,6 @@ class StageDataParser
|
||||||
clearStageCache();
|
clearStageCache();
|
||||||
trace("[STAGEDATA] Loading stage cache...");
|
trace("[STAGEDATA] Loading stage cache...");
|
||||||
|
|
||||||
#if polymod
|
|
||||||
//
|
//
|
||||||
// SCRIPTED STAGES
|
// SCRIPTED STAGES
|
||||||
//
|
//
|
||||||
|
@ -58,21 +57,15 @@ class StageDataParser
|
||||||
trace(' Failed to instantiate scripted stage class: ${stageCls}');
|
trace(' Failed to instantiate scripted stage class: ${stageCls}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#end
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// UNSCRIPTED STAGES
|
// UNSCRIPTED STAGES
|
||||||
//
|
//
|
||||||
var stageIdList:Array<String> = DataAssets.listDataFilesInPath('stages/');
|
var stageIdList:Array<String> = DataAssets.listDataFilesInPath('stages/');
|
||||||
var unscriptedStageIds:Array<String> =
|
var unscriptedStageIds:Array<String> = stageIdList.filter(function(stageId:String):Bool
|
||||||
#if polymod
|
|
||||||
stageIdList.filter(function(stageId:String):Bool
|
|
||||||
{
|
{
|
||||||
return !stageCache.exists(stageId);
|
return !stageCache.exists(stageId);
|
||||||
});
|
});
|
||||||
#else
|
|
||||||
stageIdList;
|
|
||||||
#end
|
|
||||||
trace(' Instantiating ${unscriptedStageIds.length} non-scripted stages...');
|
trace(' Instantiating ${unscriptedStageIds.length} non-scripted stages...');
|
||||||
for (stageId in unscriptedStageIds)
|
for (stageId in unscriptedStageIds)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,6 @@ class BuildingShaders
|
||||||
public function update(elapsed:Float):Void
|
public function update(elapsed:Float):Void
|
||||||
{
|
{
|
||||||
shader.alphaShit.value[0] += elapsed;
|
shader.alphaShit.value[0] += elapsed;
|
||||||
trace(shader.alphaShit.value[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reset()
|
public function reset()
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package ui;
|
package ui;
|
||||||
|
|
||||||
|
import modding.PolymodHandler;
|
||||||
import flixel.group.FlxGroup.FlxTypedGroup;
|
import flixel.group.FlxGroup.FlxTypedGroup;
|
||||||
import flixel.text.FlxText;
|
import flixel.text.FlxText;
|
||||||
import flixel.util.FlxColor;
|
import flixel.util.FlxColor;
|
||||||
import polymod.Polymod;
|
import polymod.Polymod;
|
||||||
import sys.FileSystem;
|
|
||||||
|
|
||||||
class ModMenu extends ui.OptionsState.Page
|
class ModMenu extends ui.OptionsState.Page
|
||||||
{
|
{
|
||||||
var grpMods:FlxTypedGroup<ModMenuItem>;
|
var grpMods:FlxTypedGroup<ModMenuItem>;
|
||||||
var enabledMods:Array<String> = [];
|
var enabledMods:Array<ModMetadata> = [];
|
||||||
var modFolders:Array<String> = [];
|
var detectedMods:Array<ModMetadata> = [];
|
||||||
|
|
||||||
var curSelected:Int = 0;
|
var curSelected:Int = 0;
|
||||||
|
|
||||||
|
@ -62,10 +62,10 @@ class ModMenu extends ui.OptionsState.Page
|
||||||
{
|
{
|
||||||
curSelected += change;
|
curSelected += change;
|
||||||
|
|
||||||
if (curSelected >= modFolders.length)
|
if (curSelected >= detectedMods.length)
|
||||||
curSelected = 0;
|
curSelected = 0;
|
||||||
if (curSelected < 0)
|
if (curSelected < 0)
|
||||||
curSelected = modFolders.length - 1;
|
curSelected = detectedMods.length - 1;
|
||||||
|
|
||||||
for (txt in 0...grpMods.length)
|
for (txt in 0...grpMods.length)
|
||||||
{
|
{
|
||||||
|
@ -80,8 +80,6 @@ class ModMenu extends ui.OptionsState.Page
|
||||||
organizeByY();
|
organizeByY();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static var MOD_PATH = "./mods";
|
|
||||||
|
|
||||||
private function refreshModList():Void
|
private function refreshModList():Void
|
||||||
{
|
{
|
||||||
while (grpMods.members.length > 0)
|
while (grpMods.members.length > 0)
|
||||||
|
@ -90,36 +88,17 @@ class ModMenu extends ui.OptionsState.Page
|
||||||
}
|
}
|
||||||
|
|
||||||
#if desktop
|
#if desktop
|
||||||
var modList = [];
|
detectedMods = PolymodHandler.getAllMods();
|
||||||
modFolders = [];
|
|
||||||
|
|
||||||
trace("mods path:" + FileSystem.absolutePath(MOD_PATH));
|
trace('ModMenu: Detected ${detectedMods.length} mods');
|
||||||
if (!FileSystem.exists(MOD_PATH))
|
|
||||||
|
for (index in 0...detectedMods.length)
|
||||||
{
|
{
|
||||||
FlxG.log.warn("missing mods folder, expected: " + FileSystem.absolutePath(MOD_PATH));
|
var modMetadata:ModMetadata = detectedMods[index];
|
||||||
return;
|
var modName:String = modMetadata.title;
|
||||||
}
|
var txt:ModMenuItem = new ModMenuItem(0, 10 + (40 * index), 0, modName, 32);
|
||||||
|
txt.text = modName;
|
||||||
for (file in FileSystem.readDirectory(MOD_PATH))
|
|
||||||
{
|
|
||||||
if (FileSystem.isDirectory(MOD_PATH + file))
|
|
||||||
modFolders.push(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
enabledMods = [];
|
|
||||||
|
|
||||||
modList = Polymod.scan(MOD_PATH);
|
|
||||||
|
|
||||||
trace(modList);
|
|
||||||
|
|
||||||
var loopNum:Int = 0;
|
|
||||||
for (i in modFolders)
|
|
||||||
{
|
|
||||||
var txt:ModMenuItem = new ModMenuItem(0, 10 + (40 * loopNum), 0, i, 32);
|
|
||||||
txt.text = i;
|
|
||||||
grpMods.add(txt);
|
grpMods.add(txt);
|
||||||
|
|
||||||
loopNum++;
|
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,7 @@ class OptionsState extends MusicBeatState
|
||||||
var controls = addPage(Controls, new ControlsMenu());
|
var controls = addPage(Controls, new ControlsMenu());
|
||||||
// var colors = addPage(Colors, new ColorsMenu());
|
// var colors = addPage(Colors, new ColorsMenu());
|
||||||
|
|
||||||
#if polymod
|
|
||||||
var mods = addPage(Mods, new ModMenu());
|
var mods = addPage(Mods, new ModMenu());
|
||||||
#end
|
|
||||||
|
|
||||||
if (options.hasMultipleOptions())
|
if (options.hasMultipleOptions())
|
||||||
{
|
{
|
||||||
|
@ -43,10 +41,7 @@ class OptionsState extends MusicBeatState
|
||||||
controls.onExit.add(switchPage.bind(Options));
|
controls.onExit.add(switchPage.bind(Options));
|
||||||
// colors.onExit.add(switchPage.bind(Options));
|
// colors.onExit.add(switchPage.bind(Options));
|
||||||
preferences.onExit.add(switchPage.bind(Options));
|
preferences.onExit.add(switchPage.bind(Options));
|
||||||
|
|
||||||
#if polymod
|
|
||||||
mods.onExit.add(switchPage.bind(Options));
|
mods.onExit.add(switchPage.bind(Options));
|
||||||
#end
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -180,9 +175,7 @@ class OptionsMenu extends Page
|
||||||
createItem(t("PREFERENCES"), function() switchPage(Preferences));
|
createItem(t("PREFERENCES"), function() switchPage(Preferences));
|
||||||
createItem(t("CONTROLS"), function() switchPage(Controls));
|
createItem(t("CONTROLS"), function() switchPage(Controls));
|
||||||
// createItem(t("COLORS"), function() switchPage(Colors));
|
// createItem(t("COLORS"), function() switchPage(Colors));
|
||||||
#if polymod
|
|
||||||
createItem(t("MODS"), function() switchPage(Mods));
|
createItem(t("MODS"), function() switchPage(Mods));
|
||||||
#end
|
|
||||||
|
|
||||||
#if CAN_OPEN_LINKS
|
#if CAN_OPEN_LINKS
|
||||||
if (showDonate)
|
if (showDonate)
|
||||||
|
|
Loading…
Reference in a new issue