FUCK SPACES!!!! TABS RULES!!! 💪💪💪💪
This commit is contained in:
@@ -17,137 +17,137 @@ using StringTools;
|
|||||||
class AtlasFrameMaker extends FlxFramesCollection{
|
class AtlasFrameMaker extends FlxFramesCollection{
|
||||||
|
|
||||||
|
|
||||||
//public static var widthoffset:Int = 0;
|
//public static var widthoffset:Int = 0;
|
||||||
//public static var heightoffset:Int = 0;
|
//public static var heightoffset:Int = 0;
|
||||||
//public static var excludeArray:Array<String>;
|
//public static var excludeArray:Array<String>;
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Creates Frames from TextureAtlas(very early and broken ok) Originally made for FNF HD by Smokey and Rozebud
|
* Creates Frames from TextureAtlas(very early and broken ok) Originally made for FNF HD by Smokey and Rozebud
|
||||||
*
|
*
|
||||||
* @param key The file path.
|
* @param key The file path.
|
||||||
* @param _excludeArray Use this to only create selected animations. Keep null to create all of them.
|
* @param _excludeArray Use this to only create selected animations. Keep null to create all of them.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static function construct(key:String,?_excludeArray:Array<String> = null):FlxFramesCollection{
|
public static function construct(key:String,?_excludeArray:Array<String> = null):FlxFramesCollection{
|
||||||
|
|
||||||
// widthoffset = _widthoffset;
|
// widthoffset = _widthoffset;
|
||||||
// heightoffset = _heightoffset;
|
// heightoffset = _heightoffset;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var frameCollection:FlxFramesCollection;
|
var frameCollection:FlxFramesCollection;
|
||||||
var frameArray:Array<Array<FlxFrame>> = [];
|
var frameArray:Array<Array<FlxFrame>> = [];
|
||||||
var animationData:AnimationData = Json.parse(Assets.getText(key + "/Animation.json"));
|
var animationData:AnimationData = Json.parse(Assets.getText(key + "/Animation.json"));
|
||||||
var atlasData:AtlasData = Json.parse(Assets.getText(key + "/spritemap.json").replace("\uFEFF", ""));//FIXED UTF8 w/ BOM error
|
var atlasData:AtlasData = Json.parse(Assets.getText(key + "/spritemap.json").replace("\uFEFF", ""));//FIXED UTF8 w/ BOM error
|
||||||
var bitmapData:BitmapData = Assets.getBitmapData(key + "/spritemap.png");
|
var bitmapData:BitmapData = Assets.getBitmapData(key + "/spritemap.png");
|
||||||
var ss = new SpriteAnimationLibrary(animationData, atlasData, bitmapData);
|
var ss = new SpriteAnimationLibrary(animationData, atlasData, bitmapData);
|
||||||
var t = ss.createAnimation();
|
var t = ss.createAnimation();
|
||||||
if(_excludeArray == null){
|
if(_excludeArray == null){
|
||||||
_excludeArray = t.getFrameLabels();
|
_excludeArray = t.getFrameLabels();
|
||||||
}
|
}
|
||||||
frameCollection = new FlxFramesCollection(FlxGraphic.fromBitmapData(bitmapData),FlxFrameCollectionType.IMAGE);
|
frameCollection = new FlxFramesCollection(FlxGraphic.fromBitmapData(bitmapData),FlxFrameCollectionType.IMAGE);
|
||||||
|
|
||||||
|
|
||||||
for(x in t.getFrameLabels()){
|
for(x in t.getFrameLabels()){
|
||||||
|
|
||||||
frameArray.push(getFramesArray(t, x,_excludeArray));
|
frameArray.push(getFramesArray(t, x,_excludeArray));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(x in frameArray){
|
for(x in frameArray){
|
||||||
for(y in x){
|
for(y in x){
|
||||||
frameCollection.pushFrame(y);
|
frameCollection.pushFrame(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameCollection;
|
return frameCollection;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@:noCompletion static function getFramesArray(t:SpriteMovieClip,animation:String,_excludeArray:Array<String>):Array<FlxFrame>
|
@:noCompletion static function getFramesArray(t:SpriteMovieClip,animation:String,_excludeArray:Array<String>):Array<FlxFrame>
|
||||||
{
|
{
|
||||||
var sizeInfo:Rectangle = new Rectangle(0,0);
|
var sizeInfo:Rectangle = new Rectangle(0,0);
|
||||||
t.currentLabel = animation;
|
t.currentLabel = animation;
|
||||||
var bitMapArray:Array<BitmapData> = [];
|
var bitMapArray:Array<BitmapData> = [];
|
||||||
var daFramez:Array<FlxFrame> = [];
|
var daFramez:Array<FlxFrame> = [];
|
||||||
var firstPass = true;
|
var firstPass = true;
|
||||||
var frameSize:FlxPoint = new FlxPoint(0,0);
|
var frameSize:FlxPoint = new FlxPoint(0,0);
|
||||||
|
|
||||||
for (i in t.getFrame(animation)...t.numFrames){
|
for (i in t.getFrame(animation)...t.numFrames){
|
||||||
t.currentFrame = i;
|
t.currentFrame = i;
|
||||||
if (t.currentLabel == animation){
|
if (t.currentLabel == animation){
|
||||||
if (_excludeArray.contains(animation)){
|
if (_excludeArray.contains(animation)){
|
||||||
sizeInfo = t.getBounds(t);
|
sizeInfo = t.getBounds(t);
|
||||||
|
|
||||||
var bitmapShit:BitmapData = new BitmapData(
|
var bitmapShit:BitmapData = new BitmapData(
|
||||||
Std.int(sizeInfo.width + Math.abs(sizeInfo.x)),Std.int(sizeInfo.height +Math.abs(sizeInfo.y)),true,0);
|
Std.int(sizeInfo.width + Math.abs(sizeInfo.x)),Std.int(sizeInfo.height +Math.abs(sizeInfo.y)),true,0);
|
||||||
|
|
||||||
bitmapShit.draw(t,null,null,null,null,true);
|
bitmapShit.draw(t,null,null,null,null,true);
|
||||||
bitMapArray.push(bitmapShit);
|
bitMapArray.push(bitmapShit);
|
||||||
|
|
||||||
if (firstPass){
|
if (firstPass){
|
||||||
frameSize.set(bitmapShit.width,bitmapShit.height);
|
frameSize.set(bitmapShit.width,bitmapShit.height);
|
||||||
firstPass = false;
|
firstPass = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i in 0...bitMapArray.length){
|
for (i in 0...bitMapArray.length){
|
||||||
var b = FlxGraphic.fromBitmapData(bitMapArray[i]);
|
var b = FlxGraphic.fromBitmapData(bitMapArray[i]);
|
||||||
var theFrame = new FlxFrame(b);
|
var theFrame = new FlxFrame(b);
|
||||||
theFrame.parent = b;
|
theFrame.parent = b;
|
||||||
theFrame.name = animation + i;
|
theFrame.name = animation + i;
|
||||||
theFrame.sourceSize.set(frameSize.x,frameSize.y);
|
theFrame.sourceSize.set(frameSize.x,frameSize.y);
|
||||||
theFrame.frame = new FlxRect(0, 0, bitMapArray[i].width, bitMapArray[i].height);
|
theFrame.frame = new FlxRect(0, 0, bitMapArray[i].width, bitMapArray[i].height);
|
||||||
daFramez.push(theFrame);
|
daFramez.push(theFrame);
|
||||||
|
|
||||||
//trace(daFramez);
|
//trace(daFramez);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameSize != null)
|
if (frameSize != null)
|
||||||
frameSize.put();
|
frameSize.put();
|
||||||
|
|
||||||
return daFramez;
|
return daFramez;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public static function renderTest(key:String, animation:String, ?frame:Int = 0):Void
|
/*public static function renderTest(key:String, animation:String, ?frame:Int = 0):Void
|
||||||
{
|
{
|
||||||
var animationData:AnimationData = Json.parse(Assets.getText(key + "/Animation.json"));
|
var animationData:AnimationData = Json.parse(Assets.getText(key + "/Animation.json"));
|
||||||
var atlasData:AtlasData = Json.parse(Assets.getText(key + "/spritemap.json"));
|
var atlasData:AtlasData = Json.parse(Assets.getText(key + "/spritemap.json"));
|
||||||
var bitmapData:BitmapData = Assets.getBitmapData(key + "/spritemap.png");
|
var bitmapData:BitmapData = Assets.getBitmapData(key + "/spritemap.png");
|
||||||
var ss = new SpriteAnimationLibrary(animationData, atlasData, bitmapData);
|
var ss = new SpriteAnimationLibrary(animationData, atlasData, bitmapData);
|
||||||
var t = ss.createAnimation();
|
var t = ss.createAnimation();
|
||||||
var bitMapArray:Array<BitmapData> = [];
|
var bitMapArray:Array<BitmapData> = [];
|
||||||
|
|
||||||
for (i in 0...t.numFrames){
|
for (i in 0...t.numFrames){
|
||||||
t.currentFrame = i;
|
t.currentFrame = i;
|
||||||
if (t.currentLabel == animation){
|
if (t.currentLabel == animation){
|
||||||
//trace(t.currentFrame);
|
//trace(t.currentFrame);
|
||||||
var bitmapShit:BitmapData = new BitmapData(Std.int(t.width),Std.int(t.height),true,0);
|
var bitmapShit:BitmapData = new BitmapData(Std.int(t.width),Std.int(t.height),true,0);
|
||||||
//bitmapShit.drawWithQuality(t,null,null,null,null,true);
|
//bitmapShit.drawWithQuality(t,null,null,null,null,true);
|
||||||
bitmapShit.draw(t, new Matrix(1, 0, 0, 1, t.width/2, t.height/2), null, null, null, false);
|
bitmapShit.draw(t, new Matrix(1, 0, 0, 1, t.width/2, t.height/2), null, null, null, false);
|
||||||
bitMapArray.push(bitmapShit);
|
bitMapArray.push(bitmapShit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
saveImage(bitMapArray[frame]);
|
saveImage(bitMapArray[frame]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function saveImage(bitmapData:BitmapData)
|
public static function saveImage(bitmapData:BitmapData)
|
||||||
{
|
{
|
||||||
var b:ByteArray = new ByteArray();
|
var b:ByteArray = new ByteArray();
|
||||||
b = bitmapData.encode(bitmapData.rect, new PNGEncoderOptions(true), b);
|
b = bitmapData.encode(bitmapData.rect, new PNGEncoderOptions(true), b);
|
||||||
new FileDialog().save(b, "png", null, "file");
|
new FileDialog().save(b, "png", null, "file");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+112
-112
@@ -29,146 +29,146 @@ import flixel.FlxCamera;
|
|||||||
import away3d.containers.View3D;
|
import away3d.containers.View3D;
|
||||||
|
|
||||||
class Flx3DCamera extends FlxCamera {
|
class Flx3DCamera extends FlxCamera {
|
||||||
private static var __3DIDS:Int = 0;
|
private static var __3DIDS:Int = 0;
|
||||||
|
|
||||||
public var view:View3D;
|
public var view:View3D;
|
||||||
|
|
||||||
var meshes:Array<Mesh> = [];
|
var meshes:Array<Mesh> = [];
|
||||||
public function new(X:Int = 0, Y:Int = 0, Width:Int = 0, Height:Int = 0, DefaultZoom:Float = 1) {
|
public function new(X:Int = 0, Y:Int = 0, Width:Int = 0, Height:Int = 0, DefaultZoom:Float = 1) {
|
||||||
if (!Flx3DUtil.is3DAvailable())
|
if (!Flx3DUtil.is3DAvailable())
|
||||||
throw "[Flx3DCamera] 3D is not available on this platform. Stages in use: " + Flx3DUtil.getTotal3D() + ", Max stages allowed: " + FlxG.stage.stage3Ds.length + ".";
|
throw "[Flx3DCamera] 3D is not available on this platform. Stages in use: " + Flx3DUtil.getTotal3D() + ", Max stages allowed: " + FlxG.stage.stage3Ds.length + ".";
|
||||||
super(X, Y, Width, Height, DefaultZoom);
|
super(X, Y, Width, Height, DefaultZoom);
|
||||||
__cur3DStageID = __3DIDS++;
|
__cur3DStageID = __3DIDS++;
|
||||||
|
|
||||||
view = new View3D();
|
view = new View3D();
|
||||||
view.width = this.width;
|
view.width = this.width;
|
||||||
view.height = this.height;
|
view.height = this.height;
|
||||||
view.visible = true;
|
view.visible = true;
|
||||||
|
|
||||||
FlxG.stage.addChild(view);
|
FlxG.stage.addChild(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function render() {
|
public override function render() {
|
||||||
super.render();
|
super.render();
|
||||||
|
|
||||||
view.x = FlxG.game.x + FlxG.game.scaleX * (flashSprite.x + flashSprite.scaleX * (_scrollRect.x + _scrollRect.scaleX * (_scrollRect.scrollRect.x)));
|
view.x = FlxG.game.x + FlxG.game.scaleX * (flashSprite.x + flashSprite.scaleX * (_scrollRect.x + _scrollRect.scaleX * (_scrollRect.scrollRect.x)));
|
||||||
view.x -= _scrollRect.scrollRect.width * ((zoom / initialZoom) - 1) / 2;
|
view.x -= _scrollRect.scrollRect.width * ((zoom / initialZoom) - 1) / 2;
|
||||||
view.y = FlxG.game.y + FlxG.game.scaleY * (flashSprite.y + flashSprite.scaleY * (_scrollRect.y + _scrollRect.scaleY * (_scrollRect.scrollRect.y)));
|
view.y = FlxG.game.y + FlxG.game.scaleY * (flashSprite.y + flashSprite.scaleY * (_scrollRect.y + _scrollRect.scaleY * (_scrollRect.scrollRect.y)));
|
||||||
view.y -= _scrollRect.scrollRect.height * ((zoom / initialZoom) - 1) / 2;
|
view.y -= _scrollRect.scrollRect.height * ((zoom / initialZoom) - 1) / 2;
|
||||||
|
|
||||||
view.width = _scrollRect.scrollRect.width / initialZoom;
|
view.width = _scrollRect.scrollRect.width / initialZoom;
|
||||||
view.width += _scrollRect.scrollRect.width / initialZoom * ((zoom / initialZoom) - 1);
|
view.width += _scrollRect.scrollRect.width / initialZoom * ((zoom / initialZoom) - 1);
|
||||||
view.height = _scrollRect.scrollRect.height / initialZoom;
|
view.height = _scrollRect.scrollRect.height / initialZoom;
|
||||||
view.height += _scrollRect.scrollRect.height / initialZoom * ((zoom / initialZoom) - 1);
|
view.height += _scrollRect.scrollRect.height / initialZoom * ((zoom / initialZoom) - 1);
|
||||||
|
|
||||||
view.render();
|
view.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addModel(assetPath:String, callback:Asset3DEvent->Void, ?texturePath:String, smoothTexture:Bool = true) {
|
public function addModel(assetPath:String, callback:Asset3DEvent->Void, ?texturePath:String, smoothTexture:Bool = true) {
|
||||||
|
|
||||||
var model = Assets.getBytes(assetPath);
|
var model = Assets.getBytes(assetPath);
|
||||||
if (model == null)
|
if (model == null)
|
||||||
throw 'Model at ${assetPath} was not found.';
|
throw 'Model at ${assetPath} was not found.';
|
||||||
|
|
||||||
var context = new AssetLoaderContext();
|
var context = new AssetLoaderContext();
|
||||||
var noExt = Path.withoutExtension(assetPath);
|
var noExt = Path.withoutExtension(assetPath);
|
||||||
trace(noExt);
|
trace(noExt);
|
||||||
context.mapUrlToData('${Path.withoutDirectory(noExt)}.mtl', '$noExt.mtl');
|
context.mapUrlToData('${Path.withoutDirectory(noExt)}.mtl', '$noExt.mtl');
|
||||||
|
|
||||||
var material:TextureMaterial = null;
|
var material:TextureMaterial = null;
|
||||||
if (texturePath != null)
|
if (texturePath != null)
|
||||||
material = new TextureMaterial(Cast.bitmapTexture(texturePath), smoothTexture);
|
material = new TextureMaterial(Cast.bitmapTexture(texturePath), smoothTexture);
|
||||||
|
|
||||||
return loadData(model, context, switch(Path.extension(assetPath).toLowerCase()) {
|
return loadData(model, context, switch(Path.extension(assetPath).toLowerCase()) {
|
||||||
case "dae": new DAEParser();
|
case "dae": new DAEParser();
|
||||||
case "md2": new MD2Parser();
|
case "md2": new MD2Parser();
|
||||||
case "md5": new MD5MeshParser();
|
case "md5": new MD5MeshParser();
|
||||||
case "awd": new AWDParser();
|
case "awd": new AWDParser();
|
||||||
default: new OBJParser();
|
default: new OBJParser();
|
||||||
}, (event:Asset3DEvent) -> {
|
}, (event:Asset3DEvent) -> {
|
||||||
if (event.asset != null && event.asset.assetType == Asset3DType.MESH) {
|
if (event.asset != null && event.asset.assetType == Asset3DType.MESH) {
|
||||||
var mesh:Mesh = cast(event.asset, Mesh);
|
var mesh:Mesh = cast(event.asset, Mesh);
|
||||||
if (material != null)
|
if (material != null)
|
||||||
mesh.material = material;
|
mesh.material = material;
|
||||||
meshes.push(mesh);
|
meshes.push(mesh);
|
||||||
}
|
}
|
||||||
callback(event);
|
callback(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private var __cur3DStageID:Int;
|
private var __cur3DStageID:Int;
|
||||||
private var _loaders:Map<Asset3DLibraryBundle, AssetLoaderToken> = [];
|
private var _loaders:Map<Asset3DLibraryBundle, AssetLoaderToken> = [];
|
||||||
|
|
||||||
private function loadData(data:Dynamic, context:AssetLoaderContext, parser:ParserBase, onAssetCallback:Asset3DEvent->Void):AssetLoaderToken {
|
private function loadData(data:Dynamic, context:AssetLoaderContext, parser:ParserBase, onAssetCallback:Asset3DEvent->Void):AssetLoaderToken {
|
||||||
var token:AssetLoaderToken;
|
var token:AssetLoaderToken;
|
||||||
|
|
||||||
var lib:Asset3DLibraryBundle;
|
var lib:Asset3DLibraryBundle;
|
||||||
lib = Asset3DLibraryBundle.getInstance('Flx3DView-${__cur3DStageID}');
|
lib = Asset3DLibraryBundle.getInstance('Flx3DView-${__cur3DStageID}');
|
||||||
token = lib.loadData(data, context, null, parser);
|
token = lib.loadData(data, context, null, parser);
|
||||||
|
|
||||||
token.addEventListener(Asset3DEvent.ASSET_COMPLETE, (event:Asset3DEvent) -> {
|
token.addEventListener(Asset3DEvent.ASSET_COMPLETE, (event:Asset3DEvent) -> {
|
||||||
// ! Taken from Loader3D https://github.com/openfl/away3d/blob/master/away3d/loaders/Loader3D.hx#L207-L232
|
// ! Taken from Loader3D https://github.com/openfl/away3d/blob/master/away3d/loaders/Loader3D.hx#L207-L232
|
||||||
if (event.type == Asset3DEvent.ASSET_COMPLETE) {
|
if (event.type == Asset3DEvent.ASSET_COMPLETE) {
|
||||||
var obj:ObjectContainer3D = null;
|
var obj:ObjectContainer3D = null;
|
||||||
switch (event.asset.assetType) {
|
switch (event.asset.assetType) {
|
||||||
case Asset3DType.LIGHT:
|
case Asset3DType.LIGHT:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, LightBase) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, LightBase) ? cast event.asset : null;
|
||||||
case Asset3DType.CONTAINER:
|
case Asset3DType.CONTAINER:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, ObjectContainer3D) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, ObjectContainer3D) ? cast event.asset : null;
|
||||||
case Asset3DType.MESH:
|
case Asset3DType.MESH:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, Mesh) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, Mesh) ? cast event.asset : null;
|
||||||
case Asset3DType.SKYBOX:
|
case Asset3DType.SKYBOX:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, SkyBox) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, SkyBox) ? cast event.asset : null;
|
||||||
case Asset3DType.TEXTURE_PROJECTOR:
|
case Asset3DType.TEXTURE_PROJECTOR:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, TextureProjector) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, TextureProjector) ? cast event.asset : null;
|
||||||
case Asset3DType.CAMERA:
|
case Asset3DType.CAMERA:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, Camera3D) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, Camera3D) ? cast event.asset : null;
|
||||||
case Asset3DType.SEGMENT_SET:
|
case Asset3DType.SEGMENT_SET:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, SegmentSet) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, SegmentSet) ? cast event.asset : null;
|
||||||
}
|
}
|
||||||
if (obj != null && obj.parent == null)
|
if (obj != null && obj.parent == null)
|
||||||
view.scene.addChild(obj);
|
view.scene.addChild(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onAssetCallback != null)
|
if (onAssetCallback != null)
|
||||||
onAssetCallback(event);
|
onAssetCallback(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, (_) -> {
|
token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, (_) -> {
|
||||||
trace("Loader Finished...");
|
trace("Loader Finished...");
|
||||||
});
|
});
|
||||||
|
|
||||||
_loaders.set(lib,token);
|
_loaders.set(lib,token);
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
override function destroy() {
|
override function destroy() {
|
||||||
if (meshes != null)
|
if (meshes != null)
|
||||||
for(mesh in meshes)
|
for(mesh in meshes)
|
||||||
mesh.dispose();
|
mesh.dispose();
|
||||||
|
|
||||||
var bundle = Asset3DLibraryBundle.getInstance('Flx3DView-${__cur3DStageID}');
|
var bundle = Asset3DLibraryBundle.getInstance('Flx3DView-${__cur3DStageID}');
|
||||||
bundle.stopAllLoadingSessions();
|
bundle.stopAllLoadingSessions();
|
||||||
@:privateAccess {
|
@:privateAccess {
|
||||||
if (bundle._loadingSessions != null) {
|
if (bundle._loadingSessions != null) {
|
||||||
for(load in bundle._loadingSessions) {
|
for(load in bundle._loadingSessions) {
|
||||||
load.dispose();
|
load.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Asset3DLibrary._instances.remove('Flx3DView-${__cur3DStageID}');
|
Asset3DLibrary._instances.remove('Flx3DView-${__cur3DStageID}');
|
||||||
}
|
}
|
||||||
|
|
||||||
FlxG.stage.removeChild(view);
|
FlxG.stage.removeChild(view);
|
||||||
try {
|
try {
|
||||||
view.dispose();
|
view.dispose();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline function addChild(c)
|
public inline function addChild(c)
|
||||||
view.scene.addChild(c);
|
view.scene.addChild(c);
|
||||||
}
|
}
|
||||||
+93
-93
@@ -29,120 +29,120 @@ import funkin.windows.WindowsAPI.ConsoleColor;
|
|||||||
// FlxView3D with helpers for easier updating
|
// FlxView3D with helpers for easier updating
|
||||||
|
|
||||||
class Flx3DView extends FlxView3D {
|
class Flx3DView extends FlxView3D {
|
||||||
private static var __3DIDS:Int = 0;
|
private static var __3DIDS:Int = 0;
|
||||||
|
|
||||||
var meshes:Array<Mesh> = [];
|
var meshes:Array<Mesh> = [];
|
||||||
public function new(x:Float = 0, y:Float = 0, width:Int = -1, height:Int = -1) {
|
public function new(x:Float = 0, y:Float = 0, width:Int = -1, height:Int = -1) {
|
||||||
if (!Flx3DUtil.is3DAvailable())
|
if (!Flx3DUtil.is3DAvailable())
|
||||||
throw "[Flx3DView] 3D is not available on this platform. Stages in use: " + Flx3DUtil.getTotal3D() + ", Max stages allowed: " + FlxG.stage.stage3Ds.length + ".";
|
throw "[Flx3DView] 3D is not available on this platform. Stages in use: " + Flx3DUtil.getTotal3D() + ", Max stages allowed: " + FlxG.stage.stage3Ds.length + ".";
|
||||||
super(x, y, width, height);
|
super(x, y, width, height);
|
||||||
__cur3DStageID = __3DIDS++;
|
__cur3DStageID = __3DIDS++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addModel(assetPath:String, callback:Asset3DEvent->Void, ?texturePath:String, smoothTexture:Bool = true) {
|
public function addModel(assetPath:String, callback:Asset3DEvent->Void, ?texturePath:String, smoothTexture:Bool = true) {
|
||||||
|
|
||||||
var model = Assets.getBytes(assetPath);
|
var model = Assets.getBytes(assetPath);
|
||||||
if (model == null)
|
if (model == null)
|
||||||
throw 'Model at ${assetPath} was not found.';
|
throw 'Model at ${assetPath} was not found.';
|
||||||
|
|
||||||
var context = new AssetLoaderContext();
|
var context = new AssetLoaderContext();
|
||||||
var noExt = Path.withoutExtension(assetPath);
|
var noExt = Path.withoutExtension(assetPath);
|
||||||
trace(noExt);
|
trace(noExt);
|
||||||
context.mapUrlToData('${Path.withoutDirectory(noExt)}.mtl', '$noExt.mtl');
|
context.mapUrlToData('${Path.withoutDirectory(noExt)}.mtl', '$noExt.mtl');
|
||||||
|
|
||||||
var material:TextureMaterial = null;
|
var material:TextureMaterial = null;
|
||||||
if (texturePath != null)
|
if (texturePath != null)
|
||||||
material = new TextureMaterial(Cast.bitmapTexture(texturePath), smoothTexture);
|
material = new TextureMaterial(Cast.bitmapTexture(texturePath), smoothTexture);
|
||||||
|
|
||||||
return loadData(model, context, switch(Path.extension(assetPath).toLowerCase()) {
|
return loadData(model, context, switch(Path.extension(assetPath).toLowerCase()) {
|
||||||
case "dae": new DAEParser();
|
case "dae": new DAEParser();
|
||||||
case "md2": new MD2Parser();
|
case "md2": new MD2Parser();
|
||||||
case "md5": new MD5MeshParser();
|
case "md5": new MD5MeshParser();
|
||||||
case "awd": new AWDParser();
|
case "awd": new AWDParser();
|
||||||
default: new OBJParser();
|
default: new OBJParser();
|
||||||
}, (event:Asset3DEvent) -> {
|
}, (event:Asset3DEvent) -> {
|
||||||
if (event.asset != null && event.asset.assetType == Asset3DType.MESH) {
|
if (event.asset != null && event.asset.assetType == Asset3DType.MESH) {
|
||||||
var mesh:Mesh = cast(event.asset, Mesh);
|
var mesh:Mesh = cast(event.asset, Mesh);
|
||||||
if (material != null)
|
if (material != null)
|
||||||
mesh.material = material;
|
mesh.material = material;
|
||||||
meshes.push(mesh);
|
meshes.push(mesh);
|
||||||
}
|
}
|
||||||
callback(event);
|
callback(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@:deprecated public function addMesh(assetPath:String, callback:Mesh->Void, ?texturePath:String, smoothTexture:Bool = true) {
|
@:deprecated public function addMesh(assetPath:String, callback:Mesh->Void, ?texturePath:String, smoothTexture:Bool = true) {
|
||||||
Logs.trace('The addMesh() function is deprecated, use addModel instead!', ERROR, RED);
|
Logs.trace('The addMesh() function is deprecated, use addModel instead!', ERROR, RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private var __cur3DStageID:Int;
|
private var __cur3DStageID:Int;
|
||||||
private var _loaders:Map<Asset3DLibraryBundle, AssetLoaderToken> = [];
|
private var _loaders:Map<Asset3DLibraryBundle, AssetLoaderToken> = [];
|
||||||
|
|
||||||
private function loadData(data:Dynamic, context:AssetLoaderContext, parser:ParserBase, onAssetCallback:Asset3DEvent->Void):AssetLoaderToken {
|
private function loadData(data:Dynamic, context:AssetLoaderContext, parser:ParserBase, onAssetCallback:Asset3DEvent->Void):AssetLoaderToken {
|
||||||
var token:AssetLoaderToken;
|
var token:AssetLoaderToken;
|
||||||
|
|
||||||
var lib:Asset3DLibraryBundle;
|
var lib:Asset3DLibraryBundle;
|
||||||
lib = Asset3DLibraryBundle.getInstance('Flx3DView-${__cur3DStageID}');
|
lib = Asset3DLibraryBundle.getInstance('Flx3DView-${__cur3DStageID}');
|
||||||
token = lib.loadData(data, context, null, parser);
|
token = lib.loadData(data, context, null, parser);
|
||||||
|
|
||||||
token.addEventListener(Asset3DEvent.ASSET_COMPLETE, (event:Asset3DEvent) -> {
|
token.addEventListener(Asset3DEvent.ASSET_COMPLETE, (event:Asset3DEvent) -> {
|
||||||
// ! Taken from Loader3D https://github.com/openfl/away3d/blob/master/away3d/loaders/Loader3D.hx#L207-L232
|
// ! Taken from Loader3D https://github.com/openfl/away3d/blob/master/away3d/loaders/Loader3D.hx#L207-L232
|
||||||
if (event.type == Asset3DEvent.ASSET_COMPLETE) {
|
if (event.type == Asset3DEvent.ASSET_COMPLETE) {
|
||||||
var obj:ObjectContainer3D = null;
|
var obj:ObjectContainer3D = null;
|
||||||
switch (event.asset.assetType) {
|
switch (event.asset.assetType) {
|
||||||
case Asset3DType.LIGHT:
|
case Asset3DType.LIGHT:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, LightBase) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, LightBase) ? cast event.asset : null;
|
||||||
case Asset3DType.CONTAINER:
|
case Asset3DType.CONTAINER:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, ObjectContainer3D) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, ObjectContainer3D) ? cast event.asset : null;
|
||||||
case Asset3DType.MESH:
|
case Asset3DType.MESH:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, Mesh) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, Mesh) ? cast event.asset : null;
|
||||||
case Asset3DType.SKYBOX:
|
case Asset3DType.SKYBOX:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, SkyBox) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, SkyBox) ? cast event.asset : null;
|
||||||
case Asset3DType.TEXTURE_PROJECTOR:
|
case Asset3DType.TEXTURE_PROJECTOR:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, TextureProjector) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, TextureProjector) ? cast event.asset : null;
|
||||||
case Asset3DType.CAMERA:
|
case Asset3DType.CAMERA:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, Camera3D) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, Camera3D) ? cast event.asset : null;
|
||||||
case Asset3DType.SEGMENT_SET:
|
case Asset3DType.SEGMENT_SET:
|
||||||
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, SegmentSet) ? cast event.asset : null;
|
obj = #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end(event.asset, SegmentSet) ? cast event.asset : null;
|
||||||
}
|
}
|
||||||
if (obj != null && obj.parent == null)
|
if (obj != null && obj.parent == null)
|
||||||
view.scene.addChild(obj);
|
view.scene.addChild(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onAssetCallback != null)
|
if (onAssetCallback != null)
|
||||||
onAssetCallback(event);
|
onAssetCallback(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, (_) -> {
|
token.addEventListener(LoaderEvent.RESOURCE_COMPLETE, (_) -> {
|
||||||
trace("Loader Finished...");
|
trace("Loader Finished...");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
_loaders.set(lib,token);
|
_loaders.set(lib,token);
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
override function destroy() {
|
override function destroy() {
|
||||||
if (meshes != null)
|
if (meshes != null)
|
||||||
for(mesh in meshes)
|
for(mesh in meshes)
|
||||||
mesh.dispose();
|
mesh.dispose();
|
||||||
|
|
||||||
var bundle = Asset3DLibraryBundle.getInstance('Flx3DView-${__cur3DStageID}');
|
var bundle = Asset3DLibraryBundle.getInstance('Flx3DView-${__cur3DStageID}');
|
||||||
bundle.stopAllLoadingSessions();
|
bundle.stopAllLoadingSessions();
|
||||||
@:privateAccess {
|
@:privateAccess {
|
||||||
if (bundle._loadingSessions != null) {
|
if (bundle._loadingSessions != null) {
|
||||||
for(load in bundle._loadingSessions) {
|
for(load in bundle._loadingSessions) {
|
||||||
load.dispose();
|
load.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Asset3DLibrary._instances.remove('Flx3DView-${__cur3DStageID}');
|
Asset3DLibrary._instances.remove('Flx3DView-${__cur3DStageID}');
|
||||||
}
|
}
|
||||||
|
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline function addChild(c)
|
public inline function addChild(c)
|
||||||
view.scene.addChild(c);
|
view.scene.addChild(c);
|
||||||
}
|
}
|
||||||
@@ -1,102 +1,102 @@
|
|||||||
package funkin.chart;
|
package funkin.chart;
|
||||||
|
|
||||||
class BaseGameParser {
|
class BaseGameParser {
|
||||||
public static function parse(data:Dynamic, result:ChartData) {
|
public static function parse(data:Dynamic, result:ChartData) {
|
||||||
// base fnf chart parsing
|
// base fnf chart parsing
|
||||||
var data:SwagSong = data;
|
var data:SwagSong = data;
|
||||||
if (Reflect.hasField(data, "song")) {
|
if (Reflect.hasField(data, "song")) {
|
||||||
var field:Dynamic = Reflect.field(data, "song");
|
var field:Dynamic = Reflect.field(data, "song");
|
||||||
if (!(field is String))
|
if (!(field is String))
|
||||||
data = field;
|
data = field;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.scrollSpeed = data.speed;
|
result.scrollSpeed = data.speed;
|
||||||
result.stage = data.stage;
|
result.stage = data.stage;
|
||||||
|
|
||||||
result.strumLines.push({
|
result.strumLines.push({
|
||||||
characters: [data.player2],
|
characters: [data.player2],
|
||||||
type: 0,
|
type: 0,
|
||||||
position: data.player2.startsWith("gf") ? "girlfriend" : "dad",
|
position: data.player2.startsWith("gf") ? "girlfriend" : "dad",
|
||||||
notes: []
|
notes: []
|
||||||
});
|
});
|
||||||
result.strumLines.push({
|
result.strumLines.push({
|
||||||
characters: [data.player1],
|
characters: [data.player1],
|
||||||
type: 1,
|
type: 1,
|
||||||
position: "boyfriend",
|
position: "boyfriend",
|
||||||
notes: []
|
notes: []
|
||||||
});
|
});
|
||||||
if (data.gf != "none") {
|
if (data.gf != "none") {
|
||||||
result.strumLines.push({
|
result.strumLines.push({
|
||||||
characters: [data.gf != null ? data.gf : "gf"],
|
characters: [data.gf != null ? data.gf : "gf"],
|
||||||
type: 2,
|
type: 2,
|
||||||
position: "girlfriend",
|
position: "girlfriend",
|
||||||
notes: [],
|
notes: [],
|
||||||
visible: false,
|
visible: false,
|
||||||
strumLinePos: 0.5
|
strumLinePos: 0.5
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
result.meta.bpm = data.bpm;
|
result.meta.bpm = data.bpm;
|
||||||
|
|
||||||
var camFocusedBF:Bool = false;
|
var camFocusedBF:Bool = false;
|
||||||
var beatsPerMesure:Float = data.beatsPerMesure.getDefault(4);
|
var beatsPerMesure:Float = data.beatsPerMesure.getDefault(4);
|
||||||
var curBPM:Float = data.bpm;
|
var curBPM:Float = data.bpm;
|
||||||
var curTime:Float = 0;
|
var curTime:Float = 0;
|
||||||
var curCrochet:Float = ((60 / curBPM) * 1000);
|
var curCrochet:Float = ((60 / curBPM) * 1000);
|
||||||
|
|
||||||
if (data.notes != null) for(section in data.notes) {
|
if (data.notes != null) for(section in data.notes) {
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
curTime += curCrochet * beatsPerMesure;
|
curTime += curCrochet * beatsPerMesure;
|
||||||
continue; // Yoshi Engine charts crash fix
|
continue; // Yoshi Engine charts crash fix
|
||||||
}
|
}
|
||||||
|
|
||||||
if (camFocusedBF != (camFocusedBF = section.mustHitSection)) {
|
if (camFocusedBF != (camFocusedBF = section.mustHitSection)) {
|
||||||
result.events.push({
|
result.events.push({
|
||||||
time: curTime,
|
time: curTime,
|
||||||
type: CAM_MOVEMENT,
|
type: CAM_MOVEMENT,
|
||||||
params: [camFocusedBF ? 1 : 0]
|
params: [camFocusedBF ? 1 : 0]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section.sectionNotes != null) for(note in section.sectionNotes) {
|
if (section.sectionNotes != null) for(note in section.sectionNotes) {
|
||||||
if (note[1] < 0) continue;
|
if (note[1] < 0) continue;
|
||||||
|
|
||||||
var daStrumTime:Float = note[0];
|
var daStrumTime:Float = note[0];
|
||||||
var daNoteData:Int = Std.int(note[1] % 8);
|
var daNoteData:Int = Std.int(note[1] % 8);
|
||||||
var daNoteType:Int = Std.int(note[1] / 8);
|
var daNoteType:Int = Std.int(note[1] / 8);
|
||||||
var gottaHitNote:Bool = daNoteData >= 4 ? !section.mustHitSection : section.mustHitSection;
|
var gottaHitNote:Bool = daNoteData >= 4 ? !section.mustHitSection : section.mustHitSection;
|
||||||
|
|
||||||
if (note.length > 2) {
|
if (note.length > 2) {
|
||||||
if (note[3] is Int)
|
if (note[3] is Int)
|
||||||
daNoteType = Chart.addNoteType(result, data.noteTypes[Std.int(note[3])-1]);
|
daNoteType = Chart.addNoteType(result, data.noteTypes[Std.int(note[3])-1]);
|
||||||
else if (note[3] is String)
|
else if (note[3] is String)
|
||||||
daNoteType = Chart.addNoteType(result, note[3]);
|
daNoteType = Chart.addNoteType(result, note[3]);
|
||||||
} else {
|
} else {
|
||||||
daNoteType = Chart.addNoteType(result, data.noteTypes[daNoteType-1]);
|
daNoteType = Chart.addNoteType(result, data.noteTypes[daNoteType-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
result.strumLines[gottaHitNote ? 1 : 0].notes.push({
|
result.strumLines[gottaHitNote ? 1 : 0].notes.push({
|
||||||
time: daStrumTime,
|
time: daStrumTime,
|
||||||
id: daNoteData % 4,
|
id: daNoteData % 4,
|
||||||
type: daNoteType,
|
type: daNoteType,
|
||||||
sLen: note[2]
|
sLen: note[2]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section.changeBPM && section.bpm != curBPM) {
|
if (section.changeBPM && section.bpm != curBPM) {
|
||||||
curCrochet = ((60 / (curBPM = section.bpm)) * 1000);
|
curCrochet = ((60 / (curBPM = section.bpm)) * 1000);
|
||||||
|
|
||||||
result.events.push({
|
result.events.push({
|
||||||
time: curTime,
|
time: curTime,
|
||||||
type: BPM_CHANGE,
|
type: BPM_CHANGE,
|
||||||
params: [section.bpm]
|
params: [section.bpm]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
curTime += curCrochet * beatsPerMesure;
|
curTime += curCrochet * beatsPerMesure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typedef SwagSong =
|
typedef SwagSong =
|
||||||
{
|
{
|
||||||
|
|||||||
+144
-144
@@ -13,42 +13,42 @@ import sys.FileSystem;
|
|||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
class Chart {
|
class Chart {
|
||||||
public static function loadChartMeta(songName:String, difficulty:String = "normal", fromMods:Bool = true) {
|
public static function loadChartMeta(songName:String, difficulty:String = "normal", fromMods:Bool = true) {
|
||||||
var metaPath = Paths.file('songs/${songName.toLowerCase()}/meta.json');
|
var metaPath = Paths.file('songs/${songName.toLowerCase()}/meta.json');
|
||||||
var metaDiffPath = Paths.file('songs/${songName.toLowerCase()}/meta-${difficulty.toLowerCase()}.json');
|
var metaDiffPath = Paths.file('songs/${songName.toLowerCase()}/meta-${difficulty.toLowerCase()}.json');
|
||||||
|
|
||||||
var data:ChartMetaData = null;
|
var data:ChartMetaData = null;
|
||||||
var fromMods:Bool = fromMods;
|
var fromMods:Bool = fromMods;
|
||||||
for(path in [metaDiffPath, metaPath]) {
|
for(path in [metaDiffPath, metaPath]) {
|
||||||
if (Assets.exists(path)) {
|
if (Assets.exists(path)) {
|
||||||
fromMods = Paths.assetsTree.existsSpecific(path, "TEXT", MODS);
|
fromMods = Paths.assetsTree.existsSpecific(path, "TEXT", MODS);
|
||||||
try {
|
try {
|
||||||
data = Json.parse(Assets.getText(path));
|
data = Json.parse(Assets.getText(path));
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Failed to load song metadata for ${songName} ($path): ${Std.string(e)}', ERROR);
|
Logs.trace('Failed to load song metadata for ${songName} ($path): ${Std.string(e)}', ERROR);
|
||||||
}
|
}
|
||||||
if (data != null) break;
|
if (data != null) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data == null)
|
if (data == null)
|
||||||
data = {
|
data = {
|
||||||
name: songName,
|
name: songName,
|
||||||
bpm: 100
|
bpm: 100
|
||||||
};
|
};
|
||||||
data.setFieldDefault("name", songName);
|
data.setFieldDefault("name", songName);
|
||||||
data.setFieldDefault("beatsPerMesure", 4);
|
data.setFieldDefault("beatsPerMesure", 4);
|
||||||
data.setFieldDefault("stepsPerBeat", 4);
|
data.setFieldDefault("stepsPerBeat", 4);
|
||||||
data.setFieldDefault("needsVoices", true);
|
data.setFieldDefault("needsVoices", true);
|
||||||
data.setFieldDefault("icon", "face");
|
data.setFieldDefault("icon", "face");
|
||||||
data.setFieldDefault("difficulties", []);
|
data.setFieldDefault("difficulties", []);
|
||||||
data.setFieldDefault("coopAllowed", false);
|
data.setFieldDefault("coopAllowed", false);
|
||||||
data.setFieldDefault("opponentModeAllowed", false);
|
data.setFieldDefault("opponentModeAllowed", false);
|
||||||
data.setFieldDefault("displayName", data.name);
|
data.setFieldDefault("displayName", data.name);
|
||||||
data.setFieldDefault("parsedColor", data.color.getColorFromDynamic());
|
data.setFieldDefault("parsedColor", data.color.getColorFromDynamic());
|
||||||
|
|
||||||
if (data.difficulties.length <= 0) {
|
if (data.difficulties.length <= 0) {
|
||||||
data.difficulties = [for(f in Paths.getFolderContent('songs/${songName.toLowerCase()}/charts/', false, !fromMods)) if (Path.extension(f = f.toUpperCase()) == "JSON") Path.withoutExtension(f)];
|
data.difficulties = [for(f in Paths.getFolderContent('songs/${songName.toLowerCase()}/charts/', false, !fromMods)) if (Path.extension(f = f.toUpperCase()) == "JSON") Path.withoutExtension(f)];
|
||||||
if (data.difficulties.length == 3) {
|
if (data.difficulties.length == 3) {
|
||||||
var hasHard = false, hasNormal = false, hasEasy = false;
|
var hasHard = false, hasNormal = false, hasEasy = false;
|
||||||
for(d in data.difficulties) {
|
for(d in data.difficulties) {
|
||||||
@@ -64,133 +64,133 @@ class Chart {
|
|||||||
data.difficulties[2] = "HARD";
|
data.difficulties[2] = "HARD";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.difficulties.length <= 0)
|
if (data.difficulties.length <= 0)
|
||||||
data.difficulties.push("CHART MISSING");
|
data.difficulties.push("CHART MISSING");
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function parse(songName:String, difficulty:String = "normal"):ChartData {
|
public static function parse(songName:String, difficulty:String = "normal"):ChartData {
|
||||||
var chartPath = Paths.chart(songName, difficulty);
|
var chartPath = Paths.chart(songName, difficulty);
|
||||||
var base:ChartData = {
|
var base:ChartData = {
|
||||||
strumLines: [],
|
strumLines: [],
|
||||||
noteTypes: [],
|
noteTypes: [],
|
||||||
events: [],
|
events: [],
|
||||||
meta: {
|
meta: {
|
||||||
name: null
|
name: null
|
||||||
},
|
},
|
||||||
scrollSpeed: 2,
|
scrollSpeed: 2,
|
||||||
stage: "stage",
|
stage: "stage",
|
||||||
codenameChart: true,
|
codenameChart: true,
|
||||||
fromMods: Paths.assetsTree.existsSpecific(chartPath, "TEXT", MODS)
|
fromMods: Paths.assetsTree.existsSpecific(chartPath, "TEXT", MODS)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!Assets.exists(chartPath)) {
|
if (!Assets.exists(chartPath)) {
|
||||||
Logs.trace('Chart for song ${songName} ($difficulty) at "$chartPath" was not found.', ERROR, RED);
|
Logs.trace('Chart for song ${songName} ($difficulty) at "$chartPath" was not found.', ERROR, RED);
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
var data:Dynamic = null;
|
var data:Dynamic = null;
|
||||||
try {
|
try {
|
||||||
data = Json.parse(Assets.getText(chartPath));
|
data = Json.parse(Assets.getText(chartPath));
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Could not parse chart for song ${songName} ($difficulty): ${Std.string(e)}', ERROR, RED);
|
Logs.trace('Could not parse chart for song ${songName} ($difficulty): ${Std.string(e)}', ERROR, RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CHART CONVERSION
|
* CHART CONVERSION
|
||||||
*/
|
*/
|
||||||
#if REGION
|
#if REGION
|
||||||
if (Reflect.hasField(data, "codenameChart") && Reflect.field(data, "codenameChart") == true) {
|
if (Reflect.hasField(data, "codenameChart") && Reflect.field(data, "codenameChart") == true) {
|
||||||
// codename chart
|
// codename chart
|
||||||
base = data;
|
base = data;
|
||||||
} else {
|
} else {
|
||||||
// base game chart
|
// base game chart
|
||||||
BaseGameParser.parse(data, base);
|
BaseGameParser.parse(data, base);
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
if (base.meta == null)
|
if (base.meta == null)
|
||||||
base.meta = loadChartMeta(songName, difficulty, base.fromMods);
|
base.meta = loadChartMeta(songName, difficulty, base.fromMods);
|
||||||
else {
|
else {
|
||||||
var loadedMeta = loadChartMeta(songName, difficulty, base.fromMods);
|
var loadedMeta = loadChartMeta(songName, difficulty, base.fromMods);
|
||||||
for(field in Reflect.fields(base.meta)) {
|
for(field in Reflect.fields(base.meta)) {
|
||||||
var f = Reflect.field(base.meta, field);
|
var f = Reflect.field(base.meta, field);
|
||||||
if (f != null)
|
if (f != null)
|
||||||
Reflect.setField(loadedMeta, field, f);
|
Reflect.setField(loadedMeta, field, f);
|
||||||
}
|
}
|
||||||
base.meta = loadedMeta;
|
base.meta = loadedMeta;
|
||||||
}
|
}
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function addNoteType(chart:ChartData, noteTypeName:String):Int {
|
public static function addNoteType(chart:ChartData, noteTypeName:String):Int {
|
||||||
switch(noteTypeName.trim()) {
|
switch(noteTypeName.trim()) {
|
||||||
case "Default Note" | null | "":
|
case "Default Note" | null | "":
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
var index = chart.noteTypes.indexOf(noteTypeName);
|
var index = chart.noteTypes.indexOf(noteTypeName);
|
||||||
if (index > -1)
|
if (index > -1)
|
||||||
return index+1;
|
return index+1;
|
||||||
chart.noteTypes.push(noteTypeName);
|
chart.noteTypes.push(noteTypeName);
|
||||||
return chart.noteTypes.length;
|
return chart.noteTypes.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the chart to the specific song folder path.
|
* Saves the chart to the specific song folder path.
|
||||||
* @param songFolderPath Path to the song folder (ex: `mods/your mod/songs/song/`)
|
* @param songFolderPath Path to the song folder (ex: `mods/your mod/songs/song/`)
|
||||||
* @param chart Chart to save
|
* @param chart Chart to save
|
||||||
* @param difficulty Name of the difficulty
|
* @param difficulty Name of the difficulty
|
||||||
* @param saveSettings
|
* @param saveSettings
|
||||||
* @return Filtered chart used for saving.
|
* @return Filtered chart used for saving.
|
||||||
*/
|
*/
|
||||||
public static function save(songFolderPath:String, chart:ChartData, difficulty:String = "normal", ?saveSettings:ChartSaveSettings):ChartData {
|
public static function save(songFolderPath:String, chart:ChartData, difficulty:String = "normal", ?saveSettings:ChartSaveSettings):ChartData {
|
||||||
if (saveSettings == null) saveSettings = {};
|
if (saveSettings == null) saveSettings = {};
|
||||||
|
|
||||||
var filteredChart = filterChartForSaving(chart, saveSettings.saveMetaInChart);
|
var filteredChart = filterChartForSaving(chart, saveSettings.saveMetaInChart);
|
||||||
var meta = filteredChart.meta;
|
var meta = filteredChart.meta;
|
||||||
|
|
||||||
// idk how null reacts to it so better be sure
|
// idk how null reacts to it so better be sure
|
||||||
|
|
||||||
#if sys
|
#if sys
|
||||||
if (!FileSystem.exists('${songFolderPath}\\charts\\'))
|
if (!FileSystem.exists('${songFolderPath}\\charts\\'))
|
||||||
FileSystem.createDirectory('${songFolderPath}\\charts\\');
|
FileSystem.createDirectory('${songFolderPath}\\charts\\');
|
||||||
|
|
||||||
var chartPath = '${songFolderPath}\\charts\\${difficulty.trim()}.json';
|
var chartPath = '${songFolderPath}\\charts\\${difficulty.trim()}.json';
|
||||||
var metaPath = '${songFolderPath}\\meta.json';
|
var metaPath = '${songFolderPath}\\meta.json';
|
||||||
|
|
||||||
File.saveContent(chartPath, Json.stringify(filteredChart, null, saveSettings.prettyPrint == true ? "\t" : null));
|
File.saveContent(chartPath, Json.stringify(filteredChart, null, saveSettings.prettyPrint == true ? "\t" : null));
|
||||||
|
|
||||||
if (saveSettings.overrideExistingMeta == true || !FileSystem.exists(metaPath))
|
if (saveSettings.overrideExistingMeta == true || !FileSystem.exists(metaPath))
|
||||||
File.saveContent(metaPath, Json.stringify(meta, null, saveSettings.prettyPrint == true ? "\t" : null));
|
File.saveContent(metaPath, Json.stringify(meta, null, saveSettings.prettyPrint == true ? "\t" : null));
|
||||||
#end
|
#end
|
||||||
return filteredChart;
|
return filteredChart;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function filterChartForSaving(chart:ChartData, ?saveMetaInChart:Null<Bool>):ChartData {
|
public static function filterChartForSaving(chart:ChartData, ?saveMetaInChart:Null<Bool>):ChartData {
|
||||||
var data = Reflect.copy(chart); // make a copy of the chart to leave the OG intact
|
var data = Reflect.copy(chart); // make a copy of the chart to leave the OG intact
|
||||||
if (saveMetaInChart != true) {
|
if (saveMetaInChart != true) {
|
||||||
data.meta = null;
|
data.meta = null;
|
||||||
} else {
|
} else {
|
||||||
data.meta = Reflect.copy(chart.meta); // also make a copy of the metadata to leave the OG intact.
|
data.meta = Reflect.copy(chart.meta); // also make a copy of the metadata to leave the OG intact.
|
||||||
if (data.meta != null) data.meta.parsedColor = null;
|
if (data.meta != null) data.meta.parsedColor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.fromMods = null;
|
data.fromMods = null;
|
||||||
|
|
||||||
var sortedData:Dynamic = {};
|
var sortedData:Dynamic = {};
|
||||||
for(f in Reflect.fields(data)) {
|
for(f in Reflect.fields(data)) {
|
||||||
var v = Reflect.field(data, f);
|
var v = Reflect.field(data, f);
|
||||||
if (v != null)
|
if (v != null)
|
||||||
Reflect.setField(sortedData, f, v);
|
Reflect.setField(sortedData, f, v);
|
||||||
}
|
}
|
||||||
return sortedData;
|
return sortedData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ChartSaveSettings = {
|
typedef ChartSaveSettings = {
|
||||||
var ?overrideExistingMeta:Bool;
|
var ?overrideExistingMeta:Bool;
|
||||||
var ?saveMetaInChart:Bool;
|
var ?saveMetaInChart:Bool;
|
||||||
var ?prettyPrint:Bool;
|
var ?prettyPrint:Bool;
|
||||||
}
|
}
|
||||||
@@ -3,102 +3,102 @@ package funkin.chart;
|
|||||||
import flixel.util.FlxColor;
|
import flixel.util.FlxColor;
|
||||||
|
|
||||||
typedef ChartData = {
|
typedef ChartData = {
|
||||||
public var strumLines:Array<ChartStrumLine>;
|
public var strumLines:Array<ChartStrumLine>;
|
||||||
public var events:Array<ChartEvent>;
|
public var events:Array<ChartEvent>;
|
||||||
public var meta:ChartMetaData;
|
public var meta:ChartMetaData;
|
||||||
public var codenameChart:Bool;
|
public var codenameChart:Bool;
|
||||||
public var stage:String;
|
public var stage:String;
|
||||||
public var scrollSpeed:Float;
|
public var scrollSpeed:Float;
|
||||||
public var noteTypes:Array<String>;
|
public var noteTypes:Array<String>;
|
||||||
|
|
||||||
public var ?fromMods:Bool;
|
public var ?fromMods:Bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ChartMetaData = {
|
typedef ChartMetaData = {
|
||||||
public var name:String;
|
public var name:String;
|
||||||
public var ?bpm:Float;
|
public var ?bpm:Float;
|
||||||
public var ?displayName:String;
|
public var ?displayName:String;
|
||||||
public var ?beatsPerMesure:Float;
|
public var ?beatsPerMesure:Float;
|
||||||
public var ?stepsPerBeat:Float;
|
public var ?stepsPerBeat:Float;
|
||||||
public var ?needsVoices:Bool;
|
public var ?needsVoices:Bool;
|
||||||
public var ?icon:String;
|
public var ?icon:String;
|
||||||
public var ?color:Dynamic;
|
public var ?color:Dynamic;
|
||||||
public var ?difficulties:Array<String>;
|
public var ?difficulties:Array<String>;
|
||||||
public var ?coopAllowed:Bool;
|
public var ?coopAllowed:Bool;
|
||||||
public var ?opponentModeAllowed:Bool;
|
public var ?opponentModeAllowed:Bool;
|
||||||
|
|
||||||
// NOT TO BE EXPORTED
|
// NOT TO BE EXPORTED
|
||||||
public var ?parsedColor:FlxColor;
|
public var ?parsedColor:FlxColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ChartStrumLine = {
|
typedef ChartStrumLine = {
|
||||||
var characters:Array<String>;
|
var characters:Array<String>;
|
||||||
var type:ChartStrumLineType;
|
var type:ChartStrumLineType;
|
||||||
var notes:Array<ChartNote>;
|
var notes:Array<ChartNote>;
|
||||||
var position:String;
|
var position:String;
|
||||||
var ?strumLinePos:Float; // 0.25 = default opponent pos, 0.75 = default boyfriend pos
|
var ?strumLinePos:Float; // 0.25 = default opponent pos, 0.75 = default boyfriend pos
|
||||||
var ?visible:Null<Bool>;
|
var ?visible:Null<Bool>;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ChartNote = {
|
typedef ChartNote = {
|
||||||
var time:Float; // time at which the note will be hit (ms)
|
var time:Float; // time at which the note will be hit (ms)
|
||||||
var id:Int; // strum id of the note
|
var id:Int; // strum id of the note
|
||||||
var type:Int; // type (int) of the note
|
var type:Int; // type (int) of the note
|
||||||
var sLen:Float; // sustain length of the note (ms)
|
var sLen:Float; // sustain length of the note (ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ChartEvent = {
|
typedef ChartEvent = {
|
||||||
var time:Float;
|
var time:Float;
|
||||||
var type:ChartEventType;
|
var type:ChartEventType;
|
||||||
var params:Array<Dynamic>;
|
var params:Array<Dynamic>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@:enum
|
@:enum
|
||||||
abstract ChartStrumLineType(Int) from Int to Int {
|
abstract ChartStrumLineType(Int) from Int to Int {
|
||||||
/**
|
/**
|
||||||
* STRUMLINE IS MARKED AS OPPONENT - WILL BE PLAYED BY CPU, OR PLAYED BY PLAYER IF OPPONENT MODE IS ON
|
* STRUMLINE IS MARKED AS OPPONENT - WILL BE PLAYED BY CPU, OR PLAYED BY PLAYER IF OPPONENT MODE IS ON
|
||||||
*/
|
*/
|
||||||
var OPPONENT = 0;
|
var OPPONENT = 0;
|
||||||
/**
|
/**
|
||||||
* STRUMLINE IS MARKED AS PLAYER - WILL BE PLAYED AS PLAYER, OR PLAYED AS CPU IF OPPONENT MODE IS ON
|
* STRUMLINE IS MARKED AS PLAYER - WILL BE PLAYED AS PLAYER, OR PLAYED AS CPU IF OPPONENT MODE IS ON
|
||||||
*/
|
*/
|
||||||
var PLAYER = 1;
|
var PLAYER = 1;
|
||||||
/**
|
/**
|
||||||
* STRUMLINE IS MARKED AS ADDITIONAL - WILL BE PLAYED AS CPU EVEN IF OPPONENT MODE IS ENABLED
|
* STRUMLINE IS MARKED AS ADDITIONAL - WILL BE PLAYED AS CPU EVEN IF OPPONENT MODE IS ENABLED
|
||||||
*/
|
*/
|
||||||
var ADDITIONAL = 2;
|
var ADDITIONAL = 2;
|
||||||
}
|
}
|
||||||
@:enum
|
@:enum
|
||||||
abstract ChartEventType(Int) from Int to Int {
|
abstract ChartEventType(Int) from Int to Int {
|
||||||
/**
|
/**
|
||||||
* CUSTOM EVENT
|
* CUSTOM EVENT
|
||||||
* Params:
|
* Params:
|
||||||
* - Function Name (String)
|
* - Function Name (String)
|
||||||
* - Function Parameters...
|
* - Function Parameters...
|
||||||
*/
|
*/
|
||||||
var CUSTOM = -1;
|
var CUSTOM = -1;
|
||||||
/**
|
/**
|
||||||
* NO EVENT, MADE FOR UNKNOWN EVENTS / EVENTS THAT CANNOT BE PARSED
|
* NO EVENT, MADE FOR UNKNOWN EVENTS / EVENTS THAT CANNOT BE PARSED
|
||||||
*/
|
*/
|
||||||
var NONE = 0;
|
var NONE = 0;
|
||||||
/**
|
/**
|
||||||
* CAMERA MOVEMENT EVENT
|
* CAMERA MOVEMENT EVENT
|
||||||
* Params:
|
* Params:
|
||||||
* - Target Strumline ID (Int)
|
* - Target Strumline ID (Int)
|
||||||
*/
|
*/
|
||||||
var CAM_MOVEMENT = 1;
|
var CAM_MOVEMENT = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BPM CHANGE EVENT
|
* BPM CHANGE EVENT
|
||||||
* Params:
|
* Params:
|
||||||
* - Target BPM (Float)
|
* - Target BPM (Float)
|
||||||
*/
|
*/
|
||||||
var BPM_CHANGE = 2;
|
var BPM_CHANGE = 2;
|
||||||
/**
|
/**
|
||||||
* ALT ANIM TOGGLE
|
* ALT ANIM TOGGLE
|
||||||
* Params:
|
* Params:
|
||||||
* - Strum Line which is going to be toggled (Int)
|
* - Strum Line which is going to be toggled (Int)
|
||||||
* - Whenever its going to be toggled or not (Bool)
|
* - Whenever its going to be toggled or not (Bool)
|
||||||
*/
|
*/
|
||||||
var ALT_ANIM_TOGGLE = 3;
|
var ALT_ANIM_TOGGLE = 3;
|
||||||
}
|
}
|
||||||
@@ -4,19 +4,19 @@ package funkin.cutscenes;
|
|||||||
* Substate made for cutscenes.
|
* Substate made for cutscenes.
|
||||||
*/
|
*/
|
||||||
class Cutscene extends MusicBeatSubstate {
|
class Cutscene extends MusicBeatSubstate {
|
||||||
var __callback:Void->Void;
|
var __callback:Void->Void;
|
||||||
var game:PlayState = PlayState.instance;
|
var game:PlayState = PlayState.instance;
|
||||||
|
|
||||||
public function new(callback:Void->Void) {
|
public function new(callback:Void->Void) {
|
||||||
super();
|
super();
|
||||||
__callback = callback;
|
__callback = callback;
|
||||||
}
|
}
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function close() {
|
public override function close() {
|
||||||
__callback();
|
__callback();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,78 +9,78 @@ import funkin.scripting.Script;
|
|||||||
* To add cutscenes to your songs, add a `cutscene.hx` file in your song's directory (ex: `songs/song/cutscene.hx`)
|
* To add cutscenes to your songs, add a `cutscene.hx` file in your song's directory (ex: `songs/song/cutscene.hx`)
|
||||||
*/
|
*/
|
||||||
class ScriptedCutscene extends Cutscene {
|
class ScriptedCutscene extends Cutscene {
|
||||||
var script:Script;
|
var script:Script;
|
||||||
|
|
||||||
var scriptPath:String;
|
var scriptPath:String;
|
||||||
public function new(scriptPath:String, callback:Void->Void) {
|
public function new(scriptPath:String, callback:Void->Void) {
|
||||||
super(callback);
|
super(callback);
|
||||||
|
|
||||||
script = Script.create(this.scriptPath = scriptPath);
|
script = Script.create(this.scriptPath = scriptPath);
|
||||||
script.setPublicMap(PlayState.instance.scripts.publicVariables);
|
script.setPublicMap(PlayState.instance.scripts.publicVariables);
|
||||||
script.setParent(this);
|
script.setParent(this);
|
||||||
script.load();
|
script.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
trace("fuck");
|
trace("fuck");
|
||||||
script.call("create");
|
script.call("create");
|
||||||
if (Std.isOfType(script, DummyScript)) {
|
if (Std.isOfType(script, DummyScript)) {
|
||||||
Logs.trace('Could not find script for scripted cutscene at ${scriptPath}', ERROR, RED);
|
Logs.trace('Could not find script for scripted cutscene at ${scriptPath}', ERROR, RED);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
script.call("update", [elapsed]);
|
script.call("update", [elapsed]);
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
script.call("postUpdate", [elapsed]);
|
script.call("postUpdate", [elapsed]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function beatHit(curBeat:Int) {
|
public override function beatHit(curBeat:Int) {
|
||||||
super.beatHit(curBeat);
|
super.beatHit(curBeat);
|
||||||
script.call("beatHit", [curBeat]);
|
script.call("beatHit", [curBeat]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function stepHit(curStep:Int) {
|
public override function stepHit(curStep:Int) {
|
||||||
super.stepHit(curStep);
|
super.stepHit(curStep);
|
||||||
script.call("stepHit", [curStep]);
|
script.call("stepHit", [curStep]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
script.call("destroy");
|
script.call("destroy");
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
// VIDEOS
|
// VIDEOS
|
||||||
#if REGION
|
#if REGION
|
||||||
public function startVideo(path:String, ?callback:Void->Void) {
|
public function startVideo(path:String, ?callback:Void->Void) {
|
||||||
persistentDraw = false;
|
persistentDraw = false;
|
||||||
openSubState(new VideoCutscene(path, function() {
|
openSubState(new VideoCutscene(path, function() {
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback();
|
callback();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public var isVideoPlaying(get, null):Bool;
|
public var isVideoPlaying(get, null):Bool;
|
||||||
|
|
||||||
private inline function get_isVideoPlaying()
|
private inline function get_isVideoPlaying()
|
||||||
return subState is VideoCutscene;
|
return subState is VideoCutscene;
|
||||||
#end
|
#end
|
||||||
|
|
||||||
// DIALOGUE
|
// DIALOGUE
|
||||||
#if REGION
|
#if REGION
|
||||||
public function startDialogue(path:String, ?callback:Void->Void) {
|
public function startDialogue(path:String, ?callback:Void->Void) {
|
||||||
persistentDraw = true;
|
persistentDraw = true;
|
||||||
openSubState(new VideoCutscene(path, function() {
|
openSubState(new VideoCutscene(path, function() {
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback();
|
callback();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public var isDialoguePlaying(get, null):Bool;
|
public var isDialoguePlaying(get, null):Bool;
|
||||||
|
|
||||||
private inline function get_isDialoguePlaying()
|
private inline function get_isDialoguePlaying()
|
||||||
return subState is DialogueCutscene;
|
return subState is DialogueCutscene;
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
@@ -5,52 +5,52 @@ package funkin.cutscenes;
|
|||||||
* Substate made for video cutscenes. To use it in a scripted cutscene, call `startVideo`.
|
* Substate made for video cutscenes. To use it in a scripted cutscene, call `startVideo`.
|
||||||
*/
|
*/
|
||||||
class VideoCutscene extends Cutscene {
|
class VideoCutscene extends Cutscene {
|
||||||
var path:String;
|
var path:String;
|
||||||
var localPath:String;
|
var localPath:String;
|
||||||
|
|
||||||
#if VIDEO_CUTSCENES
|
#if VIDEO_CUTSCENES
|
||||||
var video:MP4Handler;
|
var video:MP4Handler;
|
||||||
var videoSprite:FlxSprite;
|
var videoSprite:FlxSprite;
|
||||||
#end
|
#end
|
||||||
var cutsceneCamera:FlxCamera;
|
var cutsceneCamera:FlxCamera;
|
||||||
|
|
||||||
public function new(path:String, callback:Void->Void) {
|
public function new(path:String, callback:Void->Void) {
|
||||||
super(callback);
|
super(callback);
|
||||||
localPath = Assets.getPath(this.path = path);
|
localPath = Assets.getPath(this.path = path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
cutsceneCamera = new FlxCamera();
|
cutsceneCamera = new FlxCamera();
|
||||||
cutsceneCamera.bgColor = 0;
|
cutsceneCamera.bgColor = 0;
|
||||||
FlxG.cameras.add(cutsceneCamera, false);
|
FlxG.cameras.add(cutsceneCamera, false);
|
||||||
|
|
||||||
#if VIDEO_CUTSCENES
|
#if VIDEO_CUTSCENES
|
||||||
video = new MP4Handler();
|
video = new MP4Handler();
|
||||||
video.finishCallback = close;
|
video.finishCallback = close;
|
||||||
video.canvasWidth = cutsceneCamera.width;
|
video.canvasWidth = cutsceneCamera.width;
|
||||||
video.canvasHeight = cutsceneCamera.height;
|
video.canvasHeight = cutsceneCamera.height;
|
||||||
|
|
||||||
videoSprite = new FlxSprite();
|
videoSprite = new FlxSprite();
|
||||||
videoSprite.cameras = [cutsceneCamera];
|
videoSprite.cameras = [cutsceneCamera];
|
||||||
videoSprite.antialiasing = true;
|
videoSprite.antialiasing = true;
|
||||||
add(videoSprite);
|
add(videoSprite);
|
||||||
|
|
||||||
video.playMP4(localPath, false, videoSprite);
|
video.playMP4(localPath, false, videoSprite);
|
||||||
#end
|
#end
|
||||||
|
|
||||||
cameras = [cutsceneCamera];
|
cameras = [cutsceneCamera];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
#if !VIDEO_CUTSCENES
|
#if !VIDEO_CUTSCENES
|
||||||
close();
|
close();
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
FlxG.cameras.remove(cutsceneCamera, true);
|
FlxG.cameras.remove(cutsceneCamera, true);
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,113 +6,113 @@ import flixel.math.FlxPoint;
|
|||||||
import haxe.xml.Access;
|
import haxe.xml.Access;
|
||||||
|
|
||||||
class DialogueBox extends FunkinSprite {
|
class DialogueBox extends FunkinSprite {
|
||||||
public var dialogueBoxData:Access;
|
public var dialogueBoxData:Access;
|
||||||
public var positions:Map<String, CharPosDef> = [];
|
public var positions:Map<String, CharPosDef> = [];
|
||||||
|
|
||||||
public var textTypeSFX:String = Paths.sound('dialogue/text');
|
public var textTypeSFX:String = Paths.sound('dialogue/text');
|
||||||
public var nextSFX:String = Paths.sound('dialogue/next');
|
public var nextSFX:String = Paths.sound('dialogue/next');
|
||||||
|
|
||||||
public var text:FlxTypeText;
|
public var text:FlxTypeText;
|
||||||
|
|
||||||
public function new(name:String) {
|
public function new(name:String) {
|
||||||
super();
|
super();
|
||||||
try {
|
try {
|
||||||
dialogueBoxData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/boxes/$name'))).firstElement());
|
dialogueBoxData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/boxes/$name'))).firstElement());
|
||||||
|
|
||||||
loadSprite(Paths.image('dialogue/boxes/${dialogueBoxData.getAtt('sprite').getDefault(name)}'));
|
loadSprite(Paths.image('dialogue/boxes/${dialogueBoxData.getAtt('sprite').getDefault(name)}'));
|
||||||
|
|
||||||
for(anim in dialogueBoxData.nodes.anim) {
|
for(anim in dialogueBoxData.nodes.anim) {
|
||||||
if (!anim.has.name) continue;
|
if (!anim.has.name) continue;
|
||||||
XMLUtil.addXMLAnimation(this, anim);
|
XMLUtil.addXMLAnimation(this, anim);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(pos in dialogueBoxData.nodes.charpos) {
|
for(pos in dialogueBoxData.nodes.charpos) {
|
||||||
if (!pos.has.name) continue;
|
if (!pos.has.name) continue;
|
||||||
positions[pos.att.name] = {
|
positions[pos.att.name] = {
|
||||||
x: pos.has.x ? Std.parseFloat(pos.att.x).getDefault(0) : 0,
|
x: pos.has.x ? Std.parseFloat(pos.att.x).getDefault(0) : 0,
|
||||||
y: pos.has.y ? Std.parseFloat(pos.att.y).getDefault(0) : 0,
|
y: pos.has.y ? Std.parseFloat(pos.att.y).getDefault(0) : 0,
|
||||||
flipBubble: pos.getAtt('flipBubble') == "true"
|
flipBubble: pos.getAtt('flipBubble') == "true"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogueBoxData.has.textSound) textTypeSFX = Paths.sound(dialogueBoxData.att.textSound);
|
if (dialogueBoxData.has.textSound) textTypeSFX = Paths.sound(dialogueBoxData.att.textSound);
|
||||||
if (dialogueBoxData.has.nextSound) nextSFX = Paths.sound(dialogueBoxData.att.nextSound);
|
if (dialogueBoxData.has.nextSound) nextSFX = Paths.sound(dialogueBoxData.att.nextSound);
|
||||||
|
|
||||||
antialiasing = dialogueBoxData.getAtt("antialiasing").getDefault("true") == "true";
|
antialiasing = dialogueBoxData.getAtt("antialiasing").getDefault("true") == "true";
|
||||||
screenCenter(X);
|
screenCenter(X);
|
||||||
y = FlxG.height - height;
|
y = FlxG.height - height;
|
||||||
if (dialogueBoxData.has.x) x += Std.parseFloat(dialogueBoxData.att.x).getDefault(0);
|
if (dialogueBoxData.has.x) x += Std.parseFloat(dialogueBoxData.att.x).getDefault(0);
|
||||||
if (dialogueBoxData.has.y) y += Std.parseFloat(dialogueBoxData.att.y).getDefault(0);
|
if (dialogueBoxData.has.y) y += Std.parseFloat(dialogueBoxData.att.y).getDefault(0);
|
||||||
visible = false;
|
visible = false;
|
||||||
|
|
||||||
var textNode = dialogueBoxData.node.text;
|
var textNode = dialogueBoxData.node.text;
|
||||||
if (textNode == null)
|
if (textNode == null)
|
||||||
throw "The dialog box XML requires one text element.";
|
throw "The dialog box XML requires one text element.";
|
||||||
text = new FlxTypeText(
|
text = new FlxTypeText(
|
||||||
textNode.has.x ? Std.parseFloat(textNode.att.x).getDefault(0) : 0,
|
textNode.has.x ? Std.parseFloat(textNode.att.x).getDefault(0) : 0,
|
||||||
FlxG.height - (textNode.has.y ? Std.parseFloat(textNode.att.y).getDefault(0) : 0),
|
FlxG.height - (textNode.has.y ? Std.parseFloat(textNode.att.y).getDefault(0) : 0),
|
||||||
textNode.has.width ? Std.parseInt(textNode.att.width).getDefault(FlxG.width) : FlxG.width, "");
|
textNode.has.width ? Std.parseInt(textNode.att.width).getDefault(FlxG.width) : FlxG.width, "");
|
||||||
text.color = textNode.getAtt("color").getColorFromDynamic().getDefault(0xFF000000);
|
text.color = textNode.getAtt("color").getColorFromDynamic().getDefault(0xFF000000);
|
||||||
text.size = Std.parseInt(textNode.att.size).getDefault(20);
|
text.size = Std.parseInt(textNode.att.size).getDefault(20);
|
||||||
text.font = Paths.font('${textNode.getAtt("font").getDefault("vcr.ttf")}');
|
text.font = Paths.font('${textNode.getAtt("font").getDefault("vcr.ttf")}');
|
||||||
text.antialiasing = textNode.getAtt("antialiasing").getDefault("false") == "true";
|
text.antialiasing = textNode.getAtt("antialiasing").getDefault("false") == "true";
|
||||||
text.sounds = [FlxG.sound.load(textTypeSFX)];
|
text.sounds = [FlxG.sound.load(textTypeSFX)];
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
active = false;
|
active = false;
|
||||||
Logs.trace('Couldn\'t load dialogue box "$name": ${e.toString()}', ERROR);
|
Logs.trace('Couldn\'t load dialogue box "$name": ${e.toString()}', ERROR);
|
||||||
}
|
}
|
||||||
FlxG.sound.cache(nextSFX);
|
FlxG.sound.cache(nextSFX);
|
||||||
FlxG.sound.cache(textTypeSFX);
|
FlxG.sound.cache(textTypeSFX);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function popupChar(char:DialogueCharacter) {
|
public function popupChar(char:DialogueCharacter) {
|
||||||
if (!active) return;
|
if (!active) return;
|
||||||
var pos = positions[char.positionName];
|
var pos = positions[char.positionName];
|
||||||
if (pos == null) return;
|
if (pos == null) return;
|
||||||
|
|
||||||
char.show((FlxG.width / 2) + pos.x, FlxG.height - pos.y);
|
char.show((FlxG.width / 2) + pos.x, FlxG.height - pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private var __nextText:String;
|
private var __nextText:String;
|
||||||
private var __speed:Float;
|
private var __speed:Float;
|
||||||
public function playBubbleAnim(bubble:String, text:String, speed:Float = 0.05) {
|
public function playBubbleAnim(bubble:String, text:String, speed:Float = 0.05) {
|
||||||
this.__nextText = text;
|
this.__nextText = text;
|
||||||
this.__speed = speed;
|
this.__speed = speed;
|
||||||
this.text.resetText(text);
|
this.text.resetText(text);
|
||||||
FlxG.sound.play(nextSFX);
|
FlxG.sound.play(nextSFX);
|
||||||
if (hasAnimation('$bubble-open'))
|
if (hasAnimation('$bubble-open'))
|
||||||
playAnim('$bubble-open', true);
|
playAnim('$bubble-open', true);
|
||||||
else {
|
else {
|
||||||
playAnim(bubble);
|
playAnim(bubble);
|
||||||
setText(__nextText, __speed);
|
setText(__nextText, __speed);
|
||||||
}
|
}
|
||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setText(text:String, speed:Float = 0.02) {
|
public function setText(text:String, speed:Float = 0.02) {
|
||||||
this.text.delay = speed;
|
this.text.delay = speed;
|
||||||
this.text.start(speed, true);
|
this.text.start(speed, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
if (isAnimFinished()) {
|
if (isAnimFinished()) {
|
||||||
var animName = getAnimName();
|
var animName = getAnimName();
|
||||||
if (animName.endsWith("-open")) {
|
if (animName.endsWith("-open")) {
|
||||||
playAnim(animName.substr(0, animName.length - 5));
|
playAnim(animName.substr(0, animName.length - 5));
|
||||||
setText(__nextText, __speed);
|
setText(__nextText, __speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
positions = null;
|
positions = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef CharPosDef = {
|
typedef CharPosDef = {
|
||||||
var x:Float;
|
var x:Float;
|
||||||
var y:Float;
|
var y:Float;
|
||||||
var flipBubble:Bool;
|
var flipBubble:Bool;
|
||||||
}
|
}
|
||||||
@@ -4,56 +4,56 @@ import flixel.tweens.FlxTween;
|
|||||||
import haxe.xml.Access;
|
import haxe.xml.Access;
|
||||||
|
|
||||||
class DialogueCharacter extends FunkinSprite {
|
class DialogueCharacter extends FunkinSprite {
|
||||||
public var charData:Access;
|
public var charData:Access;
|
||||||
public var curTween:FlxTween;
|
public var curTween:FlxTween;
|
||||||
public var curTweenContext:DialogueCharTweenContext = NONE;
|
public var curTweenContext:DialogueCharTweenContext = NONE;
|
||||||
public var positionName:String;
|
public var positionName:String;
|
||||||
|
|
||||||
public function new(name:String, position:String) {
|
public function new(name:String, position:String) {
|
||||||
super();
|
super();
|
||||||
this.positionName = position;
|
this.positionName = position;
|
||||||
try {
|
try {
|
||||||
charData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/characters/$name'))).firstElement());
|
charData = new Access(Xml.parse(Assets.getText(Paths.xml('dialogue/characters/$name'))).firstElement());
|
||||||
loadSprite(Paths.image('dialogue/characters/${charData.getAtt('sprite').getDefault(name)}'));
|
loadSprite(Paths.image('dialogue/characters/${charData.getAtt('sprite').getDefault(name)}'));
|
||||||
antialiasing = charData.getAtt('antialiasing').getDefault('true') == 'true';
|
antialiasing = charData.getAtt('antialiasing').getDefault('true') == 'true';
|
||||||
scale.scale(charData.has.scale ? Std.parseFloat(charData.att.scale).getDefault(1) : 1);
|
scale.scale(charData.has.scale ? Std.parseFloat(charData.att.scale).getDefault(1) : 1);
|
||||||
updateHitbox();
|
updateHitbox();
|
||||||
offset.set(
|
offset.set(
|
||||||
charData.has.x ? Std.parseFloat(charData.att.x).getDefault(0) : 0,
|
charData.has.x ? Std.parseFloat(charData.att.x).getDefault(0) : 0,
|
||||||
(charData.has.y ? Std.parseFloat(charData.att.y).getDefault(0) : 0) + this.height);
|
(charData.has.y ? Std.parseFloat(charData.att.y).getDefault(0) : 0) + this.height);
|
||||||
for(anim in charData.nodes.anim)
|
for(anim in charData.nodes.anim)
|
||||||
XMLUtil.addXMLAnimation(this, anim, true);
|
XMLUtil.addXMLAnimation(this, anim, true);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Failed to load dialogue character $name: ${e.toString()}', ERROR);
|
Logs.trace('Failed to load dialogue character $name: ${e.toString()}', ERROR);
|
||||||
}
|
}
|
||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(x:Float, y:Float) {
|
public function show(x:Float, y:Float) {
|
||||||
if (curTweenContext != (curTweenContext = POPIN)) {
|
if (curTweenContext != (curTweenContext = POPIN)) {
|
||||||
setPosition(x, y + 100);
|
setPosition(x, y + 100);
|
||||||
if (curTween != null)
|
if (curTween != null)
|
||||||
curTween.cancel();
|
curTween.cancel();
|
||||||
|
|
||||||
alpha = 0;
|
alpha = 0;
|
||||||
visible = true;
|
visible = true;
|
||||||
|
|
||||||
curTween = FlxTween.tween(this, {alpha: 1, y: y}, 0.2, {ease: FlxEase.quintOut});
|
curTween = FlxTween.tween(this, {alpha: 1, y: y}, 0.2, {ease: FlxEase.quintOut});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hide() {
|
public function hide() {
|
||||||
if (curTweenContext != (curTweenContext = POPOUT)) {
|
if (curTweenContext != (curTweenContext = POPOUT)) {
|
||||||
if (curTween != null)
|
if (curTween != null)
|
||||||
curTween.cancel();
|
curTween.cancel();
|
||||||
|
|
||||||
curTween = FlxTween.tween(this, {alpha: 0, y: y + 100}, 0.2, {ease: FlxEase.quintIn});
|
curTween = FlxTween.tween(this, {alpha: 0, y: y + 100}, 0.2, {ease: FlxEase.quintIn});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum abstract DialogueCharTweenContext(Int) {
|
enum abstract DialogueCharTweenContext(Int) {
|
||||||
var NONE = -1;
|
var NONE = -1;
|
||||||
var POPIN = 0;
|
var POPIN = 0;
|
||||||
var POPOUT = 1;
|
var POPOUT = 1;
|
||||||
}
|
}
|
||||||
@@ -6,43 +6,43 @@ import funkin.options.TreeMenu;
|
|||||||
import funkin.windows.WindowsAPI;
|
import funkin.windows.WindowsAPI;
|
||||||
|
|
||||||
class DebugOptions extends TreeMenu {
|
class DebugOptions extends TreeMenu {
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
FlxG.camera.fade(0xFF000000, 0.5, true);
|
FlxG.camera.fade(0xFF000000, 0.5, true);
|
||||||
|
|
||||||
|
|
||||||
var bg:FlxSprite = new FlxSprite(-80).loadAnimatedGraphic(Paths.image('menus/menuBGBlue'));
|
var bg:FlxSprite = new FlxSprite(-80).loadAnimatedGraphic(Paths.image('menus/menuBGBlue'));
|
||||||
// bg.scrollFactor.set();
|
// bg.scrollFactor.set();
|
||||||
bg.scale.set(1.15, 1.15);
|
bg.scale.set(1.15, 1.15);
|
||||||
bg.updateHitbox();
|
bg.updateHitbox();
|
||||||
bg.screenCenter();
|
bg.screenCenter();
|
||||||
bg.scrollFactor.set();
|
bg.scrollFactor.set();
|
||||||
bg.antialiasing = true;
|
bg.antialiasing = true;
|
||||||
add(bg);
|
add(bg);
|
||||||
|
|
||||||
main = new DebugOptionsScreen();
|
main = new DebugOptionsScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DebugOptionsScreen extends OptionsScreen {
|
class DebugOptionsScreen extends OptionsScreen {
|
||||||
public override function new() {
|
public override function new() {
|
||||||
super("Debug Options", "Use this menu to change debug options.");
|
super("Debug Options", "Use this menu to change debug options.");
|
||||||
#if windows
|
#if windows
|
||||||
add(new TextOption(
|
add(new TextOption(
|
||||||
"Show Console",
|
"Show Console",
|
||||||
"Select this to show the debug console, which contains log information about the game.",
|
"Select this to show the debug console, which contains log information about the game.",
|
||||||
function() {
|
function() {
|
||||||
WindowsAPI.allocConsole();
|
WindowsAPI.allocConsole();
|
||||||
}));
|
}));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Enable Editor SFXs",
|
"Enable Editor SFXs",
|
||||||
"If checked, will play sound effects when working on editors (ex: will play sfxs when checking checkboxes...)",
|
"If checked, will play sound effects when working on editors (ex: will play sfxs when checking checkboxes...)",
|
||||||
"editorSFX"));
|
"editorSFX"));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Resizable Editors",
|
"Resizable Editors",
|
||||||
"If checked, editors will be resizable and extensible like other programs instead of zooming in upon maximization.",
|
"If checked, editors will be resizable and extensible like other programs instead of zooming in upon maximization.",
|
||||||
"resizableEditors"));
|
"resizableEditors"));
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,199 +5,199 @@ import flixel.math.FlxPoint;
|
|||||||
import flixel.effects.FlxFlicker;
|
import flixel.effects.FlxFlicker;
|
||||||
|
|
||||||
class EditorPicker extends MusicBeatSubstate {
|
class EditorPicker extends MusicBeatSubstate {
|
||||||
public var bg:FlxSprite;
|
public var bg:FlxSprite;
|
||||||
|
|
||||||
public var options:Array<Editor> = [
|
public var options:Array<Editor> = [
|
||||||
{
|
{
|
||||||
name: "Chart Editor",
|
name: "Chart Editor",
|
||||||
iconID: 0,
|
iconID: 0,
|
||||||
state: funkin.editors.charter.CharterSelection
|
state: funkin.editors.charter.CharterSelection
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Character Editor",
|
name: "Character Editor",
|
||||||
iconID: 1,
|
iconID: 1,
|
||||||
state: null
|
state: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Stage Editor",
|
name: "Stage Editor",
|
||||||
iconID: 2,
|
iconID: 2,
|
||||||
state: null
|
state: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "UI Debug State",
|
name: "UI Debug State",
|
||||||
iconID: 3,
|
iconID: 3,
|
||||||
state: UIDebugState
|
state: UIDebugState
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Debug Options",
|
name: "Debug Options",
|
||||||
iconID: 4,
|
iconID: 4,
|
||||||
state: DebugOptions
|
state: DebugOptions
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
public var sprites:Array<EditorPickerOption> = [];
|
public var sprites:Array<EditorPickerOption> = [];
|
||||||
|
|
||||||
public var curSelected:Int = 0;
|
public var curSelected:Int = 0;
|
||||||
|
|
||||||
|
|
||||||
public var oldMousePos:FlxPoint = FlxPoint.get();
|
public var oldMousePos:FlxPoint = FlxPoint.get();
|
||||||
public var curMousePos:FlxPoint = FlxPoint.get();
|
public var curMousePos:FlxPoint = FlxPoint.get();
|
||||||
|
|
||||||
public var optionHeight:Float = 0;
|
public var optionHeight:Float = 0;
|
||||||
|
|
||||||
public var selected:Bool = false;
|
public var selected:Bool = false;
|
||||||
|
|
||||||
public var camVelocity:Float = 0;
|
public var camVelocity:Float = 0;
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
camera = new FlxCamera();
|
camera = new FlxCamera();
|
||||||
camera.bgColor = 0;
|
camera.bgColor = 0;
|
||||||
FlxG.cameras.add(camera, false);
|
FlxG.cameras.add(camera, false);
|
||||||
|
|
||||||
bg = new FlxSprite().makeGraphic(1, 1, 0xFF000000);
|
bg = new FlxSprite().makeGraphic(1, 1, 0xFF000000);
|
||||||
bg.scrollFactor.set();
|
bg.scrollFactor.set();
|
||||||
bg.scale.set(FlxG.width, FlxG.height);
|
bg.scale.set(FlxG.width, FlxG.height);
|
||||||
bg.updateHitbox();
|
bg.updateHitbox();
|
||||||
bg.alpha = 0;
|
bg.alpha = 0;
|
||||||
add(bg);
|
add(bg);
|
||||||
|
|
||||||
optionHeight = FlxG.height / options.length;
|
optionHeight = FlxG.height / options.length;
|
||||||
for(k=>o in options) {
|
for(k=>o in options) {
|
||||||
var spr = new EditorPickerOption(o.name, o.iconID, optionHeight);
|
var spr = new EditorPickerOption(o.name, o.iconID, optionHeight);
|
||||||
spr.y = k * optionHeight;
|
spr.y = k * optionHeight;
|
||||||
add(spr);
|
add(spr);
|
||||||
sprites.push(spr);
|
sprites.push(spr);
|
||||||
}
|
}
|
||||||
sprites[0].selected = true;
|
sprites[0].selected = true;
|
||||||
|
|
||||||
FlxG.mouse.getScreenPosition(camera, oldMousePos);
|
FlxG.mouse.getScreenPosition(camera, oldMousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
bg.alpha = CoolUtil.fpsLerp(bg.alpha, selected ? 1 : 0.5, 0.25);
|
bg.alpha = CoolUtil.fpsLerp(bg.alpha, selected ? 1 : 0.5, 0.25);
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
camVelocity += FlxG.width * elapsed * 2;
|
camVelocity += FlxG.width * elapsed * 2;
|
||||||
camera.scroll.x += camVelocity * elapsed;
|
camera.scroll.x += camVelocity * elapsed;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
changeSelection(-FlxG.mouse.wheel + (controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0));
|
changeSelection(-FlxG.mouse.wheel + (controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0));
|
||||||
|
|
||||||
FlxG.mouse.getScreenPosition(camera, curMousePos);
|
FlxG.mouse.getScreenPosition(camera, curMousePos);
|
||||||
if (curMousePos.x != oldMousePos.x || curMousePos.y != oldMousePos.y) {
|
if (curMousePos.x != oldMousePos.x || curMousePos.y != oldMousePos.y) {
|
||||||
oldMousePos.set(curMousePos.x, curMousePos.y);
|
oldMousePos.set(curMousePos.x, curMousePos.y);
|
||||||
curSelected = -1;
|
curSelected = -1;
|
||||||
changeSelection(Std.int(curMousePos.y / optionHeight)+1);
|
changeSelection(Std.int(curMousePos.y / optionHeight)+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controls.ACCEPT || FlxG.mouse.justReleased) {
|
if (controls.ACCEPT || FlxG.mouse.justReleased) {
|
||||||
selected = true;
|
selected = true;
|
||||||
CoolUtil.playMenuSFX(CONFIRM);
|
CoolUtil.playMenuSFX(CONFIRM);
|
||||||
|
|
||||||
FlxTransitionableState.skipNextTransIn = true;
|
FlxTransitionableState.skipNextTransIn = true;
|
||||||
FlxTransitionableState.skipNextTransOut = true;
|
FlxTransitionableState.skipNextTransOut = true;
|
||||||
|
|
||||||
FlxG.sound.music.fadeOut(0.7, 0, function(n) {
|
FlxG.sound.music.fadeOut(0.7, 0, function(n) {
|
||||||
FlxG.sound.music.stop();
|
FlxG.sound.music.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
sprites[curSelected].flicker(function() {
|
sprites[curSelected].flicker(function() {
|
||||||
if (FlxG.sound.music != null)
|
if (FlxG.sound.music != null)
|
||||||
camera.fade(0xFF000000, 0.25, false, function() {
|
camera.fade(0xFF000000, 0.25, false, function() {
|
||||||
FlxG.switchState(Type.createInstance(options[curSelected].state, []));
|
FlxG.switchState(Type.createInstance(options[curSelected].state, []));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (controls.BACK)
|
if (controls.BACK)
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changeSelection(change:Int) {
|
public function changeSelection(change:Int) {
|
||||||
if (change == 0) return;
|
if (change == 0) return;
|
||||||
|
|
||||||
curSelected = FlxMath.wrap(curSelected + change, 0, sprites.length-1);
|
curSelected = FlxMath.wrap(curSelected + change, 0, sprites.length-1);
|
||||||
|
|
||||||
for(o in sprites)
|
for(o in sprites)
|
||||||
o.selected = false;
|
o.selected = false;
|
||||||
sprites[curSelected].selected = true;
|
sprites[curSelected].selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef Editor = {
|
typedef Editor = {
|
||||||
var name:String;
|
var name:String;
|
||||||
var iconID:Int;
|
var iconID:Int;
|
||||||
var state:Class<MusicBeatState>;
|
var state:Class<MusicBeatState>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditorPickerOption extends FlxTypedSpriteGroup<FlxSprite> {
|
class EditorPickerOption extends FlxTypedSpriteGroup<FlxSprite> {
|
||||||
public var iconSpr:FlxSprite;
|
public var iconSpr:FlxSprite;
|
||||||
public var label:Alphabet;
|
public var label:Alphabet;
|
||||||
|
|
||||||
public var selectionBG:FlxSprite;
|
public var selectionBG:FlxSprite;
|
||||||
|
|
||||||
public var selected:Bool = false;
|
public var selected:Bool = false;
|
||||||
|
|
||||||
public var selectionLerp:Float = 0;
|
public var selectionLerp:Float = 0;
|
||||||
|
|
||||||
public var iconRotationCycle:Float = 0;
|
public var iconRotationCycle:Float = 0;
|
||||||
public function new(name:String, iconID:Int, height:Float) {
|
public function new(name:String, iconID:Int, height:Float) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
|
||||||
FlxG.mouse.visible = true;
|
FlxG.mouse.visible = true;
|
||||||
iconSpr = new FlxSprite();
|
iconSpr = new FlxSprite();
|
||||||
iconSpr.loadGraphic(Paths.image('editors/icons'), true, 128, 128);
|
iconSpr.loadGraphic(Paths.image('editors/icons'), true, 128, 128);
|
||||||
iconSpr.animation.add("icon", [iconID], 24, true);
|
iconSpr.animation.add("icon", [iconID], 24, true);
|
||||||
iconSpr.animation.play("icon");
|
iconSpr.animation.play("icon");
|
||||||
iconSpr.antialiasing = true;
|
iconSpr.antialiasing = true;
|
||||||
if (height < 150) {
|
if (height < 150) {
|
||||||
iconSpr.scale.set(height / 150, height / 150);
|
iconSpr.scale.set(height / 150, height / 150);
|
||||||
iconSpr.updateHitbox();
|
iconSpr.updateHitbox();
|
||||||
}
|
}
|
||||||
iconSpr.x = 25 + ((height - iconSpr.width) / 2);
|
iconSpr.x = 25 + ((height - iconSpr.width) / 2);
|
||||||
iconSpr.y = (height - iconSpr.height) / 2;
|
iconSpr.y = (height - iconSpr.height) / 2;
|
||||||
|
|
||||||
label = new Alphabet(25 + iconSpr.width + 25, 0, name, true);
|
label = new Alphabet(25 + iconSpr.width + 25, 0, name, true);
|
||||||
label.y = (height - label.height) / 2;
|
label.y = (height - label.height) / 2;
|
||||||
|
|
||||||
selectionBG = new FlxSprite().makeGraphic(1, 1, -1);
|
selectionBG = new FlxSprite().makeGraphic(1, 1, -1);
|
||||||
selectionBG.scale.set(FlxG.width, height);
|
selectionBG.scale.set(FlxG.width, height);
|
||||||
selectionBG.updateHitbox();
|
selectionBG.updateHitbox();
|
||||||
selectionBG.alpha = 0;
|
selectionBG.alpha = 0;
|
||||||
|
|
||||||
add(selectionBG);
|
add(selectionBG);
|
||||||
add(iconSpr);
|
add(iconSpr);
|
||||||
add(label);
|
add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
iconRotationCycle += elapsed;
|
iconRotationCycle += elapsed;
|
||||||
|
|
||||||
selectionLerp = CoolUtil.fpsLerp(selectionLerp, selected ? 1 : 0, 0.25);
|
selectionLerp = CoolUtil.fpsLerp(selectionLerp, selected ? 1 : 0, 0.25);
|
||||||
|
|
||||||
selectionBG.alpha = (iconSpr.alpha = FlxEase.cubeOut(selectionLerp)) * 0.5;
|
selectionBG.alpha = (iconSpr.alpha = FlxEase.cubeOut(selectionLerp)) * 0.5;
|
||||||
selectionBG.x = FlxMath.lerp(-FlxG.width, 0, selectionLerp);
|
selectionBG.x = FlxMath.lerp(-FlxG.width, 0, selectionLerp);
|
||||||
|
|
||||||
label.x = FlxMath.lerp(10, 25 + iconSpr.width + 25, selectionLerp);
|
label.x = FlxMath.lerp(10, 25 + iconSpr.width + 25, selectionLerp);
|
||||||
iconSpr.x = label.x - 25 - iconSpr.width;
|
iconSpr.x = label.x - 25 - iconSpr.width;
|
||||||
iconSpr.angle = Math.sin(iconRotationCycle * 0.5) * 5;
|
iconSpr.angle = Math.sin(iconRotationCycle * 0.5) * 5;
|
||||||
|
|
||||||
scrollFactor.set(FlxMath.lerp(1, 0.1, selectionLerp), 0);
|
scrollFactor.set(FlxMath.lerp(1, 0.1, selectionLerp), 0);
|
||||||
selectionBG.scrollFactor.set(0, 0);
|
selectionBG.scrollFactor.set(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function flicker(callback:Void->Void) {
|
public function flicker(callback:Void->Void) {
|
||||||
FlxFlicker.flicker(label, 0.5, Options.flashingMenu ? 0.06 : 0.15, false, false, function(t) {
|
FlxFlicker.flicker(label, 0.5, Options.flashingMenu ? 0.06 : 0.15, false, false, function(t) {
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,27 +5,27 @@ import flixel.addons.display.FlxBackdrop;
|
|||||||
import funkin.options.*;
|
import funkin.options.*;
|
||||||
|
|
||||||
class EditorTreeMenu extends TreeMenu {
|
class EditorTreeMenu extends TreeMenu {
|
||||||
public var bg:FlxBackdrop;
|
public var bg:FlxBackdrop;
|
||||||
public var bgType:String = "default";
|
public var bgType:String = "default";
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
FlxG.camera.fade(0xFF000000, 0.5, true);
|
FlxG.camera.fade(0xFF000000, 0.5, true);
|
||||||
|
|
||||||
bg = new FlxBackdrop();
|
bg = new FlxBackdrop();
|
||||||
bg.loadGraphic(Paths.image('editors/bgs/${bgType}'));
|
bg.loadGraphic(Paths.image('editors/bgs/${bgType}'));
|
||||||
bg.antialiasing = true;
|
bg.antialiasing = true;
|
||||||
add(bg);
|
add(bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function exit() {
|
public override function exit() {
|
||||||
FlxG.switchState(new MainMenuState());
|
FlxG.switchState(new MainMenuState());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
bg.x += elapsed * 125;
|
bg.x += elapsed * 125;
|
||||||
bg.y += elapsed * 125;
|
bg.y += elapsed * 125;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,132 +3,132 @@ package funkin.editors;
|
|||||||
import funkin.editors.ui.*;
|
import funkin.editors.ui.*;
|
||||||
|
|
||||||
class UIDebugState extends UIState {
|
class UIDebugState extends UIState {
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
FlxG.mouse.useSystemCursor = FlxG.mouse.visible = true;
|
FlxG.mouse.useSystemCursor = FlxG.mouse.visible = true;
|
||||||
|
|
||||||
var bg = new FlxSprite().makeGraphic(1, 1, 0xFF444444);
|
var bg = new FlxSprite().makeGraphic(1, 1, 0xFF444444);
|
||||||
bg.scale.set(FlxG.width, FlxG.height);
|
bg.scale.set(FlxG.width, FlxG.height);
|
||||||
bg.updateHitbox();
|
bg.updateHitbox();
|
||||||
bg.scrollFactor.set();
|
bg.scrollFactor.set();
|
||||||
add(bg);
|
add(bg);
|
||||||
|
|
||||||
add(new UITopMenu([
|
add(new UITopMenu([
|
||||||
{
|
{
|
||||||
label: "File",
|
label: "File",
|
||||||
childs: [
|
childs: [
|
||||||
{
|
{
|
||||||
label: "New"
|
label: "New"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Open"
|
label: "Open"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Save"
|
label: "Save"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Save As..."
|
label: "Save As..."
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
label: "Exit",
|
label: "Exit",
|
||||||
onSelect: (t) -> {FlxG.switchState(new funkin.menus.MainMenuState());}
|
onSelect: (t) -> {FlxG.switchState(new funkin.menus.MainMenuState());}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Edit"
|
label: "Edit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "View"
|
label: "View"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Help"
|
label: "Help"
|
||||||
}
|
}
|
||||||
]));
|
]));
|
||||||
|
|
||||||
add(new UICheckbox(10, 40, "Test unchecked", false));
|
add(new UICheckbox(10, 40, "Test unchecked", false));
|
||||||
add(new UICheckbox(10, 70, "Test checked", true));
|
add(new UICheckbox(10, 70, "Test checked", true));
|
||||||
add(new UIButton(10, 100, "Test button", function() {
|
add(new UIButton(10, 100, "Test button", function() {
|
||||||
trace("Hello, World!");
|
trace("Hello, World!");
|
||||||
}, 130, 32));
|
}, 130, 32));
|
||||||
add(new UIButton(10, 140, "Warning test", function() {
|
add(new UIButton(10, 140, "Warning test", function() {
|
||||||
openSubState(new UIWarningSubstate("Test", "This is a test message", [
|
openSubState(new UIWarningSubstate("Test", "This is a test message", [
|
||||||
{
|
{
|
||||||
label: "Alt. Choice",
|
label: "Alt. Choice",
|
||||||
onClick: function(t) {
|
onClick: function(t) {
|
||||||
trace("Alt. Choice clicked!");
|
trace("Alt. Choice clicked!");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "OK",
|
label: "OK",
|
||||||
onClick: function(t) {
|
onClick: function(t) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]));
|
]));
|
||||||
}, 130, 32));
|
}, 130, 32));
|
||||||
add(new UIButton(10, 180, "Warning test (Overflowing)", function() {
|
add(new UIButton(10, 180, "Warning test (Overflowing)", function() {
|
||||||
openSubState(new UIWarningSubstate("Test", "This is a test message", [
|
openSubState(new UIWarningSubstate("Test", "This is a test message", [
|
||||||
{
|
{
|
||||||
label: "Alt. Choice",
|
label: "Alt. Choice",
|
||||||
onClick: function(t) {
|
onClick: function(t) {
|
||||||
trace("Alt. Choice clicked!");
|
trace("Alt. Choice clicked!");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "OK",
|
label: "OK",
|
||||||
onClick: function(t) {}
|
onClick: function(t) {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "1",
|
label: "1",
|
||||||
onClick: function(t) {}
|
onClick: function(t) {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "2",
|
label: "2",
|
||||||
onClick: function(t) {}
|
onClick: function(t) {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "3",
|
label: "3",
|
||||||
onClick: function(t) {}
|
onClick: function(t) {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "4",
|
label: "4",
|
||||||
onClick: function(t) {}
|
onClick: function(t) {}
|
||||||
}
|
}
|
||||||
]));
|
]));
|
||||||
}, 130, 48));
|
}, 130, 48));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
if (FlxG.mouse.justReleasedRight) {
|
if (FlxG.mouse.justReleasedRight) {
|
||||||
openContextMenu([
|
openContextMenu([
|
||||||
{
|
{
|
||||||
label: "Test 1",
|
label: "Test 1",
|
||||||
onSelect: function(t) {
|
onSelect: function(t) {
|
||||||
trace("Test 1 clicked");
|
trace("Test 1 clicked");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Test 2",
|
label: "Test 2",
|
||||||
onSelect: function(t) {
|
onSelect: function(t) {
|
||||||
trace("Test 2 clicked");
|
trace("Test 2 clicked");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Test 3",
|
label: "Test 3",
|
||||||
childs: [
|
childs: [
|
||||||
{
|
{
|
||||||
label: "Test 4",
|
label: "Test 4",
|
||||||
onSelect: function(t) {
|
onSelect: function(t) {
|
||||||
trace("Test 4 clicked");
|
trace("Test 4 clicked");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,32 +6,32 @@ import funkin.shaders.CustomShader;
|
|||||||
import flixel.util.FlxColor;
|
import flixel.util.FlxColor;
|
||||||
|
|
||||||
class CharterNote extends UISprite {
|
class CharterNote extends UISprite {
|
||||||
var angleTween:FlxTween;
|
var angleTween:FlxTween;
|
||||||
|
|
||||||
public var selected:Bool = false;
|
public var selected:Bool = false;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
antialiasing = true;
|
antialiasing = true;
|
||||||
loadGraphic(Paths.image('editors/charter/note'), true, 157, 154);
|
loadGraphic(Paths.image('editors/charter/note'), true, 157, 154);
|
||||||
animation.add("note", [for(i in 0...frames.frames.length) i], 0, true);
|
animation.add("note", [for(i in 0...frames.frames.length) i], 0, true);
|
||||||
animation.play("note");
|
animation.play("note");
|
||||||
this.setUnstretchedGraphicSize(40, 40, false);
|
this.setUnstretchedGraphicSize(40, 40, false);
|
||||||
|
|
||||||
angle = 45; // green-red inbetween
|
angle = 45; // green-red inbetween
|
||||||
|
|
||||||
cursor = BUTTON;
|
cursor = BUTTON;
|
||||||
|
|
||||||
moves = false;
|
moves = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function updateButton() {
|
public override function updateButton() {
|
||||||
__rect.x = x;
|
__rect.x = x;
|
||||||
__rect.y = y;
|
__rect.y = y;
|
||||||
__rect.width = 40;
|
__rect.width = 40;
|
||||||
__rect.height = 40;
|
__rect.height = 40;
|
||||||
UIState.state.updateRectButtonHandler(this, __rect, onHovered);
|
UIState.state.updateRectButtonHandler(this, __rect, onHovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public var step:Float;
|
public var step:Float;
|
||||||
@@ -39,27 +39,27 @@ class CharterNote extends UISprite {
|
|||||||
public var susLength:Float;
|
public var susLength:Float;
|
||||||
public var type:Int;
|
public var type:Int;
|
||||||
|
|
||||||
public function updatePos(step:Float, id:Int, susLength:Float = 0, type:Int = 0) {
|
public function updatePos(step:Float, id:Int, susLength:Float = 0, type:Int = 0) {
|
||||||
this.step = step;
|
this.step = step;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.susLength = susLength;
|
this.susLength = susLength;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
x = id * 40;
|
x = id * 40;
|
||||||
y = step * 40;
|
y = step * 40;
|
||||||
|
|
||||||
if (angleTween != null) angleTween.cancel();
|
if (angleTween != null) angleTween.cancel();
|
||||||
|
|
||||||
angleTween = FlxTween.tween(this, {angle: switch(animation.curAnim.curFrame = (id % 4)) {
|
angleTween = FlxTween.tween(this, {angle: switch(animation.curAnim.curFrame = (id % 4)) {
|
||||||
case 0: -90;
|
case 0: -90;
|
||||||
case 1: 180;
|
case 1: 180;
|
||||||
case 2: 0;
|
case 2: 0;
|
||||||
case 3: 90;
|
case 3: 90;
|
||||||
default: 0; // how is that even possible
|
default: 0; // how is that even possible
|
||||||
}}, 2/3, {ease: function(t) {
|
}}, 2/3, {ease: function(t) {
|
||||||
return ((Math.sin(t * Math.PI) * 0.35) * 3 * t * Math.sqrt(1 - t)) + t;
|
return ((Math.sin(t * Math.PI) * 0.35) * 3 * t * Math.sqrt(1 - t)) + t;
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function kill() {
|
public override function kill() {
|
||||||
if (angleTween != null) {
|
if (angleTween != null) {
|
||||||
@@ -76,7 +76,7 @@ class CharterNote extends UISprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var __passed:Bool = false;
|
var __passed:Bool = false;
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
if (__passed != (__passed = step < Conductor.curStepFloat)) {
|
if (__passed != (__passed = step < Conductor.curStepFloat)) {
|
||||||
@@ -85,8 +85,8 @@ class CharterNote extends UISprite {
|
|||||||
Charter.instance.hitsound.replay();
|
Charter.instance.hitsound.replay();
|
||||||
}
|
}
|
||||||
|
|
||||||
colorTransform.redMultiplier = colorTransform.greenMultiplier = colorTransform.blueMultiplier = selected ? 0.75 : 1;
|
colorTransform.redMultiplier = colorTransform.greenMultiplier = colorTransform.blueMultiplier = selected ? 0.75 : 1;
|
||||||
colorTransform.redOffset = colorTransform.greenOffset = selected ? 96 : 0;
|
colorTransform.redOffset = colorTransform.greenOffset = selected ? 96 : 0;
|
||||||
colorTransform.blueOffset = selected ? 168 : 0;
|
colorTransform.blueOffset = selected ? 168 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,48 +3,48 @@ package funkin.editors.charter;
|
|||||||
import funkin.system.Conductor;
|
import funkin.system.Conductor;
|
||||||
|
|
||||||
class CharterNoteGroup extends FlxTypedGroup<CharterNote> {
|
class CharterNoteGroup extends FlxTypedGroup<CharterNote> {
|
||||||
var __loopSprite:CharterNote;
|
var __loopSprite:CharterNote;
|
||||||
var i:Int = 0;
|
var i:Int = 0;
|
||||||
var max:Float = 0;
|
var max:Float = 0;
|
||||||
var __currentlyLooping:Bool = false;
|
var __currentlyLooping:Bool = false;
|
||||||
|
|
||||||
public override function forEach(noteFunc:CharterNote->Void, recursive:Bool = false) {
|
public override function forEach(noteFunc:CharterNote->Void, recursive:Bool = false) {
|
||||||
i = 0;
|
i = 0;
|
||||||
__loopSprite = null;
|
__loopSprite = null;
|
||||||
|
|
||||||
max = FlxG.height / 70 / camera.zoom;
|
max = FlxG.height / 70 / camera.zoom;
|
||||||
|
|
||||||
var oldCur = __currentlyLooping;
|
var oldCur = __currentlyLooping;
|
||||||
__currentlyLooping = true;
|
__currentlyLooping = true;
|
||||||
|
|
||||||
while(i < length) {
|
while(i < length) {
|
||||||
__loopSprite = members[i];
|
__loopSprite = members[i];
|
||||||
if (__loopSprite == null || !__loopSprite.exists) {
|
if (__loopSprite == null || !__loopSprite.exists) {
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Math.abs(__loopSprite.step - Conductor.curStepFloat) < max)
|
if (Math.abs(__loopSprite.step - Conductor.curStepFloat) < max)
|
||||||
noteFunc(__loopSprite);
|
noteFunc(__loopSprite);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
__currentlyLooping = oldCur;
|
__currentlyLooping = oldCur;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
@:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
|
@:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
|
||||||
@:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras;
|
@:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras;
|
||||||
|
|
||||||
forEach((n) -> n.draw());
|
forEach((n) -> n.draw());
|
||||||
|
|
||||||
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
@:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
|
@:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
|
||||||
@:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras;
|
@:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras;
|
||||||
|
|
||||||
forEach((n) -> n.update(elapsed));
|
forEach((n) -> n.update(elapsed));
|
||||||
|
|
||||||
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,38 +3,38 @@ package funkin.editors.ui;
|
|||||||
import flixel.math.FlxPoint;
|
import flixel.math.FlxPoint;
|
||||||
|
|
||||||
class UIBackdrop extends UISprite {
|
class UIBackdrop extends UISprite {
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
var __oldPos = FlxPoint.get(x, y);
|
var __oldPos = FlxPoint.get(x, y);
|
||||||
var __oldScroll = FlxPoint.get(scrollFactor.x, scrollFactor.y);
|
var __oldScroll = FlxPoint.get(scrollFactor.x, scrollFactor.y);
|
||||||
|
|
||||||
x -= camera.scroll.x * scrollFactor.x;
|
x -= camera.scroll.x * scrollFactor.x;
|
||||||
y -= camera.scroll.y * scrollFactor.y;
|
y -= camera.scroll.y * scrollFactor.y;
|
||||||
|
|
||||||
while(x > -width)
|
while(x > -width)
|
||||||
x -= width;
|
x -= width;
|
||||||
while(y > -height)
|
while(y > -height)
|
||||||
y -= height;
|
y -= height;
|
||||||
|
|
||||||
var defX = x;
|
var defX = x;
|
||||||
|
|
||||||
while(y < FlxG.height) {
|
while(y < FlxG.height) {
|
||||||
while(x < FlxG.width) {
|
while(x < FlxG.width) {
|
||||||
super.drawSuper();
|
super.drawSuper();
|
||||||
x += width;
|
x += width;
|
||||||
}
|
}
|
||||||
y += height;
|
y += height;
|
||||||
x = defX;
|
x = defX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setPosition(__oldPos.x, __oldPos.y);
|
setPosition(__oldPos.x, __oldPos.y);
|
||||||
scrollFactor.set(__oldScroll.x, __oldScroll.y);
|
scrollFactor.set(__oldScroll.x, __oldScroll.y);
|
||||||
__oldPos.put();
|
__oldPos.put();
|
||||||
__oldScroll.put();
|
__oldScroll.put();
|
||||||
drawMembers();
|
drawMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,42 +3,42 @@ package funkin.editors.ui;
|
|||||||
import flixel.graphics.frames.FlxFrame;
|
import flixel.graphics.frames.FlxFrame;
|
||||||
|
|
||||||
class UIButton extends UISliceSprite {
|
class UIButton extends UISliceSprite {
|
||||||
public var callback:Void->Void = null;
|
public var callback:Void->Void = null;
|
||||||
|
|
||||||
public var field:UIText;
|
public var field:UIText;
|
||||||
|
|
||||||
public override function new(x:Float, y:Float, text:String, callback:Void->Void, w:Int = 120, h:Int = 32) {
|
public override function new(x:Float, y:Float, text:String, callback:Void->Void, w:Int = 120, h:Int = 32) {
|
||||||
super(x, y, w, h, 'editors/ui/button');
|
super(x, y, w, h, 'editors/ui/button');
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
members.push(field = new UIText(x, y, w, text));
|
members.push(field = new UIText(x, y, w, text));
|
||||||
field.borderStyle = OUTLINE;
|
field.borderStyle = OUTLINE;
|
||||||
field.borderColor = 0x88000000;
|
field.borderColor = 0x88000000;
|
||||||
field.borderSize = 1;
|
field.borderSize = 1;
|
||||||
field.alignment = CENTER;
|
field.alignment = CENTER;
|
||||||
field.fieldWidth = w;
|
field.fieldWidth = w;
|
||||||
|
|
||||||
cursor = BUTTON;
|
cursor = BUTTON;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function resize(w:Int, h:Int) {
|
public override function resize(w:Int, h:Int) {
|
||||||
super.resize(w, h);
|
super.resize(w, h);
|
||||||
if (field != null)
|
if (field != null)
|
||||||
field.fieldWidth = w;
|
field.fieldWidth = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function onHovered() {
|
public override function onHovered() {
|
||||||
super.onHovered();
|
super.onHovered();
|
||||||
if (FlxG.mouse.justReleased && callback != null)
|
if (FlxG.mouse.justReleased && callback != null)
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
field.follow(this, 0, (bHeight - field.height) / 2);
|
field.follow(this, 0, (bHeight - field.height) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
framesOffset = hovered ? (pressed ? 18 : 9) : 0;
|
framesOffset = hovered ? (pressed ? 18 : 9) : 0;
|
||||||
super.draw();
|
super.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,74 +3,74 @@ package funkin.editors.ui;
|
|||||||
import funkin.ui.FunkinText;
|
import funkin.ui.FunkinText;
|
||||||
|
|
||||||
class UICheckbox extends UISprite {
|
class UICheckbox extends UISprite {
|
||||||
public var checked:Bool = false;
|
public var checked:Bool = false;
|
||||||
public var onChecked:Bool->Void = null;
|
public var onChecked:Bool->Void = null;
|
||||||
|
|
||||||
public var field:UIText;
|
public var field:UIText;
|
||||||
public var check:FlxSprite;
|
public var check:FlxSprite;
|
||||||
|
|
||||||
public function new(x:Float, y:Float, text:String, checked:Bool = false, w:Int = 0) {
|
public function new(x:Float, y:Float, text:String, checked:Bool = false, w:Int = 0) {
|
||||||
super(x, y);
|
super(x, y);
|
||||||
loadGraphic(Paths.image('editors/ui/checkbox'), true, 20, 20);
|
loadGraphic(Paths.image('editors/ui/checkbox'), true, 20, 20);
|
||||||
for(frame=>name in ["normal", "hover", "pressed", "checkmark"])
|
for(frame=>name in ["normal", "hover", "pressed", "checkmark"])
|
||||||
animation.add(name, [frame], 0, false);
|
animation.add(name, [frame], 0, false);
|
||||||
|
|
||||||
this.checked = checked;
|
this.checked = checked;
|
||||||
|
|
||||||
field = new UIText(x, y, w, text);
|
field = new UIText(x, y, w, text);
|
||||||
check = new FlxSprite().loadGraphicFromSprite(this);
|
check = new FlxSprite().loadGraphicFromSprite(this);
|
||||||
check.animation.play("checkmark");
|
check.animation.play("checkmark");
|
||||||
|
|
||||||
members.push(check);
|
members.push(check);
|
||||||
members.push(field);
|
members.push(field);
|
||||||
|
|
||||||
cursor = BUTTON;
|
cursor = BUTTON;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
// ANIMATION HANDLING
|
// ANIMATION HANDLING
|
||||||
animation.play(hovered ? (pressed ? "pressed" : "hover") : "normal");
|
animation.play(hovered ? (pressed ? "pressed" : "hover") : "normal");
|
||||||
|
|
||||||
// CHECKMARK HANDLING
|
// CHECKMARK HANDLING
|
||||||
check.alpha = checked ? 1 : 0;
|
check.alpha = checked ? 1 : 0;
|
||||||
check.scale.x = CoolUtil.fpsLerp(check.scale.x, 1, 0.25);
|
check.scale.x = CoolUtil.fpsLerp(check.scale.x, 1, 0.25);
|
||||||
check.scale.y = CoolUtil.fpsLerp(check.scale.y, 1, 0.25);
|
check.scale.y = CoolUtil.fpsLerp(check.scale.y, 1, 0.25);
|
||||||
|
|
||||||
// POSITION HANDLING
|
// POSITION HANDLING
|
||||||
updatePositions();
|
updatePositions();
|
||||||
|
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline function updatePositions() {
|
public inline function updatePositions() {
|
||||||
check.follow(this);
|
check.follow(this);
|
||||||
field.follow(this, 25, 0);
|
field.follow(this, 25, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
updatePositions();
|
updatePositions();
|
||||||
super.draw();
|
super.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function onHovered() {
|
public override function onHovered() {
|
||||||
super.onHovered();
|
super.onHovered();
|
||||||
if (FlxG.mouse.justReleased) {
|
if (FlxG.mouse.justReleased) {
|
||||||
// clicked
|
// clicked
|
||||||
checked = !checked;
|
checked = !checked;
|
||||||
check.scale.set(1.25, 1.25);
|
check.scale.set(1.25, 1.25);
|
||||||
|
|
||||||
if (Options.editorSFX)
|
if (Options.editorSFX)
|
||||||
CoolUtil.playMenuSFX(checked ? CHECKED : UNCHECKED, 0.5);
|
CoolUtil.playMenuSFX(checked ? CHECKED : UNCHECKED, 0.5);
|
||||||
if (onChecked != null)
|
if (onChecked != null)
|
||||||
onChecked(checked);
|
onChecked(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function updateButton() {
|
public override function updateButton() {
|
||||||
__rect.x = x;
|
__rect.x = x;
|
||||||
__rect.y = y;
|
__rect.y = y;
|
||||||
__rect.width = field.width + 30;
|
__rect.width = field.width + 30;
|
||||||
__rect.height = field.height > height ? field.height : height;
|
__rect.height = field.height > height ? field.height : height;
|
||||||
UIState.state.updateRectButtonHandler(this, __rect, onHovered);
|
UIState.state.updateRectButtonHandler(this, __rect, onHovered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,55 +3,55 @@ package funkin.editors.ui;
|
|||||||
import flixel.graphics.frames.FlxFrame;
|
import flixel.graphics.frames.FlxFrame;
|
||||||
|
|
||||||
class UISliceSprite extends UISprite {
|
class UISliceSprite extends UISprite {
|
||||||
public var bWidth:Int = 120;
|
public var bWidth:Int = 120;
|
||||||
public var bHeight:Int = 20;
|
public var bHeight:Int = 20;
|
||||||
public var framesOffset:Int = 0;
|
public var framesOffset:Int = 0;
|
||||||
|
|
||||||
public var incorporeal:Bool = false;
|
public var incorporeal:Bool = false;
|
||||||
|
|
||||||
public function new(x:Float, y:Float, w:Int, h:Int, path:String) {
|
public function new(x:Float, y:Float, w:Int, h:Int, path:String) {
|
||||||
super(x, y);
|
super(x, y);
|
||||||
|
|
||||||
frames = CoolUtil.loadFrames(Paths.image(path));
|
frames = CoolUtil.loadFrames(Paths.image(path));
|
||||||
resize(w, h);
|
resize(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function updateButton() {
|
public override function updateButton() {
|
||||||
if (incorporeal) return;
|
if (incorporeal) return;
|
||||||
__rect.x = x;
|
__rect.x = x;
|
||||||
__rect.y = y;
|
__rect.y = y;
|
||||||
__rect.width = bWidth;
|
__rect.width = bWidth;
|
||||||
__rect.height = bHeight;
|
__rect.height = bHeight;
|
||||||
UIState.state.updateRectButtonHandler(this, __rect, onHovered);
|
UIState.state.updateRectButtonHandler(this, __rect, onHovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resize(w:Int, h:Int) {
|
public function resize(w:Int, h:Int) {
|
||||||
bWidth = w;
|
bWidth = w;
|
||||||
bHeight = h;
|
bHeight = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
var x:Float = this.x;
|
var x:Float = this.x;
|
||||||
var y:Float = this.y;
|
var y:Float = this.y;
|
||||||
|
|
||||||
var topleft:FlxFrame = frames.frames[framesOffset];
|
var topleft:FlxFrame = frames.frames[framesOffset];
|
||||||
var top:FlxFrame = frames.frames[framesOffset + 1];
|
var top:FlxFrame = frames.frames[framesOffset + 1];
|
||||||
var topright:FlxFrame = frames.frames[framesOffset + 2];
|
var topright:FlxFrame = frames.frames[framesOffset + 2];
|
||||||
var middleleft:FlxFrame = frames.frames[framesOffset + 3];
|
var middleleft:FlxFrame = frames.frames[framesOffset + 3];
|
||||||
var middle:FlxFrame = frames.frames[framesOffset + 4];
|
var middle:FlxFrame = frames.frames[framesOffset + 4];
|
||||||
var middleright:FlxFrame = frames.frames[framesOffset + 5];
|
var middleright:FlxFrame = frames.frames[framesOffset + 5];
|
||||||
var bottomleft:FlxFrame = frames.frames[framesOffset + 6];
|
var bottomleft:FlxFrame = frames.frames[framesOffset + 6];
|
||||||
var bottom:FlxFrame = frames.frames[framesOffset + 7];
|
var bottom:FlxFrame = frames.frames[framesOffset + 7];
|
||||||
var bottomright:FlxFrame = frames.frames[framesOffset + 8];
|
var bottomright:FlxFrame = frames.frames[framesOffset + 8];
|
||||||
|
|
||||||
@:privateAccess if (visible) {
|
@:privateAccess if (visible) {
|
||||||
// TOP LEFT
|
// TOP LEFT
|
||||||
frame = topleft;
|
frame = topleft;
|
||||||
setPosition(x, y);
|
setPosition(x, y);
|
||||||
__setSize(topleft.frame.width, topleft.frame.height);
|
__setSize(topleft.frame.width, topleft.frame.height);
|
||||||
super.drawSuper();
|
super.drawSuper();
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
if (bWidth > topleft.frame.width + topright.frame.width) {
|
if (bWidth > topleft.frame.width + topright.frame.width) {
|
||||||
frame = top;
|
frame = top;
|
||||||
setPosition(x + topleft.frame.width, y);
|
setPosition(x + topleft.frame.width, y);
|
||||||
@@ -59,13 +59,13 @@ class UISliceSprite extends UISprite {
|
|||||||
super.drawSuper();
|
super.drawSuper();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TOP RIGHT
|
// TOP RIGHT
|
||||||
frame = topright;
|
frame = topright;
|
||||||
setPosition(x + bWidth - topright.frame.width, y);
|
setPosition(x + bWidth - topright.frame.width, y);
|
||||||
__setSize(topright.frame.width, topright.frame.height);
|
__setSize(topright.frame.width, topright.frame.height);
|
||||||
super.drawSuper();
|
super.drawSuper();
|
||||||
|
|
||||||
// MIDDLE LEFT
|
// MIDDLE LEFT
|
||||||
if (bHeight > top.frame.height + bottom.frame.height) {
|
if (bHeight > top.frame.height + bottom.frame.height) {
|
||||||
frame = middleleft;
|
frame = middleleft;
|
||||||
setPosition(x, y + top.frame.height);
|
setPosition(x, y + top.frame.height);
|
||||||
@@ -87,12 +87,12 @@ class UISliceSprite extends UISprite {
|
|||||||
super.drawSuper();
|
super.drawSuper();
|
||||||
}
|
}
|
||||||
|
|
||||||
// BOTTOM LEFT
|
// BOTTOM LEFT
|
||||||
frame = bottomleft;
|
frame = bottomleft;
|
||||||
setPosition(x, y + bHeight - bottom.frame.height);
|
setPosition(x, y + bHeight - bottom.frame.height);
|
||||||
__setSize(bottomleft.frame.width, bottomleft.frame.height);
|
__setSize(bottomleft.frame.width, bottomleft.frame.height);
|
||||||
super.drawSuper();
|
super.drawSuper();
|
||||||
|
|
||||||
if (bWidth > bottomleft.frame.width + bottomright.frame.width) {
|
if (bWidth > bottomleft.frame.width + bottomright.frame.width) {
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
frame = bottom;
|
frame = bottom;
|
||||||
@@ -101,20 +101,20 @@ class UISliceSprite extends UISprite {
|
|||||||
super.drawSuper();
|
super.drawSuper();
|
||||||
}
|
}
|
||||||
|
|
||||||
// BOTTOM RIGHT
|
// BOTTOM RIGHT
|
||||||
frame = bottomright;
|
frame = bottomright;
|
||||||
setPosition(x + bWidth - bottomright.frame.width, y + bHeight - bottom.frame.height);
|
setPosition(x + bWidth - bottomright.frame.width, y + bHeight - bottom.frame.height);
|
||||||
__setSize(bottomright.frame.width, bottomright.frame.height);
|
__setSize(bottomright.frame.width, bottomright.frame.height);
|
||||||
super.drawSuper();
|
super.drawSuper();
|
||||||
}
|
}
|
||||||
|
|
||||||
setPosition(x, y);
|
setPosition(x, y);
|
||||||
|
|
||||||
super.drawMembers();
|
super.drawMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function __setSize(Width:Float, Height:Float) {
|
private function __setSize(Width:Float, Height:Float) {
|
||||||
var newScaleX:Float = Width / frameWidth;
|
var newScaleX:Float = Width / frameWidth;
|
||||||
var newScaleY:Float = Height / frameHeight;
|
var newScaleY:Float = Height / frameHeight;
|
||||||
scale.set(newScaleX, newScaleY);
|
scale.set(newScaleX, newScaleY);
|
||||||
|
|
||||||
@@ -123,6 +123,6 @@ class UISliceSprite extends UISprite {
|
|||||||
else if (Height <= 0)
|
else if (Height <= 0)
|
||||||
scale.y = newScaleX;
|
scale.y = newScaleX;
|
||||||
|
|
||||||
updateHitbox();
|
updateHitbox();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,80 +7,80 @@ import openfl.ui.MouseCursor;
|
|||||||
@:allow(funkin.editors.ui.UIState)
|
@:allow(funkin.editors.ui.UIState)
|
||||||
@:allow(funkin.editors.ui.UIUtil)
|
@:allow(funkin.editors.ui.UIUtil)
|
||||||
class UISprite extends FlxSprite {
|
class UISprite extends FlxSprite {
|
||||||
public var members:Array<FlxBasic> = [];
|
public var members:Array<FlxBasic> = [];
|
||||||
|
|
||||||
private var __lastDrawCameras:Array<FlxCamera> = [];
|
private var __lastDrawCameras:Array<FlxCamera> = [];
|
||||||
private var __rect:FlxRect = new FlxRect();
|
private var __rect:FlxRect = new FlxRect();
|
||||||
|
|
||||||
private var __oldDefCams:Array<FlxCamera>;
|
private var __oldDefCams:Array<FlxCamera>;
|
||||||
|
|
||||||
public var hovered:Bool = false;
|
public var hovered:Bool = false;
|
||||||
public var hoveredByChild:Bool = false;
|
public var hoveredByChild:Bool = false;
|
||||||
public var pressed:Bool = false;
|
public var pressed:Bool = false;
|
||||||
|
|
||||||
public var hoverCallback:Void->Void = null;
|
public var hoverCallback:Void->Void = null;
|
||||||
|
|
||||||
public var cursor:MouseCursor = ARROW;
|
public var cursor:MouseCursor = ARROW;
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
hovered = false;
|
hovered = false;
|
||||||
pressed = false;
|
pressed = false;
|
||||||
hoveredByChild = false;
|
hoveredByChild = false;
|
||||||
|
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
updateButton();
|
updateButton();
|
||||||
|
|
||||||
@:privateAccess {
|
@:privateAccess {
|
||||||
__oldDefCams = FlxCamera._defaultCameras;
|
__oldDefCams = FlxCamera._defaultCameras;
|
||||||
FlxCamera._defaultCameras = cameras;
|
FlxCamera._defaultCameras = cameras;
|
||||||
|
|
||||||
for(m in members)
|
for(m in members)
|
||||||
m.update(elapsed);
|
m.update(elapsed);
|
||||||
|
|
||||||
FlxCamera._defaultCameras = __oldDefCams;
|
FlxCamera._defaultCameras = __oldDefCams;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
drawSuper();
|
drawSuper();
|
||||||
drawMembers();
|
drawMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function drawSuper() {
|
public function drawSuper() {
|
||||||
super.draw();
|
super.draw();
|
||||||
__lastDrawCameras = [for(c in cameras) c];
|
__lastDrawCameras = [for(c in cameras) c];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function drawMembers() {
|
public function drawMembers() {
|
||||||
@:privateAccess {
|
@:privateAccess {
|
||||||
__oldDefCams = FlxCamera._defaultCameras;
|
__oldDefCams = FlxCamera._defaultCameras;
|
||||||
FlxCamera._defaultCameras = cameras;
|
FlxCamera._defaultCameras = cameras;
|
||||||
|
|
||||||
for(m in members)
|
for(m in members)
|
||||||
m.draw();
|
m.draw();
|
||||||
|
|
||||||
FlxCamera._defaultCameras = __oldDefCams;
|
FlxCamera._defaultCameras = __oldDefCams;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
members = FlxDestroyUtil.destroyArray(members);
|
members = FlxDestroyUtil.destroyArray(members);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateButton() {
|
public function updateButton() {
|
||||||
UIState.state.updateButtonHandler(this, onHovered);
|
UIState.state.updateButtonHandler(this, onHovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called whenever the sprite is being hovered by the mouse.
|
* Called whenever the sprite is being hovered by the mouse.
|
||||||
*/
|
*/
|
||||||
public function onHovered() {
|
public function onHovered() {
|
||||||
hovered = true;
|
hovered = true;
|
||||||
if (FlxG.mouse.pressed)
|
if (FlxG.mouse.pressed)
|
||||||
pressed = true;
|
pressed = true;
|
||||||
if (hoverCallback != null)
|
if (hoverCallback != null)
|
||||||
hoverCallback();
|
hoverCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,9 @@ import flixel.util.FlxColor;
|
|||||||
import funkin.ui.FunkinText;
|
import funkin.ui.FunkinText;
|
||||||
|
|
||||||
class UIText extends FunkinText {
|
class UIText extends FunkinText {
|
||||||
// PUTTING THIS HERE IN CASE IMMA MAKE FUTURE CHANGES
|
// PUTTING THIS HERE IN CASE IMMA MAKE FUTURE CHANGES
|
||||||
public function new(x, y, w, text, size:Int = 15, color:FlxColor = 0xFFFFFFFF) {
|
public function new(x, y, w, text, size:Int = 15, color:FlxColor = 0xFFFFFFFF) {
|
||||||
super(x, y, w, text, size, false);
|
super(x, y, w, text, size, false);
|
||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,74 +3,74 @@ package funkin.editors.ui;
|
|||||||
import funkin.editors.ui.UIContextMenu.UIContextMenuOption;
|
import funkin.editors.ui.UIContextMenu.UIContextMenuOption;
|
||||||
|
|
||||||
class UITopMenu extends UISliceSprite {
|
class UITopMenu extends UISliceSprite {
|
||||||
var options:Array<UIContextMenuOption>;
|
var options:Array<UIContextMenuOption>;
|
||||||
public function new(options:Array<UIContextMenuOption>) {
|
public function new(options:Array<UIContextMenuOption>) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
super(0, 0, FlxG.width, 25, 'editors/ui/topmenu');
|
super(0, 0, FlxG.width, 25, 'editors/ui/topmenu');
|
||||||
scrollFactor.set(0, 0);
|
scrollFactor.set(0, 0);
|
||||||
|
|
||||||
var x:Int = 0;
|
var x:Int = 0;
|
||||||
for(o in options) {
|
for(o in options) {
|
||||||
var b = new UITopMenuButton(x, 0, this, o.label, o.childs);
|
var b = new UITopMenuButton(x, 0, this, o.label, o.childs);
|
||||||
x += b.bWidth;
|
x += b.bWidth;
|
||||||
members.push(b);
|
members.push(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var anyMenuOpened:Bool = false;
|
public var anyMenuOpened:Bool = false;
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
anyMenuOpened = false;
|
anyMenuOpened = false;
|
||||||
for(c in members) if (cast(c, UITopMenuButton).curMenu.contextMenuOpened()) {
|
for(c in members) if (cast(c, UITopMenuButton).curMenu.contextMenuOpened()) {
|
||||||
anyMenuOpened = true;
|
anyMenuOpened = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
|
|
||||||
bWidth = FlxG.width;
|
bWidth = FlxG.width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UITopMenuButton extends UISliceSprite {
|
class UITopMenuButton extends UISliceSprite {
|
||||||
public var label:UIText;
|
public var label:UIText;
|
||||||
public var contextMenu:Array<UIContextMenuOption>;
|
public var contextMenu:Array<UIContextMenuOption>;
|
||||||
public var parent:UITopMenu;
|
public var parent:UITopMenu;
|
||||||
|
|
||||||
public var curMenu:UIContextMenu = null;
|
public var curMenu:UIContextMenu = null;
|
||||||
|
|
||||||
public function new(x:Float, y:Float, parent:UITopMenu, label:String, contextMenu:Array<UIContextMenuOption>) {
|
public function new(x:Float, y:Float, parent:UITopMenu, label:String, contextMenu:Array<UIContextMenuOption>) {
|
||||||
super(x, y, 0, 23, "editors/ui/menu-item");
|
super(x, y, 0, 23, "editors/ui/menu-item");
|
||||||
this.contextMenu = contextMenu;
|
this.contextMenu = contextMenu;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
cursor = BUTTON;
|
cursor = BUTTON;
|
||||||
|
|
||||||
this.label = new UIText(4, 0, 0, label);
|
this.label = new UIText(4, 0, 0, label);
|
||||||
this.label.alignment = CENTER;
|
this.label.alignment = CENTER;
|
||||||
bWidth = this.label.frameWidth + 8;
|
bWidth = this.label.frameWidth + 8;
|
||||||
members.push(this.label);
|
members.push(this.label);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
label.follow(this, 4, Std.int((bHeight - label.height) / 2));
|
label.follow(this, 4, Std.int((bHeight - label.height) / 2));
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
var opened = curMenu.contextMenuOpened();
|
var opened = curMenu.contextMenuOpened();
|
||||||
alpha = (hovered || opened) ? 1 : 0;
|
alpha = (hovered || opened) ? 1 : 0;
|
||||||
framesOffset = opened ? 9 : 0;
|
framesOffset = opened ? 9 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function onHovered() {
|
public override function onHovered() {
|
||||||
super.onHovered();
|
super.onHovered();
|
||||||
if (hovered) {
|
if (hovered) {
|
||||||
if (curMenu.contextMenuOpened()) {
|
if (curMenu.contextMenuOpened()) {
|
||||||
UIState.state.curContextMenu.preventOutOfBoxClickDeletion();
|
UIState.state.curContextMenu.preventOutOfBoxClickDeletion();
|
||||||
} else {
|
} else {
|
||||||
if (parent.anyMenuOpened || FlxG.mouse.justReleased) {
|
if (parent.anyMenuOpened || FlxG.mouse.justReleased) {
|
||||||
curMenu = UIState.state.openContextMenu(contextMenu, null, x, y + bHeight);
|
curMenu = UIState.state.openContextMenu(contextMenu, null, x, y + bHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,82 +5,82 @@ import flixel.tweens.FlxEase;
|
|||||||
import funkin.shaders.CustomShader;
|
import funkin.shaders.CustomShader;
|
||||||
|
|
||||||
class UIWarningSubstate extends MusicBeatSubstate {
|
class UIWarningSubstate extends MusicBeatSubstate {
|
||||||
var camShaders:Array<FlxCamera> = [];
|
var camShaders:Array<FlxCamera> = [];
|
||||||
var blurShader:CustomShader = new CustomShader("engine/editorBlur");
|
var blurShader:CustomShader = new CustomShader("engine/editorBlur");
|
||||||
|
|
||||||
var title:String;
|
var title:String;
|
||||||
var message:String;
|
var message:String;
|
||||||
var buttons:Array<WarningButton>;
|
var buttons:Array<WarningButton>;
|
||||||
|
|
||||||
var titleSpr:UIText;
|
var titleSpr:UIText;
|
||||||
var messageSpr:UIText;
|
var messageSpr:UIText;
|
||||||
|
|
||||||
var warnCam:FlxCamera;
|
var warnCam:FlxCamera;
|
||||||
|
|
||||||
public override function onSubstateOpen() {
|
public override function onSubstateOpen() {
|
||||||
super.onSubstateOpen();
|
super.onSubstateOpen();
|
||||||
parent.persistentUpdate = false;
|
parent.persistentUpdate = false;
|
||||||
parent.persistentDraw = true;
|
parent.persistentDraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
for(c in FlxG.cameras.list) {
|
for(c in FlxG.cameras.list) {
|
||||||
camShaders.push(c);
|
camShaders.push(c);
|
||||||
c.addShader(blurShader);
|
c.addShader(blurShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
camera = warnCam = new FlxCamera();
|
camera = warnCam = new FlxCamera();
|
||||||
warnCam.bgColor = 0;
|
warnCam.bgColor = 0;
|
||||||
warnCam.alpha = 0;
|
warnCam.alpha = 0;
|
||||||
warnCam.zoom = 0.1;
|
warnCam.zoom = 0.1;
|
||||||
FlxG.cameras.add(warnCam, false);
|
FlxG.cameras.add(warnCam, false);
|
||||||
|
|
||||||
var spr = new UISliceSprite(0, 0, CoolUtil.maxInt(560, 30 + (170 * buttons.length)), 280, "editors/ui/warning-popup");
|
var spr = new UISliceSprite(0, 0, CoolUtil.maxInt(560, 30 + (170 * buttons.length)), 280, "editors/ui/warning-popup");
|
||||||
spr.x = (FlxG.width - spr.bWidth) / 2;
|
spr.x = (FlxG.width - spr.bWidth) / 2;
|
||||||
spr.y = (FlxG.height - spr.bHeight) / 2;
|
spr.y = (FlxG.height - spr.bHeight) / 2;
|
||||||
add(spr);
|
add(spr);
|
||||||
|
|
||||||
|
|
||||||
add(titleSpr = new UIText(spr.x + 25, spr.y, spr.bWidth - 50, title, 15, -1));
|
add(titleSpr = new UIText(spr.x + 25, spr.y, spr.bWidth - 50, title, 15, -1));
|
||||||
titleSpr.y = spr.y + ((30 - titleSpr.height) / 2);
|
titleSpr.y = spr.y + ((30 - titleSpr.height) / 2);
|
||||||
|
|
||||||
add(messageSpr = new UIText(spr.x + 10, spr.y + 40, spr.bWidth - 20, message, 15, -1));
|
add(messageSpr = new UIText(spr.x + 10, spr.y + 40, spr.bWidth - 20, message, 15, -1));
|
||||||
|
|
||||||
var xPos = (FlxG.width - (30 + (170 * buttons.length))) / 2;
|
var xPos = (FlxG.width - (30 + (170 * buttons.length))) / 2;
|
||||||
for(k=>b in buttons) {
|
for(k=>b in buttons) {
|
||||||
var button = new UIButton(xPos + 20 + (170 * k), spr.y + spr.bHeight - 40, b.label, function() {
|
var button = new UIButton(xPos + 20 + (170 * k), spr.y + spr.bHeight - 40, b.label, function() {
|
||||||
b.onClick(this);
|
b.onClick(this);
|
||||||
close();
|
close();
|
||||||
}, 160, 30);
|
}, 160, 30);
|
||||||
add(button);
|
add(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlxTween.tween(camera, {alpha: 1}, 0.25, {ease: FlxEase.cubeOut});
|
FlxTween.tween(camera, {alpha: 1}, 0.25, {ease: FlxEase.cubeOut});
|
||||||
FlxTween.tween(camera, {zoom: 1}, 0.66, {ease: FlxEase.elasticOut});
|
FlxTween.tween(camera, {zoom: 1}, 0.66, {ease: FlxEase.elasticOut});
|
||||||
|
|
||||||
CoolUtil.playMenuSFX(WARNING);
|
CoolUtil.playMenuSFX(WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
for(e in camShaders)
|
for(e in camShaders)
|
||||||
e.removeShader(blurShader);
|
e.removeShader(blurShader);
|
||||||
|
|
||||||
FlxTween.cancelTweensOf(warnCam);
|
FlxTween.cancelTweensOf(warnCam);
|
||||||
FlxG.cameras.remove(warnCam);
|
FlxG.cameras.remove(warnCam);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function new(title:String, message:String, buttons:Array<WarningButton>) {
|
public function new(title:String, message:String, buttons:Array<WarningButton>) {
|
||||||
super();
|
super();
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.buttons = buttons;
|
this.buttons = buttons;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typedef WarningCamShader = {
|
typedef WarningCamShader = {
|
||||||
var cam:FlxCamera;
|
var cam:FlxCamera;
|
||||||
}
|
}
|
||||||
typedef WarningButton = {
|
typedef WarningButton = {
|
||||||
var label:String;
|
var label:String;
|
||||||
var onClick:UIWarningSubstate->Void;
|
var onClick:UIWarningSubstate->Void;
|
||||||
}
|
}
|
||||||
@@ -29,20 +29,20 @@ import openfl.filters.ShaderFilter;
|
|||||||
import openfl.Vector;
|
import openfl.Vector;
|
||||||
|
|
||||||
class HudCamera extends FlxCamera {
|
class HudCamera extends FlxCamera {
|
||||||
public var downscroll:Bool = false;
|
public var downscroll:Bool = false;
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
flipY = downscroll;
|
flipY = downscroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override function drawPixels(?frame:FlxFrame, ?pixels:BitmapData, matrix:FlxMatrix, ?transform:ColorTransform, ?blend:BlendMode, ?smoothing:Bool = false,
|
public override function drawPixels(?frame:FlxFrame, ?pixels:BitmapData, matrix:FlxMatrix, ?transform:ColorTransform, ?blend:BlendMode, ?smoothing:Bool = false,
|
||||||
?shader:FlxShader):Void
|
?shader:FlxShader):Void
|
||||||
{
|
{
|
||||||
if (downscroll) {
|
if (downscroll) {
|
||||||
matrix.scale(1, -1);
|
matrix.scale(1, -1);
|
||||||
matrix.translate(0, height);
|
matrix.translate(0, height);
|
||||||
}
|
}
|
||||||
super.drawPixels(frame, pixels, matrix, transform, blend, smoothing, shader);
|
super.drawPixels(frame, pixels, matrix, transform, blend, smoothing, shader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,112 +4,112 @@ import flixel.util.FlxSort;
|
|||||||
import funkin.system.Conductor;
|
import funkin.system.Conductor;
|
||||||
|
|
||||||
class NoteGroup extends FlxTypedGroup<Note> {
|
class NoteGroup extends FlxTypedGroup<Note> {
|
||||||
var __loopSprite:Note;
|
var __loopSprite:Note;
|
||||||
var i:Int = 0;
|
var i:Int = 0;
|
||||||
var __currentlyLooping:Bool = false;
|
var __currentlyLooping:Bool = false;
|
||||||
|
|
||||||
public function addNotes(notes:Array<Note>) {
|
public function addNotes(notes:Array<Note>) {
|
||||||
for(e in notes) add(e);
|
for(e in notes) add(e);
|
||||||
sortNotes();
|
sortNotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sortNotes() {
|
public function sortNotes() {
|
||||||
sort(function(i, n1, n2) {
|
sort(function(i, n1, n2) {
|
||||||
if (n1.strumTime == n2.strumTime)
|
if (n1.strumTime == n2.strumTime)
|
||||||
return n1.isSustainNote ? -1 : 1;
|
return n1.isSustainNote ? -1 : 1;
|
||||||
return FlxSort.byValues(FlxSort.ASCENDING, n1.strumTime, n2.strumTime);
|
return FlxSort.byValues(FlxSort.ASCENDING, n1.strumTime, n2.strumTime);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
i = 0;
|
i = 0;
|
||||||
__loopSprite = null;
|
__loopSprite = null;
|
||||||
while(i < length) {
|
while(i < length) {
|
||||||
__loopSprite = members[i];
|
__loopSprite = members[i];
|
||||||
if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.active) {
|
if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.active) {
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (__loopSprite.strumTime - Conductor.songPosition > 1500)
|
if (__loopSprite.strumTime - Conductor.songPosition > 1500)
|
||||||
break;
|
break;
|
||||||
__loopSprite.update(elapsed);
|
__loopSprite.update(elapsed);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
@:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
|
@:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
|
||||||
@:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras;
|
@:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
__loopSprite = null;
|
__loopSprite = null;
|
||||||
|
|
||||||
var oldCur = __currentlyLooping;
|
var oldCur = __currentlyLooping;
|
||||||
__currentlyLooping = true;
|
__currentlyLooping = true;
|
||||||
while(i < length) {
|
while(i < length) {
|
||||||
__loopSprite = members[i];
|
__loopSprite = members[i];
|
||||||
if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.visible) {
|
if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.visible) {
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (__loopSprite.strumTime - Conductor.songPosition > 1500) break;
|
if (__loopSprite.strumTime - Conductor.songPosition > 1500) break;
|
||||||
__loopSprite.draw();
|
__loopSprite.draw();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
__currentlyLooping = oldCur;
|
__currentlyLooping = oldCur;
|
||||||
|
|
||||||
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function forEach(noteFunc:Note->Void, recursive:Bool = false) {
|
public override function forEach(noteFunc:Note->Void, recursive:Bool = false) {
|
||||||
i = 0;
|
i = 0;
|
||||||
__loopSprite = null;
|
__loopSprite = null;
|
||||||
|
|
||||||
var oldCur = __currentlyLooping;
|
var oldCur = __currentlyLooping;
|
||||||
__currentlyLooping = true;
|
__currentlyLooping = true;
|
||||||
|
|
||||||
while(i < length) {
|
while(i < length) {
|
||||||
__loopSprite = members[i];
|
__loopSprite = members[i];
|
||||||
if (__loopSprite == null || !__loopSprite.exists) {
|
if (__loopSprite == null || !__loopSprite.exists) {
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (__loopSprite.strumTime - Conductor.songPosition > 1500) break;
|
if (__loopSprite.strumTime - Conductor.songPosition > 1500) break;
|
||||||
noteFunc(__loopSprite);
|
noteFunc(__loopSprite);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
__currentlyLooping = oldCur;
|
__currentlyLooping = oldCur;
|
||||||
}
|
}
|
||||||
public override function forEachAlive(noteFunc:Note->Void, recursive:Bool = false) {
|
public override function forEachAlive(noteFunc:Note->Void, recursive:Bool = false) {
|
||||||
forEach(function(note) {
|
forEach(function(note) {
|
||||||
if (note.alive) noteFunc(note);
|
if (note.alive) noteFunc(note);
|
||||||
}, recursive);
|
}, recursive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function remove(Object:Note, Splice:Bool = false):Note
|
public override function remove(Object:Note, Splice:Bool = false):Note
|
||||||
{
|
{
|
||||||
if (members == null)
|
if (members == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var index:Int = members.indexOf(Object);
|
var index:Int = members.indexOf(Object);
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// doesnt prevent looping from breaking
|
// doesnt prevent looping from breaking
|
||||||
if (Splice && __currentlyLooping && i >= index)
|
if (Splice && __currentlyLooping && i >= index)
|
||||||
i--;
|
i--;
|
||||||
|
|
||||||
if (Splice)
|
if (Splice)
|
||||||
{
|
{
|
||||||
members.splice(index, 1);
|
members.splice(index, 1);
|
||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
members[index] = null;
|
members[index] = null;
|
||||||
|
|
||||||
if (_memberRemoved != null)
|
if (_memberRemoved != null)
|
||||||
_memberRemoved.dispatch(Object);
|
_memberRemoved.dispatch(Object);
|
||||||
|
|
||||||
return Object;
|
return Object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,114 +3,114 @@ package funkin.game;
|
|||||||
import haxe.xml.Access;
|
import haxe.xml.Access;
|
||||||
|
|
||||||
class SplashGroup extends FlxTypedGroup<FunkinSprite> {
|
class SplashGroup extends FlxTypedGroup<FunkinSprite> {
|
||||||
/**
|
/**
|
||||||
* Whenever the splash group has successfully loaded or not.
|
* Whenever the splash group has successfully loaded or not.
|
||||||
*/
|
*/
|
||||||
public var valid:Bool = true;
|
public var valid:Bool = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XML data for the note splashes.
|
* XML data for the note splashes.
|
||||||
*/
|
*/
|
||||||
public var xml:Access;
|
public var xml:Access;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation names sorted by strum IDs.
|
* Animation names sorted by strum IDs.
|
||||||
* Use `getSplashAnim` to get one.
|
* Use `getSplashAnim` to get one.
|
||||||
*/
|
*/
|
||||||
public var animationNames:Array<Array<String>> = [];
|
public var animationNames:Array<Array<String>> = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Splash group
|
* Creates a new Splash group
|
||||||
* @param path Path to the splash data (xml)
|
* @param path Path to the splash data (xml)
|
||||||
*/
|
*/
|
||||||
public function new(path) {
|
public function new(path) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
xml = new Access(Xml.parse(Assets.getText(path)).firstElement());
|
xml = new Access(Xml.parse(Assets.getText(path)).firstElement());
|
||||||
|
|
||||||
if (!xml.has.sprite) throw "The <splash> element requires a sprite attribute.";
|
if (!xml.has.sprite) throw "The <splash> element requires a sprite attribute.";
|
||||||
|
|
||||||
var splashSprite = new FunkinSprite();
|
var splashSprite = new FunkinSprite();
|
||||||
splashSprite.antialiasing = true;
|
splashSprite.antialiasing = true;
|
||||||
splashSprite.active = splashSprite.visible = false;
|
splashSprite.active = splashSprite.visible = false;
|
||||||
splashSprite.loadSprite(Paths.image(xml.att.sprite));
|
splashSprite.loadSprite(Paths.image(xml.att.sprite));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ANIMATIONS
|
* ANIMATIONS
|
||||||
*/
|
*/
|
||||||
for(strum in xml.nodes.strum) {
|
for(strum in xml.nodes.strum) {
|
||||||
var id:Null<Int> = Std.parseInt(strum.att.id);
|
var id:Null<Int> = Std.parseInt(strum.att.id);
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
animationNames[id] = [];
|
animationNames[id] = [];
|
||||||
for(anim in strum.nodes.anim) {
|
for(anim in strum.nodes.anim) {
|
||||||
if (!anim.has.name) continue;
|
if (!anim.has.name) continue;
|
||||||
XMLUtil.addXMLAnimation(splashSprite, anim, false);
|
XMLUtil.addXMLAnimation(splashSprite, anim, false);
|
||||||
animationNames[id].push(anim.att.name);
|
animationNames[id].push(anim.att.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (animationNames.length <= 0)
|
if (animationNames.length <= 0)
|
||||||
animationNames.push([]);
|
animationNames.push([]);
|
||||||
for(anim in xml.nodes.anim) {
|
for(anim in xml.nodes.anim) {
|
||||||
if (!anim.has.name) continue;
|
if (!anim.has.name) continue;
|
||||||
XMLUtil.addXMLAnimation(splashSprite, anim, false);
|
XMLUtil.addXMLAnimation(splashSprite, anim, false);
|
||||||
for(a in animationNames) {
|
for(a in animationNames) {
|
||||||
if (a == null) continue;
|
if (a == null) continue;
|
||||||
a.push(anim.att.name);
|
a.push(anim.att.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* END OF ANIMATIONS
|
* END OF ANIMATIONS
|
||||||
*/
|
*/
|
||||||
splashSprite.animation.finishCallback = function(name) {
|
splashSprite.animation.finishCallback = function(name) {
|
||||||
splashSprite.active = splashSprite.visible = false;
|
splashSprite.active = splashSprite.visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (xml.has.scale) splashSprite.scale.scale(Std.parseFloat(xml.att.scale).getDefault(1));
|
if (xml.has.scale) splashSprite.scale.scale(Std.parseFloat(xml.att.scale).getDefault(1));
|
||||||
if (xml.has.alpha) splashSprite.alpha = Std.parseFloat(xml.att.alpha).getDefault(1);
|
if (xml.has.alpha) splashSprite.alpha = Std.parseFloat(xml.att.alpha).getDefault(1);
|
||||||
if (xml.has.antialiasing) splashSprite.antialiasing = xml.att.antialiasing == "true";
|
if (xml.has.antialiasing) splashSprite.antialiasing = xml.att.antialiasing == "true";
|
||||||
|
|
||||||
add(splashSprite);
|
add(splashSprite);
|
||||||
|
|
||||||
for (i in 0...7) {
|
for (i in 0...7) {
|
||||||
// make 7 additional splashes
|
// make 7 additional splashes
|
||||||
var spr = FunkinSprite.copyFrom(splashSprite);
|
var spr = FunkinSprite.copyFrom(splashSprite);
|
||||||
spr.animation.finishCallback = function(name) {
|
spr.animation.finishCallback = function(name) {
|
||||||
spr.active = spr.visible = false;
|
spr.active = spr.visible = false;
|
||||||
};
|
};
|
||||||
add(spr);
|
add(spr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// immediatly draw once and put image in GPU to prevent freezes
|
// immediatly draw once and put image in GPU to prevent freezes
|
||||||
splashSprite.draw();
|
splashSprite.draw();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Couldn\'t parse splash data for "${path}": ${e.toString()}', ERROR);
|
Logs.trace('Couldn\'t parse splash data for "${path}": ${e.toString()}', ERROR);
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxSize = 8;
|
maxSize = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSplashAnim(id:Int):String {
|
public function getSplashAnim(id:Int):String {
|
||||||
if (animationNames.length <= 0) return null;
|
if (animationNames.length <= 0) return null;
|
||||||
id %= animationNames.length;
|
id %= animationNames.length;
|
||||||
if (animationNames[id] == null) return null;
|
if (animationNames[id] == null) return null;
|
||||||
if (animationNames[id].length <= 0) return null;
|
if (animationNames[id].length <= 0) return null;
|
||||||
return animationNames[id][FlxG.random.int(0, animationNames[id].length-1)];
|
return animationNames[id][FlxG.random.int(0, animationNames[id].length-1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
var __splash:FunkinSprite;
|
var __splash:FunkinSprite;
|
||||||
public function showOnStrum(strum:Strum) {
|
public function showOnStrum(strum:Strum) {
|
||||||
if (!valid) return null;
|
if (!valid) return null;
|
||||||
__splash = recycle();
|
__splash = recycle();
|
||||||
|
|
||||||
__splash.cameras = strum.lastDrawCameras;
|
__splash.cameras = strum.lastDrawCameras;
|
||||||
__splash.setPosition(strum.x + ((strum.width - __splash.width) / 2), strum.y + ((strum.height - __splash.height) / 2));
|
__splash.setPosition(strum.x + ((strum.width - __splash.width) / 2), strum.y + ((strum.height - __splash.height) / 2));
|
||||||
__splash.active = __splash.visible = true;
|
__splash.active = __splash.visible = true;
|
||||||
__splash.playAnim(getSplashAnim(strum.ID), true);
|
__splash.playAnim(getSplashAnim(strum.ID), true);
|
||||||
__splash.scrollFactor.set(strum.scrollFactor.x, strum.scrollFactor.y);
|
__splash.scrollFactor.set(strum.scrollFactor.x, strum.scrollFactor.y);
|
||||||
|
|
||||||
return __splash;
|
return __splash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,49 +2,49 @@ package funkin.game;
|
|||||||
|
|
||||||
|
|
||||||
class SplashHandler extends FlxTypedGroup<FunkinSprite> {
|
class SplashHandler extends FlxTypedGroup<FunkinSprite> {
|
||||||
/**
|
/**
|
||||||
* Map containing all of the splashes group.
|
* Map containing all of the splashes group.
|
||||||
*/
|
*/
|
||||||
public var grpMap:Map<String, SplashGroup> = [];
|
public var grpMap:Map<String, SplashGroup> = [];
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a group of splashes, and creates it if it doesn't exist.
|
* Returns a group of splashes, and creates it if it doesn't exist.
|
||||||
* @param path Path to the splashes XML (`Paths.xml('splashes/splash')`)
|
* @param path Path to the splashes XML (`Paths.xml('splashes/splash')`)
|
||||||
*/
|
*/
|
||||||
public function getSplashGroup(name:String) {
|
public function getSplashGroup(name:String) {
|
||||||
if (!grpMap.exists(name)) {
|
if (!grpMap.exists(name)) {
|
||||||
var grp = new SplashGroup(Paths.xml('splashes/$name'));
|
var grp = new SplashGroup(Paths.xml('splashes/$name'));
|
||||||
grpMap.set(name, grp);
|
grpMap.set(name, grp);
|
||||||
}
|
}
|
||||||
return grpMap.get(name);
|
return grpMap.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
for(grp in grpMap)
|
for(grp in grpMap)
|
||||||
grp.destroy();
|
grp.destroy();
|
||||||
grpMap = null;
|
grpMap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var _firstDraw:Bool = true;
|
var _firstDraw:Bool = true;
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
super.draw();
|
super.draw();
|
||||||
if (_firstDraw != (_firstDraw = false))
|
if (_firstDraw != (_firstDraw = false))
|
||||||
for(grp in grpMap)
|
for(grp in grpMap)
|
||||||
grp.draw();
|
grp.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
var __grp:SplashGroup;
|
var __grp:SplashGroup;
|
||||||
public function showSplash(name:String, strum:Strum) {
|
public function showSplash(name:String, strum:Strum) {
|
||||||
__grp = getSplashGroup(name);
|
__grp = getSplashGroup(name);
|
||||||
add(__grp.showOnStrum(strum));
|
add(__grp.showOnStrum(strum));
|
||||||
|
|
||||||
// max 8 rendered splashes
|
// max 8 rendered splashes
|
||||||
while(members.length > 8)
|
while(members.length > 8)
|
||||||
remove(members[0]);
|
remove(members[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+192
-192
@@ -9,227 +9,227 @@ import haxe.io.Path;
|
|||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
class Stage extends FlxBasic implements IBeatReceiver {
|
class Stage extends FlxBasic implements IBeatReceiver {
|
||||||
public var stageXML:Access;
|
public var stageXML:Access;
|
||||||
public var stagePath:String;
|
public var stagePath:String;
|
||||||
public var stageSprites:Map<String, FlxSprite> = [];
|
public var stageSprites:Map<String, FlxSprite> = [];
|
||||||
public var stageScript:Script;
|
public var stageScript:Script;
|
||||||
public var state:FlxState;
|
public var state:FlxState;
|
||||||
public var characterPoses:Map<String, StageCharPos> = [];
|
public var characterPoses:Map<String, StageCharPos> = [];
|
||||||
|
|
||||||
public function getSprite(name:String) {
|
public function getSprite(name:String) {
|
||||||
return stageSprites[name];
|
return stageSprites[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function new(stage:String, ?state:FlxState) {
|
public function new(stage:String, ?state:FlxState) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if (state == null) state = PlayState.instance;
|
if (state == null) state = PlayState.instance;
|
||||||
if (state == null) state = FlxG.state;
|
if (state == null) state = FlxG.state;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
|
||||||
stagePath = Paths.xml('stages/$stage');
|
stagePath = Paths.xml('stages/$stage');
|
||||||
try {
|
try {
|
||||||
if (Assets.exists(stagePath)) stageXML = new Access(Xml.parse(Assets.getText(stagePath)).firstElement());
|
if (Assets.exists(stagePath)) stageXML = new Access(Xml.parse(Assets.getText(stagePath)).firstElement());
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Couldn\'t load stage "$stage": ${e.message}', ERROR);
|
Logs.trace('Couldn\'t load stage "$stage": ${e.message}', ERROR);
|
||||||
}
|
}
|
||||||
if (stageXML != null) {
|
if (stageXML != null) {
|
||||||
|
|
||||||
var spritesParentFolder = "";
|
var spritesParentFolder = "";
|
||||||
if (PlayState.instance != null) {
|
if (PlayState.instance != null) {
|
||||||
if (stageXML.has.zoom) {
|
if (stageXML.has.zoom) {
|
||||||
var parsed:Null<Float> = Std.parseFloat(stageXML.att.zoom);
|
var parsed:Null<Float> = Std.parseFloat(stageXML.att.zoom);
|
||||||
if (parsed != null && PlayState.instance != null) PlayState.instance.defaultCamZoom = parsed;
|
if (parsed != null && PlayState.instance != null) PlayState.instance.defaultCamZoom = parsed;
|
||||||
}
|
}
|
||||||
PlayState.instance.curStage = stageXML.has.name ? stageXML.att.name : stage;
|
PlayState.instance.curStage = stageXML.has.name ? stageXML.att.name : stage;
|
||||||
}
|
}
|
||||||
if (stageXML.has.folder) {
|
if (stageXML.has.folder) {
|
||||||
spritesParentFolder = stageXML.att.folder;
|
spritesParentFolder = stageXML.att.folder;
|
||||||
if (spritesParentFolder.charAt(spritesParentFolder.length-1) != "/") spritesParentFolder = spritesParentFolder + "/";
|
if (spritesParentFolder.charAt(spritesParentFolder.length-1) != "/") spritesParentFolder = spritesParentFolder + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
var elems = [];
|
var elems = [];
|
||||||
for(node in stageXML.elements) {
|
for(node in stageXML.elements) {
|
||||||
if (node.name == "high-memory" && !Options.lowMemoryMode)
|
if (node.name == "high-memory" && !Options.lowMemoryMode)
|
||||||
for(e in node.elements)
|
for(e in node.elements)
|
||||||
elems.push(e);
|
elems.push(e);
|
||||||
else
|
else
|
||||||
elems.push(node);
|
elems.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(node in elems) {
|
for(node in elems) {
|
||||||
var sprite:Dynamic = switch(node.name) {
|
var sprite:Dynamic = switch(node.name) {
|
||||||
case "sprite" | "spr" | "sparrow":
|
case "sprite" | "spr" | "sparrow":
|
||||||
if (!node.has.sprite || !node.has.name || !node.has.x || !node.has.y) continue;
|
if (!node.has.sprite || !node.has.name || !node.has.x || !node.has.y) continue;
|
||||||
|
|
||||||
var spr = XMLUtil.createSpriteFromXML(node, spritesParentFolder, BEAT);
|
var spr = XMLUtil.createSpriteFromXML(node, spritesParentFolder, BEAT);
|
||||||
|
|
||||||
if (!node.has.zoomfactor && PlayState.instance != null)
|
if (!node.has.zoomfactor && PlayState.instance != null)
|
||||||
spr.initialZoom = PlayState.instance.defaultCamZoom;
|
spr.initialZoom = PlayState.instance.defaultCamZoom;
|
||||||
|
|
||||||
stageSprites.set(spr.name, spr);
|
stageSprites.set(spr.name, spr);
|
||||||
state.add(spr);
|
state.add(spr);
|
||||||
spr;
|
spr;
|
||||||
case "box":
|
case "box":
|
||||||
if ( !node.has.name || !node.has.width || !node.has.height) continue;
|
if ( !node.has.name || !node.has.width || !node.has.height) continue;
|
||||||
|
|
||||||
var spr = new FlxSprite(
|
var spr = new FlxSprite(
|
||||||
(node.has.x) ? Std.parseFloat(node.att.x) : 0,
|
(node.has.x) ? Std.parseFloat(node.att.x) : 0,
|
||||||
(node.has.y) ? Std.parseFloat(node.att.y) : 0
|
(node.has.y) ? Std.parseFloat(node.att.y) : 0
|
||||||
).makeGraphic(
|
).makeGraphic(
|
||||||
Std.parseInt(node.att.width),
|
Std.parseInt(node.att.width),
|
||||||
Std.parseInt(node.att.height),
|
Std.parseInt(node.att.height),
|
||||||
(node.has.color) ? CoolUtil.getColorFromDynamic(node.att.color) : 0xFFFFFFFF
|
(node.has.color) ? CoolUtil.getColorFromDynamic(node.att.color) : 0xFFFFFFFF
|
||||||
);
|
);
|
||||||
|
|
||||||
stageSprites.set(node.getAtt("name"), spr);
|
stageSprites.set(node.getAtt("name"), spr);
|
||||||
state.add(spr);
|
state.add(spr);
|
||||||
spr;
|
spr;
|
||||||
case "boyfriend" | "bf":
|
case "boyfriend" | "bf":
|
||||||
addCharPos("boyfriend", node, {
|
addCharPos("boyfriend", node, {
|
||||||
x: 770,
|
x: 770,
|
||||||
y: 100,
|
y: 100,
|
||||||
flip: true
|
flip: true
|
||||||
});
|
});
|
||||||
null;
|
null;
|
||||||
case "girlfriend" | "gf":
|
case "girlfriend" | "gf":
|
||||||
addCharPos("girlfriend", node, {
|
addCharPos("girlfriend", node, {
|
||||||
x: 400,
|
x: 400,
|
||||||
y: 130,
|
y: 130,
|
||||||
flip: false
|
flip: false
|
||||||
});
|
});
|
||||||
null;
|
null;
|
||||||
case "dad" | "opponent":
|
case "dad" | "opponent":
|
||||||
addCharPos("dad", node, {
|
addCharPos("dad", node, {
|
||||||
x: 100,
|
x: 100,
|
||||||
y: 100,
|
y: 100,
|
||||||
flip: false
|
flip: false
|
||||||
});
|
});
|
||||||
null;
|
null;
|
||||||
case "character":
|
case "character":
|
||||||
if (!node.has.name) continue;
|
if (!node.has.name) continue;
|
||||||
addCharPos(node.att.name, node);
|
addCharPos(node.att.name, node);
|
||||||
null;
|
null;
|
||||||
case "ratings" | "combo":
|
case "ratings" | "combo":
|
||||||
if (PlayState.instance == null) continue;
|
if (PlayState.instance == null) continue;
|
||||||
PlayState.instance.comboGroup.setPosition(
|
PlayState.instance.comboGroup.setPosition(
|
||||||
Std.parseFloat(node.getAtt("x")).getDefault(PlayState.instance.comboGroup.x),
|
Std.parseFloat(node.getAtt("x")).getDefault(PlayState.instance.comboGroup.x),
|
||||||
Std.parseFloat(node.getAtt("y")).getDefault(PlayState.instance.comboGroup.y)
|
Std.parseFloat(node.getAtt("y")).getDefault(PlayState.instance.comboGroup.y)
|
||||||
);
|
);
|
||||||
PlayState.instance.add(PlayState.instance.comboGroup);
|
PlayState.instance.add(PlayState.instance.comboGroup);
|
||||||
PlayState.instance.comboGroup;
|
PlayState.instance.comboGroup;
|
||||||
default: null;
|
default: null;
|
||||||
}
|
}
|
||||||
if (sprite != null) {
|
if (sprite != null) {
|
||||||
for(e in node.nodes.property)
|
for(e in node.nodes.property)
|
||||||
XMLUtil.applyXMLProperty(sprite, e);
|
XMLUtil.applyXMLProperty(sprite, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (characterPoses["girlfriend"] == null)
|
if (characterPoses["girlfriend"] == null)
|
||||||
addCharPos("girlfriend", null, {
|
addCharPos("girlfriend", null, {
|
||||||
x: 400,
|
x: 400,
|
||||||
y: 130,
|
y: 130,
|
||||||
flip: false
|
flip: false
|
||||||
});
|
});
|
||||||
|
|
||||||
if (characterPoses["dad"] == null)
|
if (characterPoses["dad"] == null)
|
||||||
addCharPos("dad", null, {
|
addCharPos("dad", null, {
|
||||||
x: 100,
|
x: 100,
|
||||||
y: 100,
|
y: 100,
|
||||||
flip: false
|
flip: false
|
||||||
});
|
});
|
||||||
|
|
||||||
if (characterPoses["boyfriend"] == null)
|
if (characterPoses["boyfriend"] == null)
|
||||||
addCharPos("boyfriend", null, {
|
addCharPos("boyfriend", null, {
|
||||||
x: 770,
|
x: 770,
|
||||||
y: 100,
|
y: 100,
|
||||||
flip: true
|
flip: true
|
||||||
});
|
});
|
||||||
|
|
||||||
if (PlayState.instance == null) return;
|
if (PlayState.instance == null) return;
|
||||||
stageScript = Script.create(Paths.script('data/stages/$stage'));
|
stageScript = Script.create(Paths.script('data/stages/$stage'));
|
||||||
for(k=>e in stageSprites) {
|
for(k=>e in stageSprites) {
|
||||||
stageScript.set(k, e);
|
stageScript.set(k, e);
|
||||||
}
|
}
|
||||||
PlayState.instance.scripts.add(stageScript);
|
PlayState.instance.scripts.add(stageScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addCharPos(name:String, node:Access, ?nonXMLInfo:StageCharPosInfo) {
|
public function addCharPos(name:String, node:Access, ?nonXMLInfo:StageCharPosInfo) {
|
||||||
var dummyBasic:FlxBasic = new FlxBasic();
|
var dummyBasic:FlxBasic = new FlxBasic();
|
||||||
dummyBasic.active = false;
|
dummyBasic.active = false;
|
||||||
state.add(dummyBasic);
|
state.add(dummyBasic);
|
||||||
|
|
||||||
characterPoses[name] = {
|
characterPoses[name] = {
|
||||||
node: node,
|
node: node,
|
||||||
nonXMLInfo: nonXMLInfo,
|
nonXMLInfo: nonXMLInfo,
|
||||||
dummy: dummyBasic
|
dummy: dummyBasic
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isCharFlipped(posName:String, def:Bool = false) {
|
public function isCharFlipped(posName:String, def:Bool = false) {
|
||||||
if (characterPoses[posName] != null) {
|
if (characterPoses[posName] != null) {
|
||||||
var charPos = characterPoses[posName];
|
var charPos = characterPoses[posName];
|
||||||
if (charPos.node != null && charPos.node.has.flip)
|
if (charPos.node != null && charPos.node.has.flip)
|
||||||
return charPos.node.att.flip == "true";
|
return charPos.node.att.flip == "true";
|
||||||
if (charPos.nonXMLInfo != null)
|
if (charPos.nonXMLInfo != null)
|
||||||
return characterPoses[posName].nonXMLInfo.flip;
|
return characterPoses[posName].nonXMLInfo.flip;
|
||||||
}
|
}
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyCharStuff(char:Character, posName:String) {
|
public function applyCharStuff(char:Character, posName:String) {
|
||||||
if (characterPoses[posName] == null)
|
if (characterPoses[posName] == null)
|
||||||
state.add(char);
|
state.add(char);
|
||||||
else {
|
else {
|
||||||
var charPos = characterPoses[posName];
|
var charPos = characterPoses[posName];
|
||||||
if (charPos.nonXMLInfo != null)
|
if (charPos.nonXMLInfo != null)
|
||||||
char.setPosition(charPos.nonXMLInfo.x, charPos.nonXMLInfo.y);
|
char.setPosition(charPos.nonXMLInfo.x, charPos.nonXMLInfo.y);
|
||||||
if (charPos.node != null)
|
if (charPos.node != null)
|
||||||
doCharNodeShit(char, charPos.node);
|
doCharNodeShit(char, charPos.node);
|
||||||
state.insert(state.members.indexOf(charPos.dummy), char);
|
state.insert(state.members.indexOf(charPos.dummy), char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static function doCharNodeShit(char:Character, node:Access) {
|
private static function doCharNodeShit(char:Character, node:Access) {
|
||||||
if (node.has.x) {
|
if (node.has.x) {
|
||||||
var x:Null<Float> = Std.parseFloat(node.att.x);
|
var x:Null<Float> = Std.parseFloat(node.att.x);
|
||||||
if (x != null) char.x = x;
|
if (x != null) char.x = x;
|
||||||
}
|
}
|
||||||
if (node.has.y) {
|
if (node.has.y) {
|
||||||
var y:Null<Float> = Std.parseFloat(node.att.y);
|
var y:Null<Float> = Std.parseFloat(node.att.y);
|
||||||
if (y != null) char.y = y;
|
if (y != null) char.y = y;
|
||||||
}
|
}
|
||||||
if (node.has.camxoffset) {
|
if (node.has.camxoffset) {
|
||||||
var x:Null<Float> = Std.parseFloat(node.att.camxoffset);
|
var x:Null<Float> = Std.parseFloat(node.att.camxoffset);
|
||||||
if (x != null) char.cameraOffset.x += x;
|
if (x != null) char.cameraOffset.x += x;
|
||||||
}
|
}
|
||||||
if (node.has.camyoffset) {
|
if (node.has.camyoffset) {
|
||||||
var y:Null<Float> = Std.parseFloat(node.att.camyoffset);
|
var y:Null<Float> = Std.parseFloat(node.att.camyoffset);
|
||||||
if (y != null) char.cameraOffset.y += y;
|
if (y != null) char.cameraOffset.y += y;
|
||||||
}
|
}
|
||||||
if (node.has.scroll) {
|
if (node.has.scroll) {
|
||||||
var scroll:Null<Float> = Std.parseFloat(node.att.scroll);
|
var scroll:Null<Float> = Std.parseFloat(node.att.scroll);
|
||||||
if (scroll != null) char.scrollFactor.set(scroll, scroll);
|
if (scroll != null) char.scrollFactor.set(scroll, scroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function beatHit(curBeat:Int) {}
|
public function beatHit(curBeat:Int) {}
|
||||||
|
|
||||||
public function stepHit(curStep:Int) {}
|
public function stepHit(curStep:Int) {}
|
||||||
|
|
||||||
public function measureHit(curMeasure:Int) {}
|
public function measureHit(curMeasure:Int) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef StageCharPos = {
|
typedef StageCharPos = {
|
||||||
var node:Access;
|
var node:Access;
|
||||||
var dummy:FlxBasic;
|
var dummy:FlxBasic;
|
||||||
var ?nonXMLInfo:StageCharPosInfo;
|
var ?nonXMLInfo:StageCharPosInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef StageCharPosInfo = {
|
typedef StageCharPosInfo = {
|
||||||
var x:Float;
|
var x:Float;
|
||||||
var y:Float;
|
var y:Float;
|
||||||
var flip:Bool;
|
var flip:Bool;
|
||||||
}
|
}
|
||||||
+104
-104
@@ -4,122 +4,122 @@ import flixel.math.FlxPoint;
|
|||||||
import funkin.system.Conductor;
|
import funkin.system.Conductor;
|
||||||
|
|
||||||
class Strum extends FlxSprite {
|
class Strum extends FlxSprite {
|
||||||
public var cpu = false;
|
public var cpu = false;
|
||||||
public var lastHit:Float = -5000;
|
public var lastHit:Float = -5000;
|
||||||
|
|
||||||
public var scrollSpeed:Null<Float> = null; // custom scroll speed per strum
|
public var scrollSpeed:Null<Float> = null; // custom scroll speed per strum
|
||||||
public var noteAngle:Null<Float> = null; // custom scroll speed per strum
|
public var noteAngle:Null<Float> = null; // custom scroll speed per strum
|
||||||
|
|
||||||
public var lastDrawCameras(default, null):Array<FlxCamera> = [];
|
public var lastDrawCameras(default, null):Array<FlxCamera> = [];
|
||||||
|
|
||||||
public inline function getScrollSpeed(?note:Note):Float {
|
public inline function getScrollSpeed(?note:Note):Float {
|
||||||
if (note != null && note.scrollSpeed != null) return note.scrollSpeed;
|
if (note != null && note.scrollSpeed != null) return note.scrollSpeed;
|
||||||
if (scrollSpeed != null) return scrollSpeed;
|
if (scrollSpeed != null) return scrollSpeed;
|
||||||
if (PlayState.instance != null) return PlayState.instance.scrollSpeed;
|
if (PlayState.instance != null) return PlayState.instance.scrollSpeed;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline function getNotesAngle(?note:Note):Float {
|
public inline function getNotesAngle(?note:Note):Float {
|
||||||
if (note != null && note.noteAngle != null) return note.noteAngle;
|
if (note != null && note.noteAngle != null) return note.noteAngle;
|
||||||
if (noteAngle != null) return noteAngle;
|
if (noteAngle != null) return noteAngle;
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
if (cpu) {
|
if (cpu) {
|
||||||
if (lastHit + (Conductor.crochet / 2) < Conductor.songPosition && getAnim() == "confirm") {
|
if (lastHit + (Conductor.crochet / 2) < Conductor.songPosition && getAnim() == "confirm") {
|
||||||
playAnim("static");
|
playAnim("static");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
lastDrawCameras = [for(c in cameras) c];
|
lastDrawCameras = [for(c in cameras) c];
|
||||||
super.draw();
|
super.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@:noCompletion public static final PIX180:Float = 565.4866776461628; // 180 * Math.PI
|
@:noCompletion public static final PIX180:Float = 565.4866776461628; // 180 * Math.PI
|
||||||
@:noCompletion public static final N_WIDTHDIV2:Float = Note.swagWidth / 2;
|
@:noCompletion public static final N_WIDTHDIV2:Float = Note.swagWidth / 2;
|
||||||
|
|
||||||
public function updateNotePosition(daNote:Note) {
|
public function updateNotePosition(daNote:Note) {
|
||||||
if (!daNote.exists) return;
|
if (!daNote.exists) return;
|
||||||
|
|
||||||
daNote.__strumCameras = lastDrawCameras;
|
daNote.__strumCameras = lastDrawCameras;
|
||||||
daNote.__strum = this;
|
daNote.__strum = this;
|
||||||
daNote.scrollFactor.set(scrollFactor.x, scrollFactor.y);
|
daNote.scrollFactor.set(scrollFactor.x, scrollFactor.y);
|
||||||
daNote.__noteAngle = getNotesAngle(daNote);
|
daNote.__noteAngle = getNotesAngle(daNote);
|
||||||
daNote.angle = daNote.isSustainNote ? daNote.__noteAngle : angle;
|
daNote.angle = daNote.isSustainNote ? daNote.__noteAngle : angle;
|
||||||
|
|
||||||
if (daNote.strumRelativePos) {
|
if (daNote.strumRelativePos) {
|
||||||
daNote.setPosition(daNote.isSustainNote ? ((Note.swagWidth - daNote.width) / 2) : 0, (daNote.strumTime - Conductor.songPosition) * (0.45 * FlxMath.roundDecimal(getScrollSpeed(daNote), 2)));
|
daNote.setPosition(daNote.isSustainNote ? ((Note.swagWidth - daNote.width) / 2) : 0, (daNote.strumTime - Conductor.songPosition) * (0.45 * FlxMath.roundDecimal(getScrollSpeed(daNote), 2)));
|
||||||
if (daNote.isSustainNote) daNote.y += N_WIDTHDIV2;
|
if (daNote.isSustainNote) daNote.y += N_WIDTHDIV2;
|
||||||
} else {
|
} else {
|
||||||
var offset = FlxPoint.get(0, (Conductor.songPosition - daNote.strumTime) * (0.45 * FlxMath.roundDecimal(getScrollSpeed(daNote), 2)));
|
var offset = FlxPoint.get(0, (Conductor.songPosition - daNote.strumTime) * (0.45 * FlxMath.roundDecimal(getScrollSpeed(daNote), 2)));
|
||||||
var realOffset = FlxPoint.get(0, 0);
|
var realOffset = FlxPoint.get(0, 0);
|
||||||
|
|
||||||
if (daNote.isSustainNote) offset.y -= N_WIDTHDIV2;
|
if (daNote.isSustainNote) offset.y -= N_WIDTHDIV2;
|
||||||
|
|
||||||
if (Std.int(daNote.__noteAngle % 360) != 0) {
|
if (Std.int(daNote.__noteAngle % 360) != 0) {
|
||||||
var noteAngleCos = FlxMath.fastCos(daNote.__noteAngle / PIX180);
|
var noteAngleCos = FlxMath.fastCos(daNote.__noteAngle / PIX180);
|
||||||
var noteAngleSin = FlxMath.fastSin(daNote.__noteAngle / PIX180);
|
var noteAngleSin = FlxMath.fastSin(daNote.__noteAngle / PIX180);
|
||||||
|
|
||||||
var aOffset:FlxPoint = FlxPoint.get(
|
var aOffset:FlxPoint = FlxPoint.get(
|
||||||
(daNote.origin.x / daNote.scale.x) - daNote.offset.x,
|
(daNote.origin.x / daNote.scale.x) - daNote.offset.x,
|
||||||
(daNote.origin.y / daNote.scale.y) - daNote.offset.y
|
(daNote.origin.y / daNote.scale.y) - daNote.offset.y
|
||||||
);
|
);
|
||||||
realOffset.x = -aOffset.x + (noteAngleCos * (offset.x + aOffset.x)) + (noteAngleSin * (offset.y + aOffset.y));
|
realOffset.x = -aOffset.x + (noteAngleCos * (offset.x + aOffset.x)) + (noteAngleSin * (offset.y + aOffset.y));
|
||||||
realOffset.y = -aOffset.y + (noteAngleSin * (offset.x + aOffset.x)) + (noteAngleCos * (offset.y + aOffset.y));
|
realOffset.y = -aOffset.y + (noteAngleSin * (offset.x + aOffset.x)) + (noteAngleCos * (offset.y + aOffset.y));
|
||||||
|
|
||||||
aOffset.put();
|
aOffset.put();
|
||||||
} else {
|
} else {
|
||||||
realOffset.x = offset.x;
|
realOffset.x = offset.x;
|
||||||
realOffset.y = offset.y;
|
realOffset.y = offset.y;
|
||||||
}
|
}
|
||||||
realOffset.y *= -1;
|
realOffset.y *= -1;
|
||||||
|
|
||||||
daNote.setPosition(x + realOffset.x, y + realOffset.y);
|
daNote.setPosition(x + realOffset.x, y + realOffset.y);
|
||||||
|
|
||||||
offset.put();
|
offset.put();
|
||||||
realOffset.put();
|
realOffset.put();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateSustain(daNote:Note) {
|
public function updateSustain(daNote:Note) {
|
||||||
if (!daNote.isSustainNote) return;
|
if (!daNote.isSustainNote) return;
|
||||||
daNote.updateSustain(this);
|
daNote.updateSustain(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updatePlayerInput(pressed:Bool, justPressed:Bool, justReleased:Bool) {
|
public function updatePlayerInput(pressed:Bool, justPressed:Bool, justReleased:Bool) {
|
||||||
switch(getAnim()) {
|
switch(getAnim()) {
|
||||||
case "confirm":
|
case "confirm":
|
||||||
if (justReleased || !pressed)
|
if (justReleased || !pressed)
|
||||||
playAnim("static");
|
playAnim("static");
|
||||||
case "pressed":
|
case "pressed":
|
||||||
if (justReleased || !pressed)
|
if (justReleased || !pressed)
|
||||||
playAnim("static");
|
playAnim("static");
|
||||||
case "static":
|
case "static":
|
||||||
if (justPressed || pressed)
|
if (justPressed || pressed)
|
||||||
playAnim("pressed");
|
playAnim("pressed");
|
||||||
case null:
|
case null:
|
||||||
playAnim("static");
|
playAnim("static");
|
||||||
}
|
}
|
||||||
centerOffsets();
|
centerOffsets();
|
||||||
centerOrigin();
|
centerOrigin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function press(time:Float) {
|
public function press(time:Float) {
|
||||||
lastHit = time;
|
lastHit = time;
|
||||||
playAnim("confirm");
|
playAnim("confirm");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function playAnim(anim:String, force:Bool = true) {
|
public function playAnim(anim:String, force:Bool = true) {
|
||||||
var oldAnim = animation.curAnim;
|
var oldAnim = animation.curAnim;
|
||||||
animation.play(anim, force);
|
animation.play(anim, force);
|
||||||
centerOffsets();
|
centerOffsets();
|
||||||
centerOrigin();
|
centerOrigin();
|
||||||
}
|
}
|
||||||
public function getAnim() {
|
public function getAnim() {
|
||||||
return animation.curAnim == null ? null : animation.curAnim.name;
|
return animation.curAnim == null ? null : animation.curAnim.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+181
-181
@@ -9,206 +9,206 @@ import funkin.system.Controls;
|
|||||||
import flixel.tweens.FlxTween;
|
import flixel.tweens.FlxTween;
|
||||||
|
|
||||||
class StrumLine extends FlxTypedGroup<Strum> {
|
class StrumLine extends FlxTypedGroup<Strum> {
|
||||||
/**
|
/**
|
||||||
* Signal that triggers whenever a note is hit. Similar to onPlayerHit and onDadHit, except strumline specific.
|
* Signal that triggers whenever a note is hit. Similar to onPlayerHit and onDadHit, except strumline specific.
|
||||||
* To add a listener, do
|
* To add a listener, do
|
||||||
* `strumLine.onHit.add(function(e:NoteHitEvent) {});`
|
* `strumLine.onHit.add(function(e:NoteHitEvent) {});`
|
||||||
*/
|
*/
|
||||||
public var onHit:FlxTypedSignal<NoteHitEvent->Void> = new FlxTypedSignal<NoteHitEvent->Void>();
|
public var onHit:FlxTypedSignal<NoteHitEvent->Void> = new FlxTypedSignal<NoteHitEvent->Void>();
|
||||||
/**
|
/**
|
||||||
* Signal that triggers whenever a note is missed. Similar to onPlayerMiss and onDadMiss, except strumline specific.
|
* Signal that triggers whenever a note is missed. Similar to onPlayerMiss and onDadMiss, except strumline specific.
|
||||||
* To add a listener, do
|
* To add a listener, do
|
||||||
* `strumLine.onMiss.add(function(e:NoteHitEvent) {});`
|
* `strumLine.onMiss.add(function(e:NoteHitEvent) {});`
|
||||||
*/
|
*/
|
||||||
public var onMiss:FlxTypedSignal<NoteHitEvent->Void> = new FlxTypedSignal<NoteHitEvent->Void>();
|
public var onMiss:FlxTypedSignal<NoteHitEvent->Void> = new FlxTypedSignal<NoteHitEvent->Void>();
|
||||||
/**
|
/**
|
||||||
* Signal that triggers whenever a note is being updated. Similar to onNoteUpdate, except strumline specific.
|
* Signal that triggers whenever a note is being updated. Similar to onNoteUpdate, except strumline specific.
|
||||||
* To add a listener, do
|
* To add a listener, do
|
||||||
* `strumLine.onNoteUpdate.add(function(e:NoteUpdateEvent) {});`
|
* `strumLine.onNoteUpdate.add(function(e:NoteUpdateEvent) {});`
|
||||||
*/
|
*/
|
||||||
public var onNoteUpdate:FlxTypedSignal<NoteUpdateEvent->Void> = new FlxTypedSignal<NoteUpdateEvent->Void>();
|
public var onNoteUpdate:FlxTypedSignal<NoteUpdateEvent->Void> = new FlxTypedSignal<NoteUpdateEvent->Void>();
|
||||||
/**
|
/**
|
||||||
* Array containing all of the characters "attached" to those strums.
|
* Array containing all of the characters "attached" to those strums.
|
||||||
*/
|
*/
|
||||||
public var characters:Array<Character>;
|
public var characters:Array<Character>;
|
||||||
/**
|
/**
|
||||||
* Whenever this strumline is controlled by cpu or not.
|
* Whenever this strumline is controlled by cpu or not.
|
||||||
*/
|
*/
|
||||||
public var cpu(default, set):Bool = false;
|
public var cpu(default, set):Bool = false;
|
||||||
/**
|
/**
|
||||||
* Whenever this strumline is from the opponent side or the player side.
|
* Whenever this strumline is from the opponent side or the player side.
|
||||||
*/
|
*/
|
||||||
public var opponentSide:Bool = false;
|
public var opponentSide:Bool = false;
|
||||||
/**
|
/**
|
||||||
* Controls assigned to this strumline.
|
* Controls assigned to this strumline.
|
||||||
*/
|
*/
|
||||||
public var controls:Controls = null;
|
public var controls:Controls = null;
|
||||||
/**
|
/**
|
||||||
* Chart JSON data assigned to this StrumLine (Codename format)
|
* Chart JSON data assigned to this StrumLine (Codename format)
|
||||||
*/
|
*/
|
||||||
public var data:ChartStrumLine = null;
|
public var data:ChartStrumLine = null;
|
||||||
/**
|
/**
|
||||||
* Whenever Ghost Tapping is enabled.
|
* Whenever Ghost Tapping is enabled.
|
||||||
*/
|
*/
|
||||||
@:isVar public var ghostTapping(get, set):Null<Bool> = null;
|
@:isVar public var ghostTapping(get, set):Null<Bool> = null;
|
||||||
/**
|
/**
|
||||||
* Group of all of the notes in this strumline. Using `forEach` on this group will only loop through the first notes for performance reasons.
|
* Group of all of the notes in this strumline. Using `forEach` on this group will only loop through the first notes for performance reasons.
|
||||||
*/
|
*/
|
||||||
public var notes:NoteGroup;
|
public var notes:NoteGroup;
|
||||||
|
|
||||||
private function get_ghostTapping() {
|
private function get_ghostTapping() {
|
||||||
if (this.ghostTapping != null) return this.ghostTapping;
|
if (this.ghostTapping != null) return this.ghostTapping;
|
||||||
if (PlayState.instance != null) return PlayState.instance.ghostTapping;
|
if (PlayState.instance != null) return PlayState.instance.ghostTapping;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline function set_ghostTapping(b:Bool):Bool
|
private inline function set_ghostTapping(b:Bool):Bool
|
||||||
return this.ghostTapping = b;
|
return this.ghostTapping = b;
|
||||||
|
|
||||||
private var strumOffset:Float = 0.25;
|
private var strumOffset:Float = 0.25;
|
||||||
|
|
||||||
public function new(characters:Array<Character>, strumOffset:Float = 0.25, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls) {
|
public function new(characters:Array<Character>, strumOffset:Float = 0.25, cpu:Bool = false, opponentSide:Bool = true, ?controls:Controls) {
|
||||||
super();
|
super();
|
||||||
this.characters = characters;
|
this.characters = characters;
|
||||||
this.strumOffset = strumOffset;
|
this.strumOffset = strumOffset;
|
||||||
this.cpu = cpu;
|
this.cpu = cpu;
|
||||||
this.opponentSide = opponentSide;
|
this.opponentSide = opponentSide;
|
||||||
this.controls = controls;
|
this.controls = controls;
|
||||||
this.notes = new NoteGroup();
|
this.notes = new NoteGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generate(strumLine:ChartStrumLine) {
|
public function generate(strumLine:ChartStrumLine) {
|
||||||
if (strumLine.notes != null) for(note in strumLine.notes) {
|
if (strumLine.notes != null) for(note in strumLine.notes) {
|
||||||
notes.add(new Note(this, note, false));
|
notes.add(new Note(this, note, false));
|
||||||
|
|
||||||
if (note.sLen > Conductor.stepCrochet * 0.75) {
|
if (note.sLen > Conductor.stepCrochet * 0.75) {
|
||||||
var len:Float = note.sLen;
|
var len:Float = note.sLen;
|
||||||
var curLen:Float = 0;
|
var curLen:Float = 0;
|
||||||
while(len > 10) {
|
while(len > 10) {
|
||||||
curLen = Math.min(len, Conductor.stepCrochet);
|
curLen = Math.min(len, Conductor.stepCrochet);
|
||||||
notes.add(new Note(this, note, true, curLen, note.sLen - len));
|
notes.add(new Note(this, note, true, curLen, note.sLen - len));
|
||||||
len -= curLen;
|
len -= curLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notes.sortNotes();
|
notes.sortNotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
notes.update(elapsed);
|
notes.update(elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
super.draw();
|
super.draw();
|
||||||
notes.cameras = cameras;
|
notes.cameras = cameras;
|
||||||
notes.draw();
|
notes.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateNotes() {
|
public function updateNotes() {
|
||||||
notes.forEach(updateNote);
|
notes.forEach(updateNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
var __updateNote_strum:Strum;
|
var __updateNote_strum:Strum;
|
||||||
public function updateNote(daNote:Note) {
|
public function updateNote(daNote:Note) {
|
||||||
|
|
||||||
for(e in members) {
|
for(e in members) {
|
||||||
if (e.ID == daNote.noteData % 4) {
|
if (e.ID == daNote.noteData % 4) {
|
||||||
__updateNote_strum = e;
|
__updateNote_strum = e;
|
||||||
break; //ing bad
|
break; //ing bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PlayState.instance.scripts.event("onNoteUpdate", PlayState.instance.__updateNote_event.recycle(daNote, FlxG.elapsed, __updateNote_strum));
|
PlayState.instance.scripts.event("onNoteUpdate", PlayState.instance.__updateNote_event.recycle(daNote, FlxG.elapsed, __updateNote_strum));
|
||||||
onNoteUpdate.dispatch(PlayState.instance.__updateNote_event);
|
onNoteUpdate.dispatch(PlayState.instance.__updateNote_event);
|
||||||
if (PlayState.instance.__updateNote_event.cancelled) return;
|
if (PlayState.instance.__updateNote_event.cancelled) return;
|
||||||
|
|
||||||
if (PlayState.instance.__updateNote_event.__updateHitWindow) {
|
if (PlayState.instance.__updateNote_event.__updateHitWindow) {
|
||||||
daNote.canBeHit = (daNote.strumTime > Conductor.songPosition - (PlayState.instance.hitWindow * daNote.latePressWindow)
|
daNote.canBeHit = (daNote.strumTime > Conductor.songPosition - (PlayState.instance.hitWindow * daNote.latePressWindow)
|
||||||
&& daNote.strumTime < Conductor.songPosition + (PlayState.instance.hitWindow * daNote.earlyPressWindow));
|
&& daNote.strumTime < Conductor.songPosition + (PlayState.instance.hitWindow * daNote.earlyPressWindow));
|
||||||
|
|
||||||
if (daNote.strumTime < Conductor.songPosition - PlayState.instance.hitWindow && !daNote.wasGoodHit)
|
if (daNote.strumTime < Conductor.songPosition - PlayState.instance.hitWindow && !daNote.wasGoodHit)
|
||||||
daNote.tooLate = true;
|
daNote.tooLate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PlayState.instance.__updateNote_event.__autoCPUHit && cpu && !daNote.wasGoodHit && daNote.strumTime < Conductor.songPosition) PlayState.instance.goodNoteHit(this, daNote);
|
if (PlayState.instance.__updateNote_event.__autoCPUHit && cpu && !daNote.wasGoodHit && daNote.strumTime < Conductor.songPosition) PlayState.instance.goodNoteHit(this, daNote);
|
||||||
|
|
||||||
if (daNote.wasGoodHit && daNote.isSustainNote && daNote.strumTime + (daNote.sustainLength) < Conductor.songPosition) {
|
if (daNote.wasGoodHit && daNote.isSustainNote && daNote.strumTime + (daNote.sustainLength) < Conductor.songPosition) {
|
||||||
deleteNote(daNote);
|
deleteNote(daNote);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (daNote.tooLate && !cpu) {
|
if (daNote.tooLate && !cpu) {
|
||||||
PlayState.instance.noteMiss(this, daNote);
|
PlayState.instance.noteMiss(this, daNote);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (PlayState.instance.__updateNote_event.strum == null) return;
|
if (PlayState.instance.__updateNote_event.strum == null) return;
|
||||||
|
|
||||||
if (PlayState.instance.__updateNote_event.__reposNote) PlayState.instance.__updateNote_event.strum.updateNotePosition(daNote);
|
if (PlayState.instance.__updateNote_event.__reposNote) PlayState.instance.__updateNote_event.strum.updateNotePosition(daNote);
|
||||||
PlayState.instance.__updateNote_event.strum.updateSustain(daNote);
|
PlayState.instance.__updateNote_event.strum.updateSustain(daNote);
|
||||||
|
|
||||||
PlayState.instance.scripts.event("onNotePostUpdate", PlayState.instance.__updateNote_event);
|
PlayState.instance.scripts.event("onNotePostUpdate", PlayState.instance.__updateNote_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline function addHealth(health:Float)
|
public inline function addHealth(health:Float)
|
||||||
PlayState.instance.health += health * (opponentSide ? -1 : 1);
|
PlayState.instance.health += health * (opponentSide ? -1 : 1);
|
||||||
|
|
||||||
public function generateStrums(amount:Int = 4) {
|
public function generateStrums(amount:Int = 4) {
|
||||||
for (i in 0...4)
|
for (i in 0...4)
|
||||||
{
|
{
|
||||||
var babyArrow:Strum = new Strum((FlxG.width * strumOffset) + (Note.swagWidth * (i - 2)), PlayState.instance.strumLine.y);
|
var babyArrow:Strum = new Strum((FlxG.width * strumOffset) + (Note.swagWidth * (i - 2)), PlayState.instance.strumLine.y);
|
||||||
babyArrow.ID = i;
|
babyArrow.ID = i;
|
||||||
|
|
||||||
var event = PlayState.instance.scripts.event("onStrumCreation", EventManager.get(StrumCreationEvent).recycle(babyArrow, PlayState.instance.strumLines.indexOf(this), i));
|
var event = PlayState.instance.scripts.event("onStrumCreation", EventManager.get(StrumCreationEvent).recycle(babyArrow, PlayState.instance.strumLines.indexOf(this), i));
|
||||||
|
|
||||||
if (!event.cancelled) {
|
if (!event.cancelled) {
|
||||||
babyArrow.frames = Paths.getFrames(event.sprite);
|
babyArrow.frames = Paths.getFrames(event.sprite);
|
||||||
babyArrow.animation.addByPrefix('green', 'arrowUP');
|
babyArrow.animation.addByPrefix('green', 'arrowUP');
|
||||||
babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
|
babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
|
||||||
babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
|
babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
|
||||||
babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
|
babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
|
||||||
|
|
||||||
babyArrow.antialiasing = true;
|
babyArrow.antialiasing = true;
|
||||||
babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
|
babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
|
||||||
|
|
||||||
switch (babyArrow.ID % 4)
|
switch (babyArrow.ID % 4)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
babyArrow.animation.addByPrefix('static', 'arrowLEFT');
|
babyArrow.animation.addByPrefix('static', 'arrowLEFT');
|
||||||
babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
|
babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
|
||||||
babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
|
babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
|
||||||
case 1:
|
case 1:
|
||||||
babyArrow.animation.addByPrefix('static', 'arrowDOWN');
|
babyArrow.animation.addByPrefix('static', 'arrowDOWN');
|
||||||
babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
|
babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
|
||||||
babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
|
babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
|
||||||
case 2:
|
case 2:
|
||||||
babyArrow.animation.addByPrefix('static', 'arrowUP');
|
babyArrow.animation.addByPrefix('static', 'arrowUP');
|
||||||
babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
|
babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
|
||||||
babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
|
babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
|
||||||
case 3:
|
case 3:
|
||||||
babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
|
babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
|
||||||
babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
|
babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
|
||||||
babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
|
babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
babyArrow.cpu = cpu;
|
babyArrow.cpu = cpu;
|
||||||
babyArrow.updateHitbox();
|
babyArrow.updateHitbox();
|
||||||
babyArrow.scrollFactor.set();
|
babyArrow.scrollFactor.set();
|
||||||
|
|
||||||
if (event.__doAnimation)
|
if (event.__doAnimation)
|
||||||
{
|
{
|
||||||
babyArrow.y -= 10;
|
babyArrow.y -= 10;
|
||||||
babyArrow.alpha = 0;
|
babyArrow.alpha = 0;
|
||||||
FlxTween.tween(babyArrow, {y: babyArrow.y + 10, alpha: 1}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * i)});
|
FlxTween.tween(babyArrow, {y: babyArrow.y + 10, alpha: 1}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * i)});
|
||||||
}
|
}
|
||||||
|
|
||||||
add(babyArrow);
|
add(babyArrow);
|
||||||
|
|
||||||
babyArrow.playAnim('static');
|
babyArrow.playAnim('static');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a note from this strumline.
|
* Deletes a note from this strumline.
|
||||||
@@ -224,15 +224,15 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SETTERS & GETTERS
|
* SETTERS & GETTERS
|
||||||
*/
|
*/
|
||||||
#if REGION
|
#if REGION
|
||||||
private inline function set_cpu(b:Bool):Bool {
|
private inline function set_cpu(b:Bool):Bool {
|
||||||
for(s in members)
|
for(s in members)
|
||||||
if (s != null)
|
if (s != null)
|
||||||
s.cpu = b;
|
s.cpu = b;
|
||||||
return cpu = b;
|
return cpu = b;
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
@@ -7,57 +7,57 @@ import haxe.Http;
|
|||||||
|
|
||||||
// TODO: Document further and perhaps make this a Haxelib.
|
// TODO: Document further and perhaps make this a Haxelib.
|
||||||
class GitHub {
|
class GitHub {
|
||||||
/**
|
/**
|
||||||
* Gets all the releases from a specific GitHub repository using the GitHub API.
|
* Gets all the releases from a specific GitHub repository using the GitHub API.
|
||||||
* @param user
|
* @param user
|
||||||
* @param repository
|
* @param repository
|
||||||
* @return Releases
|
* @return Releases
|
||||||
*/
|
*/
|
||||||
public static function getReleases(user:String, repository:String, ?onError:Exception->Void):Array<GitHubRelease> {
|
public static function getReleases(user:String, repository:String, ?onError:Exception->Void):Array<GitHubRelease> {
|
||||||
try {
|
try {
|
||||||
var url = 'https://api.github.com/repos/${user}/${repository}/releases';
|
var url = 'https://api.github.com/repos/${user}/${repository}/releases';
|
||||||
|
|
||||||
var data = Json.parse(__requestOnGitHubServers(url));
|
var data = Json.parse(__requestOnGitHubServers(url));
|
||||||
if (!(data is Array))
|
if (!(data is Array))
|
||||||
throw __parseGitHubException(data);
|
throw __parseGitHubException(data);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (onError != null)
|
if (onError != null)
|
||||||
onError(e);
|
onError(e);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getContributors(user:String, repository:String, ?onError:Exception->Void):Array<GitHubContributor> {
|
public static function getContributors(user:String, repository:String, ?onError:Exception->Void):Array<GitHubContributor> {
|
||||||
try {
|
try {
|
||||||
var url = 'https://api.github.com/repos/${user}/${repository}/contributors';
|
var url = 'https://api.github.com/repos/${user}/${repository}/contributors';
|
||||||
|
|
||||||
var data = Json.parse(__requestOnGitHubServers(url));
|
var data = Json.parse(__requestOnGitHubServers(url));
|
||||||
if (!(data is Array))
|
if (!(data is Array))
|
||||||
throw __parseGitHubException(data);
|
throw __parseGitHubException(data);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (onError != null)
|
if (onError != null)
|
||||||
onError(e);
|
onError(e);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters all releases gotten by `getReleases`
|
* Filters all releases gotten by `getReleases`
|
||||||
* @param releases Releases
|
* @param releases Releases
|
||||||
* @param keepPrereleases Whenever to keep Pre-Releases.
|
* @param keepPrereleases Whenever to keep Pre-Releases.
|
||||||
* @param keepDrafts Whenever to keep Drafts.
|
* @param keepDrafts Whenever to keep Drafts.
|
||||||
* @return Filtered releases.
|
* @return Filtered releases.
|
||||||
*/
|
*/
|
||||||
public static inline function filterReleases(releases:Array<GitHubRelease>, keepPrereleases:Bool = true, keepDrafts:Bool = false)
|
public static inline function filterReleases(releases:Array<GitHubRelease>, keepPrereleases:Bool = true, keepDrafts:Bool = false)
|
||||||
return [for(release in releases) if (release != null && (!release.prerelease || (release.prerelease && keepPrereleases)) && (!release.draft || (release.draft && keepDrafts))) release];
|
return [for(release in releases) if (release != null && (!release.prerelease || (release.prerelease && keepPrereleases)) && (!release.draft || (release.draft && keepDrafts))) release];
|
||||||
|
|
||||||
public static function __requestOnGitHubServers(url:String) {
|
public static function __requestOnGitHubServers(url:String) {
|
||||||
var h = new Http(url);
|
var h = new Http(url);
|
||||||
h.setHeader("User-Agent", "request");
|
h.setHeader("User-Agent", "request");
|
||||||
var r = null;
|
var r = null;
|
||||||
h.onData = function(d) {
|
h.onData = function(d) {
|
||||||
r = d;
|
r = d;
|
||||||
@@ -67,10 +67,10 @@ class GitHub {
|
|||||||
}
|
}
|
||||||
h.request(false);
|
h.request(false);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
public static function __requestBytesOnGitHubServers(url:String) {
|
public static function __requestBytesOnGitHubServers(url:String) {
|
||||||
var h = new Http(url);
|
var h = new Http(url);
|
||||||
h.setHeader("User-Agent", "request");
|
h.setHeader("User-Agent", "request");
|
||||||
var r = null;
|
var r = null;
|
||||||
h.onBytes = function(d) {
|
h.onBytes = function(d) {
|
||||||
r = d;
|
r = d;
|
||||||
@@ -80,16 +80,16 @@ class GitHub {
|
|||||||
}
|
}
|
||||||
h.request(false);
|
h.request(false);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
private static function __parseGitHubException(obj:Dynamic):GitHubException {
|
private static function __parseGitHubException(obj:Dynamic):GitHubException {
|
||||||
var msg:String = "(No message)";
|
var msg:String = "(No message)";
|
||||||
var url:String = "(No API url)";
|
var url:String = "(No API url)";
|
||||||
if (Reflect.hasField(obj, "message"))
|
if (Reflect.hasField(obj, "message"))
|
||||||
msg = Reflect.field(obj, "message");
|
msg = Reflect.field(obj, "message");
|
||||||
if (Reflect.hasField(obj, "documentation_url"))
|
if (Reflect.hasField(obj, "documentation_url"))
|
||||||
url = Reflect.field(obj, "documentation_url");
|
url = Reflect.field(obj, "documentation_url");
|
||||||
return new GitHubException(msg, url);
|
return new GitHubException(msg, url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -97,38 +97,38 @@ import haxe.Json;
|
|||||||
import haxe.Exception;
|
import haxe.Exception;
|
||||||
|
|
||||||
class GitHub {
|
class GitHub {
|
||||||
/**
|
/**
|
||||||
* Gets all the releases from a specific GitHub repository using the GitHub API.
|
* Gets all the releases from a specific GitHub repository using the GitHub API.
|
||||||
* @param user
|
* @param user
|
||||||
* @param repository
|
* @param repository
|
||||||
* @return Releases
|
* @return Releases
|
||||||
*/
|
*/
|
||||||
public static function getReleases(user:String, repository:String, ?onError:Exception->Void):Array<GitHubRelease> {
|
public static function getReleases(user:String, repository:String, ?onError:Exception->Void):Array<GitHubRelease> {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getContributors(user:String, repository:String, ?onError:Exception->Void):Array<GitHubContributor> {
|
public static function getContributors(user:String, repository:String, ?onError:Exception->Void):Array<GitHubContributor> {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters all releases gotten by `getReleases`
|
* Filters all releases gotten by `getReleases`
|
||||||
* @param releases Releases
|
* @param releases Releases
|
||||||
* @param keepPrereleases Whenever to keep Pre-Releases.
|
* @param keepPrereleases Whenever to keep Pre-Releases.
|
||||||
* @param keepDrafts Whenever to keep Drafts.
|
* @param keepDrafts Whenever to keep Drafts.
|
||||||
* @return Filtered releases.
|
* @return Filtered releases.
|
||||||
*/
|
*/
|
||||||
public static inline function filterReleases(releases:Array<GitHubRelease>, keepPrereleases:Bool = true, keepDrafts:Bool = false)
|
public static inline function filterReleases(releases:Array<GitHubRelease>, keepPrereleases:Bool = true, keepDrafts:Bool = false)
|
||||||
return releases;
|
return releases;
|
||||||
|
|
||||||
public static function __requestOnGitHubServers(url:String) {
|
public static function __requestOnGitHubServers(url:String) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public static function __requestBytesOnGitHubServers(url:String) {
|
public static function __requestBytesOnGitHubServers(url:String) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
private static function __parseGitHubException(obj:Dynamic):GitHubException {
|
private static function __parseGitHubException(obj:Dynamic):GitHubException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@@ -3,17 +3,17 @@ package funkin.github;
|
|||||||
import funkin.github.GitHubUser;
|
import funkin.github.GitHubUser;
|
||||||
|
|
||||||
typedef GitHubAsset = {
|
typedef GitHubAsset = {
|
||||||
var url:String;
|
var url:String;
|
||||||
var id:Int;
|
var id:Int;
|
||||||
var node_id:String;
|
var node_id:String;
|
||||||
var name:String;
|
var name:String;
|
||||||
var label:String;
|
var label:String;
|
||||||
var uploader:GitHubUser;
|
var uploader:GitHubUser;
|
||||||
var content_type:String;
|
var content_type:String;
|
||||||
var state:String;
|
var state:String;
|
||||||
var size:UInt;
|
var size:UInt;
|
||||||
var download_count:Int;
|
var download_count:Int;
|
||||||
var created_at:String;
|
var created_at:String;
|
||||||
var updated_at:String;
|
var updated_at:String;
|
||||||
var browser_download_url:String;
|
var browser_download_url:String;
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
package funkin.github;
|
package funkin.github;
|
||||||
|
|
||||||
typedef GitHubContributor = {
|
typedef GitHubContributor = {
|
||||||
var login:String;
|
var login:String;
|
||||||
var id:Int;
|
var id:Int;
|
||||||
var node_id:String;
|
var node_id:String;
|
||||||
var avatar_url:String;
|
var avatar_url:String;
|
||||||
var gravatar_id:String;
|
var gravatar_id:String;
|
||||||
var url:String;
|
var url:String;
|
||||||
var html_url:String;
|
var html_url:String;
|
||||||
var followers_url:String;
|
var followers_url:String;
|
||||||
var following_url:String;
|
var following_url:String;
|
||||||
var gists_url:String;
|
var gists_url:String;
|
||||||
var starred_url:String;
|
var starred_url:String;
|
||||||
var subscriptions_url:String;
|
var subscriptions_url:String;
|
||||||
var organizations_url:String;
|
var organizations_url:String;
|
||||||
var repos_url:String;
|
var repos_url:String;
|
||||||
var events_url:String;
|
var events_url:String;
|
||||||
var received_events_url:String;
|
var received_events_url:String;
|
||||||
var type:String;
|
var type:String;
|
||||||
var site_admin:Bool;
|
var site_admin:Bool;
|
||||||
var contributions:Int;
|
var contributions:Int;
|
||||||
}
|
}
|
||||||
@@ -3,13 +3,13 @@ package funkin.github;
|
|||||||
import haxe.Exception;
|
import haxe.Exception;
|
||||||
|
|
||||||
class GitHubException extends Exception {
|
class GitHubException extends Exception {
|
||||||
public var apiMessage:String;
|
public var apiMessage:String;
|
||||||
|
|
||||||
public var documentationUrl:String;
|
public var documentationUrl:String;
|
||||||
|
|
||||||
public function new(apiMessage:String, documentationUrl:String) {
|
public function new(apiMessage:String, documentationUrl:String) {
|
||||||
super('[GitHubException] ${apiMessage} (Check ${documentationUrl})');
|
super('[GitHubException] ${apiMessage} (Check ${documentationUrl})');
|
||||||
this.apiMessage = apiMessage;
|
this.apiMessage = apiMessage;
|
||||||
this.documentationUrl = documentationUrl;
|
this.documentationUrl = documentationUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package funkin.github;
|
package funkin.github;
|
||||||
|
|
||||||
typedef GitHubReactions = {
|
typedef GitHubReactions = {
|
||||||
var url:String;
|
var url:String;
|
||||||
var total_count:Int;
|
var total_count:Int;
|
||||||
// +1 and -1 cant be added, you need to use Reflect.field
|
// +1 and -1 cant be added, you need to use Reflect.field
|
||||||
var laugh:Int;
|
var laugh:Int;
|
||||||
var hooray:Int;
|
var hooray:Int;
|
||||||
var confused:Int;
|
var confused:Int;
|
||||||
var heart:Int;
|
var heart:Int;
|
||||||
var rocket:Int;
|
var rocket:Int;
|
||||||
var eyes:Int;
|
var eyes:Int;
|
||||||
}
|
}
|
||||||
@@ -1,62 +1,62 @@
|
|||||||
package funkin.github;
|
package funkin.github;
|
||||||
|
|
||||||
typedef GitHubRelease = {
|
typedef GitHubRelease = {
|
||||||
/**
|
/**
|
||||||
* Body of the GitHub request (Markdown)
|
* Body of the GitHub request (Markdown)
|
||||||
*/
|
*/
|
||||||
var body:String;
|
var body:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Url of the release (GitHub API)
|
* Url of the release (GitHub API)
|
||||||
*/
|
*/
|
||||||
var url:String;
|
var url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Url for the assets JSON. Also accessible via `GitHubRelease.assets`
|
* Url for the assets JSON. Also accessible via `GitHubRelease.assets`
|
||||||
*/
|
*/
|
||||||
var assets_url:String;
|
var assets_url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template URL for asset download link.
|
* Template URL for asset download link.
|
||||||
*/
|
*/
|
||||||
var upload_url:String;
|
var upload_url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link to the release on the GitHub website.
|
* Link to the release on the GitHub website.
|
||||||
*/
|
*/
|
||||||
var html_url:String;
|
var html_url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the release.
|
* ID of the release.
|
||||||
*/
|
*/
|
||||||
var id:Int;
|
var id:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Author of the release
|
* Author of the release
|
||||||
*/
|
*/
|
||||||
var author:GitHubUser;
|
var author:GitHubUser;
|
||||||
|
|
||||||
var node_id:String;
|
var node_id:String;
|
||||||
|
|
||||||
var tag_name:String;
|
var tag_name:String;
|
||||||
|
|
||||||
var target_commitish:String;
|
var target_commitish:String;
|
||||||
|
|
||||||
var name:String;
|
var name:String;
|
||||||
|
|
||||||
var draft:Bool;
|
var draft:Bool;
|
||||||
|
|
||||||
var prerelease:Bool;
|
var prerelease:Bool;
|
||||||
|
|
||||||
var created_at:String;
|
var created_at:String;
|
||||||
|
|
||||||
var published_at:String;
|
var published_at:String;
|
||||||
|
|
||||||
var assets:Array<GitHubAsset>;
|
var assets:Array<GitHubAsset>;
|
||||||
|
|
||||||
var tarball_url:String;
|
var tarball_url:String;
|
||||||
|
|
||||||
var zipball_url:String;
|
var zipball_url:String;
|
||||||
|
|
||||||
var reactions:GitHubReactions;
|
var reactions:GitHubReactions;
|
||||||
}
|
}
|
||||||
@@ -2,131 +2,131 @@ package funkin.github;
|
|||||||
|
|
||||||
|
|
||||||
typedef GitHubUser = {
|
typedef GitHubUser = {
|
||||||
/**
|
/**
|
||||||
* Username of the user.
|
* Username of the user.
|
||||||
*/
|
*/
|
||||||
var login:String;
|
var login:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the user.
|
* ID of the user.
|
||||||
*/
|
*/
|
||||||
var id:Int;
|
var id:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the current node on the GitHub database.
|
* ID of the current node on the GitHub database.
|
||||||
*/
|
*/
|
||||||
var node_id:String;
|
var node_id:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link to the avatar (profile picture).
|
* Link to the avatar (profile picture).
|
||||||
*/
|
*/
|
||||||
var avatar_url:String;
|
var avatar_url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unknown
|
* Unknown
|
||||||
*/
|
*/
|
||||||
var gravatar_id:String;
|
var gravatar_id:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL to the user on GitHub's servers.
|
* URL to the user on GitHub's servers.
|
||||||
*/
|
*/
|
||||||
var url:String;
|
var url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL to the user on GitHub's website.
|
* URL to the user on GitHub's website.
|
||||||
*/
|
*/
|
||||||
var html_url:String;
|
var html_url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL on GitHub's API to access this user's followers.
|
* URL on GitHub's API to access this user's followers.
|
||||||
*/
|
*/
|
||||||
var followers_url:String;
|
var followers_url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL on GitHub's API to access the accounts this user is following.
|
* URL on GitHub's API to access the accounts this user is following.
|
||||||
*/
|
*/
|
||||||
var following_url:String;
|
var following_url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL on GitHub's API to access this user's gists.
|
* URL on GitHub's API to access this user's gists.
|
||||||
*/
|
*/
|
||||||
var gists_url:String;
|
var gists_url:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL on GitHub's API to access this user's starred repositories.
|
* URL on GitHub's API to access this user's starred repositories.
|
||||||
*/
|
*/
|
||||||
var starred_url:String;
|
var starred_url:String;
|
||||||
|
|
||||||
// NOT COMPLETE: MISSING repos_url, organizations_url, subscriptions_url, events_url, received_events_url.
|
// NOT COMPLETE: MISSING repos_url, organizations_url, subscriptions_url, events_url, received_events_url.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type of the user.
|
* Type of the user.
|
||||||
*/
|
*/
|
||||||
var type:GitHubUserType;
|
var type:GitHubUserType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever the user is a GitHub administrator.
|
* Whenever the user is a GitHub administrator.
|
||||||
*/
|
*/
|
||||||
var site_admin:Bool;
|
var site_admin:Bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the user.
|
* Name of the user.
|
||||||
*/
|
*/
|
||||||
var name:String;
|
var name:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The company this user belongs to. Can be `null`.
|
* The company this user belongs to. Can be `null`.
|
||||||
*/
|
*/
|
||||||
var company:String;
|
var company:String;
|
||||||
|
|
||||||
var blog:String;
|
var blog:String;
|
||||||
|
|
||||||
var location:String;
|
var location:String;
|
||||||
|
|
||||||
var email:String;
|
var email:String;
|
||||||
|
|
||||||
var hireable:Null<Bool>;
|
var hireable:Null<Bool>;
|
||||||
|
|
||||||
var bio:String;
|
var bio:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Twitter username of the user. Can be null.
|
* Twitter username of the user. Can be null.
|
||||||
*/
|
*/
|
||||||
var twitter_username:String;
|
var twitter_username:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of public repos this user own.
|
* Number of public repos this user own.
|
||||||
*/
|
*/
|
||||||
var public_repos:Int;
|
var public_repos:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of public gists this user own.
|
* Number of public gists this user own.
|
||||||
*/
|
*/
|
||||||
var public_gists:Int;
|
var public_gists:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of followers this user have
|
* Number of followers this user have
|
||||||
*/
|
*/
|
||||||
var followers:Int;
|
var followers:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of accounts this user follows.
|
* Number of accounts this user follows.
|
||||||
*/
|
*/
|
||||||
var following:Int;
|
var following:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date of creation of the account
|
* Date of creation of the account
|
||||||
*/
|
*/
|
||||||
var created_at:String;
|
var created_at:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date of last account update.
|
* Date of last account update.
|
||||||
*/
|
*/
|
||||||
var updated_at:String;
|
var updated_at:String;
|
||||||
}
|
}
|
||||||
|
|
||||||
@:enum
|
@:enum
|
||||||
abstract GitHubUserType(String) {
|
abstract GitHubUserType(String) {
|
||||||
var USER = "User";
|
var USER = "User";
|
||||||
var ORGANIZATION = "Organization";
|
var ORGANIZATION = "Organization";
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package funkin.interfaces;
|
package funkin.interfaces;
|
||||||
|
|
||||||
interface IBeatReceiver {
|
interface IBeatReceiver {
|
||||||
public function measureHit(curMeasure:Int):Void;
|
public function measureHit(curMeasure:Int):Void;
|
||||||
public function beatHit(curBeat:Int):Void;
|
public function beatHit(curBeat:Int):Void;
|
||||||
public function stepHit(curStep:Int):Void;
|
public function stepHit(curStep:Int):Void;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
package funkin.interfaces;
|
package funkin.interfaces;
|
||||||
|
|
||||||
interface IOffsetCompatible {
|
interface IOffsetCompatible {
|
||||||
public function addOffset(anim:String, x:Float = 0, y:Float = 0):Void;
|
public function addOffset(anim:String, x:Float = 0, y:Float = 0):Void;
|
||||||
}
|
}
|
||||||
@@ -6,113 +6,113 @@ package funkin.macros;
|
|||||||
* It adds the `recycle` function, which allows you to "reset" an event's values.
|
* It adds the `recycle` function, which allows you to "reset" an event's values.
|
||||||
*/
|
*/
|
||||||
class EventMacro {
|
class EventMacro {
|
||||||
public static function build():Array<Field> {
|
public static function build():Array<Field> {
|
||||||
var fields = Context.getBuildFields();
|
var fields = Context.getBuildFields();
|
||||||
|
|
||||||
var curClassRest = Context.getLocalClass();
|
var curClassRest = Context.getLocalClass();
|
||||||
if (curClassRest == null) return fields;
|
if (curClassRest == null) return fields;
|
||||||
|
|
||||||
var curClass = curClassRest.get();
|
var curClass = curClassRest.get();
|
||||||
if (curClass == null || curClass.name == "CancellableEvent") return fields;
|
if (curClass == null || curClass.name == "CancellableEvent") return fields;
|
||||||
|
|
||||||
|
|
||||||
// gets all fields
|
// gets all fields
|
||||||
var values:Array<EventVar> = [];
|
var values:Array<EventVar> = [];
|
||||||
var hiddenValues:Array<EventVar> = [];
|
var hiddenValues:Array<EventVar> = [];
|
||||||
for(field in fields) {
|
for(field in fields) {
|
||||||
if (field.access.contains(AStatic)) continue;
|
if (field.access.contains(AStatic)) continue;
|
||||||
|
|
||||||
var hidden = false;
|
var hidden = false;
|
||||||
if (field.meta != null)
|
if (field.meta != null)
|
||||||
for(m in field.meta)
|
for(m in field.meta)
|
||||||
if (m.name == ":dox")
|
if (m.name == ":dox")
|
||||||
hidden = true;
|
hidden = true;
|
||||||
if (!field.access.contains(APublic)) hidden = true;
|
if (!field.access.contains(APublic)) hidden = true;
|
||||||
|
|
||||||
switch(field.kind) {
|
switch(field.kind) {
|
||||||
case FVar(type, expr):
|
case FVar(type, expr):
|
||||||
(hidden ? hiddenValues : values).push({
|
(hidden ? hiddenValues : values).push({
|
||||||
name: field.name,
|
name: field.name,
|
||||||
type: type,
|
type: type,
|
||||||
expr: expr
|
expr: expr
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add recycle option
|
// add recycle option
|
||||||
var func:Function = {
|
var func:Function = {
|
||||||
args: [for(a in values) {
|
args: [for(a in values) {
|
||||||
value: a.expr,
|
value: a.expr,
|
||||||
type: a.type,
|
type: a.type,
|
||||||
opt: false,
|
opt: false,
|
||||||
name: a.name
|
name: a.name
|
||||||
}],
|
}],
|
||||||
expr: {
|
expr: {
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EBlock([])
|
expr: EBlock([])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var funcField:Field = {
|
var funcField:Field = {
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
name: "recycle",
|
name: "recycle",
|
||||||
kind: FFun(func),
|
kind: FFun(func),
|
||||||
access: [APublic]
|
access: [APublic]
|
||||||
};
|
};
|
||||||
|
|
||||||
fields.push(funcField);
|
fields.push(funcField);
|
||||||
|
|
||||||
var p = new Printer();
|
var p = new Printer();
|
||||||
switch(func.expr.expr) {
|
switch(func.expr.expr) {
|
||||||
case EBlock(exprs):
|
case EBlock(exprs):
|
||||||
// add a "set this" expr for each variable
|
// add a "set this" expr for each variable
|
||||||
for(v in values) {
|
for(v in values) {
|
||||||
var name = v.name;
|
var name = v.name;
|
||||||
exprs.push({
|
exprs.push({
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EBinop(OpAssign, {
|
expr: EBinop(OpAssign, {
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EField({
|
expr: EField({
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EConst(CIdent("this"))
|
expr: EConst(CIdent("this"))
|
||||||
}, name)
|
}, name)
|
||||||
}, {
|
}, {
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EConst(CIdent(name))
|
expr: EConst(CIdent(name))
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a "set this" expr to reset each private/hidden variables
|
// add a "set this" expr to reset each private/hidden variables
|
||||||
for(v in hiddenValues) {
|
for(v in hiddenValues) {
|
||||||
var name = v.name;
|
var name = v.name;
|
||||||
exprs.push({
|
exprs.push({
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EBinop(OpAssign, {
|
expr: EBinop(OpAssign, {
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EField({
|
expr: EField({
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EConst(CIdent("this"))
|
expr: EConst(CIdent("this"))
|
||||||
}, name)
|
}, name)
|
||||||
}, v.expr)
|
}, v.expr)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exprs.push(macro return this);
|
exprs.push(macro return this);
|
||||||
exprs.insert(0, macro recycleBase());
|
exprs.insert(0, macro recycleBase());
|
||||||
default:
|
default:
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef EventVar = {
|
typedef EventVar = {
|
||||||
var name:String;
|
var name:String;
|
||||||
var type:ComplexType;
|
var type:ComplexType;
|
||||||
var expr:Expr;
|
var expr:Expr;
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@@ -8,47 +8,47 @@ using StringTools;
|
|||||||
* Macro used in the options class to add getters for the SOLO keybinds.
|
* Macro used in the options class to add getters for the SOLO keybinds.
|
||||||
*/
|
*/
|
||||||
class OptionsMacro {
|
class OptionsMacro {
|
||||||
public static function build():Array<Field> {
|
public static function build():Array<Field> {
|
||||||
var fields = Context.getBuildFields();
|
var fields = Context.getBuildFields();
|
||||||
|
|
||||||
for(f in fields) {
|
for(f in fields) {
|
||||||
switch(f.kind) {
|
switch(f.kind) {
|
||||||
case FProp(get, set, t, e):
|
case FProp(get, set, t, e):
|
||||||
if (f.name.startsWith('SOLO_') && get == "get" && set == "null") {
|
if (f.name.startsWith('SOLO_') && get == "get" && set == "null") {
|
||||||
// Auto-create getters for solo (P1/P2) keybinds
|
// Auto-create getters for solo (P1/P2) keybinds
|
||||||
var name = f.name.substr(5);
|
var name = f.name.substr(5);
|
||||||
var getterName = 'get_SOLO_$name';
|
var getterName = 'get_SOLO_$name';
|
||||||
var ponename = 'P1_$name';
|
var ponename = 'P1_$name';
|
||||||
var ptwoname = 'P2_$name';
|
var ptwoname = 'P2_$name';
|
||||||
var newFuncExpr:Expr = macro {
|
var newFuncExpr:Expr = macro {
|
||||||
var a:Array<FlxKey> = [];
|
var a:Array<FlxKey> = [];
|
||||||
for(e in ${{
|
for(e in ${{
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EConst(CIdent(ponename))
|
expr: EConst(CIdent(ponename))
|
||||||
}}) a.push(e);
|
}}) a.push(e);
|
||||||
for(e in ${{
|
for(e in ${{
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
expr: EConst(CIdent(ptwoname))
|
expr: EConst(CIdent(ptwoname))
|
||||||
}}) a.push(e);
|
}}) a.push(e);
|
||||||
return a;
|
return a;
|
||||||
};
|
};
|
||||||
|
|
||||||
fields.push({
|
fields.push({
|
||||||
name: getterName,
|
name: getterName,
|
||||||
kind: FFun({
|
kind: FFun({
|
||||||
expr: newFuncExpr,
|
expr: newFuncExpr,
|
||||||
args: []
|
args: []
|
||||||
}),
|
}),
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
access: [APrivate, AStatic, AInline]
|
access: [APrivate, AStatic, AInline]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@@ -9,47 +9,47 @@ import haxe.macro.Expr;
|
|||||||
* Macros containing additional help functions to expand HScript capabilities.
|
* Macros containing additional help functions to expand HScript capabilities.
|
||||||
*/
|
*/
|
||||||
class ScriptsMacro {
|
class ScriptsMacro {
|
||||||
public static function addAdditionalClasses() {
|
public static function addAdditionalClasses() {
|
||||||
Compiler.include("flixel");
|
Compiler.include("flixel");
|
||||||
Compiler.include("away3d");
|
Compiler.include("away3d");
|
||||||
Compiler.include("flx3d");
|
Compiler.include("flx3d");
|
||||||
#if (sys && !web)
|
#if (sys && !web)
|
||||||
Compiler.include("sys");
|
Compiler.include("sys");
|
||||||
#end
|
#end
|
||||||
|
|
||||||
Compiler.include("DateTools");
|
Compiler.include("DateTools");
|
||||||
Compiler.include("EReg");
|
Compiler.include("EReg");
|
||||||
Compiler.include("Lambda");
|
Compiler.include("Lambda");
|
||||||
Compiler.include("StringBuf");
|
Compiler.include("StringBuf");
|
||||||
Compiler.include("haxe.crypto");
|
Compiler.include("haxe.crypto");
|
||||||
Compiler.include("haxe.display");
|
Compiler.include("haxe.display");
|
||||||
Compiler.include("haxe.exceptions");
|
Compiler.include("haxe.exceptions");
|
||||||
#if !web
|
#if !web
|
||||||
Compiler.include("haxe.extern");
|
Compiler.include("haxe.extern");
|
||||||
#end
|
#end
|
||||||
|
|
||||||
Compiler.include("scripting");
|
Compiler.include("scripting");
|
||||||
|
|
||||||
// FOR ABSTRACTS
|
// FOR ABSTRACTS
|
||||||
Compiler.addGlobalMetadata('haxe.xml', '@:build(hscript.UsingHandler.build())');
|
Compiler.addGlobalMetadata('haxe.xml', '@:build(hscript.UsingHandler.build())');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function build():Array<Field> {
|
public static function build():Array<Field> {
|
||||||
var fields:Array<Field> = Context.getBuildFields();
|
var fields:Array<Field> = Context.getBuildFields();
|
||||||
|
|
||||||
for(f in fields) {
|
for(f in fields) {
|
||||||
switch(f.kind) {
|
switch(f.kind) {
|
||||||
case FFun(func):
|
case FFun(func):
|
||||||
if (f.access == null) f.access = [];
|
if (f.access == null) f.access = [];
|
||||||
if (f.access.contains(AInline))
|
if (f.access.contains(AInline))
|
||||||
f.access.remove(AInline);
|
f.access.remove(AInline);
|
||||||
f.access.push(ADynamic);
|
f.access.push(ADynamic);
|
||||||
default:
|
default:
|
||||||
// do nothing u piece of shit
|
// do nothing u piece of shit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@@ -14,18 +14,18 @@ import haxe.macro.Compiler;
|
|||||||
* `<haxeflag name="--macro" value="funkin.macros.StdDeprecationsRemover.init()" />`
|
* `<haxeflag name="--macro" value="funkin.macros.StdDeprecationsRemover.init()" />`
|
||||||
*/
|
*/
|
||||||
class StdDeprecationsRemover {
|
class StdDeprecationsRemover {
|
||||||
public static function init() {
|
public static function init() {
|
||||||
Compiler.addGlobalMetadata('Std', '@:build(funkin.macros.StdDeprecationsRemover.build())');
|
Compiler.addGlobalMetadata('Std', '@:build(funkin.macros.StdDeprecationsRemover.build())');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function build():Array<Field> {
|
public static function build():Array<Field> {
|
||||||
var fields:Array<Field> = Context.getBuildFields();
|
var fields:Array<Field> = Context.getBuildFields();
|
||||||
|
|
||||||
for(f in fields)
|
for(f in fields)
|
||||||
if (f.name == "is")
|
if (f.name == "is")
|
||||||
f.meta = [for(e in f.meta) if (e.name != ":deprecated") e];
|
f.meta = [for(e in f.meta) if (e.name != ":deprecated") e];
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@@ -6,48 +6,48 @@ import flixel.text.FlxText;
|
|||||||
import funkin.ui.FunkinText;
|
import funkin.ui.FunkinText;
|
||||||
|
|
||||||
class BetaWarningState extends MusicBeatState {
|
class BetaWarningState extends MusicBeatState {
|
||||||
var titleAlphabet:Alphabet;
|
var titleAlphabet:Alphabet;
|
||||||
var disclaimer:FunkinText;
|
var disclaimer:FunkinText;
|
||||||
|
|
||||||
var transitioning:Bool = false;
|
var transitioning:Bool = false;
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
titleAlphabet = new Alphabet(0, 0, "WARNING", true);
|
titleAlphabet = new Alphabet(0, 0, "WARNING", true);
|
||||||
titleAlphabet.screenCenter(X);
|
titleAlphabet.screenCenter(X);
|
||||||
add(titleAlphabet);
|
add(titleAlphabet);
|
||||||
|
|
||||||
disclaimer = new FunkinText(16, titleAlphabet.y + titleAlphabet.height + 10, FlxG.width - 32, "", 32);
|
disclaimer = new FunkinText(16, titleAlphabet.y + titleAlphabet.height + 10, FlxG.width - 32, "", 32);
|
||||||
disclaimer.alignment = CENTER;
|
disclaimer.alignment = CENTER;
|
||||||
disclaimer.applyMarkup("This engine is still in a beta state. That means *majority of the features* are either *buggy* or *non finished*. If you find any bug, please report them to the Codename Engine GitHub.\n\nPress ENTER to continue",
|
disclaimer.applyMarkup("This engine is still in a beta state. That means *majority of the features* are either *buggy* or *non finished*. If you find any bug, please report them to the Codename Engine GitHub.\n\nPress ENTER to continue",
|
||||||
[
|
[
|
||||||
new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFFF4444), "*")
|
new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFFF4444), "*")
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
add(disclaimer);
|
add(disclaimer);
|
||||||
|
|
||||||
var off = Std.int((FlxG.height - (disclaimer.y + disclaimer.height)) / 2);
|
var off = Std.int((FlxG.height - (disclaimer.y + disclaimer.height)) / 2);
|
||||||
disclaimer.y += off;
|
disclaimer.y += off;
|
||||||
titleAlphabet.y += off;
|
titleAlphabet.y += off;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
if (controls.ACCEPT && transitioning) {
|
if (controls.ACCEPT && transitioning) {
|
||||||
FlxG.camera.stopFX(); FlxG.camera.visible = false;
|
FlxG.camera.stopFX(); FlxG.camera.visible = false;
|
||||||
goToTitle();
|
goToTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controls.ACCEPT && !transitioning) {
|
if (controls.ACCEPT && !transitioning) {
|
||||||
transitioning = true;
|
transitioning = true;
|
||||||
CoolUtil.playMenuSFX(CONFIRM);
|
CoolUtil.playMenuSFX(CONFIRM);
|
||||||
FlxG.camera.flash(FlxColor.WHITE, 1, function() {
|
FlxG.camera.flash(FlxColor.WHITE, 1, function() {
|
||||||
FlxG.camera.fade(FlxColor.BLACK, 2.5, false, goToTitle);
|
FlxG.camera.fade(FlxColor.BLACK, 2.5, false, goToTitle);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function goToTitle() {
|
private function goToTitle() {
|
||||||
FlxTransitionableState.skipNextTransIn = FlxTransitionableState.skipNextTransOut = true;
|
FlxTransitionableState.skipNextTransIn = FlxTransitionableState.skipNextTransOut = true;
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ class FreeplayState extends MusicBeatState
|
|||||||
if (event.cancelled) return;
|
if (event.cancelled) return;
|
||||||
|
|
||||||
curSelected = event.value;
|
curSelected = event.value;
|
||||||
if (event.playMenuSFX) CoolUtil.playMenuSFX(SCROLL, 0.7);
|
if (event.playMenuSFX) CoolUtil.playMenuSFX(SCROLL, 0.7);
|
||||||
|
|
||||||
changeDiff(0, true);
|
changeDiff(0, true);
|
||||||
|
|
||||||
@@ -382,9 +382,9 @@ class FreeplayState extends MusicBeatState
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FreeplaySonglist {
|
class FreeplaySonglist {
|
||||||
public var songs:Array<ChartMetaData> = [];
|
public var songs:Array<ChartMetaData> = [];
|
||||||
|
|
||||||
public function new() {}
|
public function new() {}
|
||||||
|
|
||||||
public function getSongsFromSource(source:funkin.system.AssetsLibraryList.AssetSource, useTxt:Bool = true) {
|
public function getSongsFromSource(source:funkin.system.AssetsLibraryList.AssetSource, useTxt:Bool = true) {
|
||||||
var path:String = Paths.txt('freeplaySonglist');
|
var path:String = Paths.txt('freeplaySonglist');
|
||||||
@@ -403,12 +403,12 @@ class FreeplaySonglist {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get(useTxt:Bool = true) {
|
public static function get(useTxt:Bool = true) {
|
||||||
var songList = new FreeplaySonglist();
|
var songList = new FreeplaySonglist();
|
||||||
|
|
||||||
if (songList.getSongsFromSource(MODS, useTxt))
|
if (songList.getSongsFromSource(MODS, useTxt))
|
||||||
songList.getSongsFromSource(SOURCE, useTxt);
|
songList.getSongsFromSource(SOURCE, useTxt);
|
||||||
|
|
||||||
return songList;
|
return songList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,72 +7,72 @@ import sys.FileSystem;
|
|||||||
import flixel.tweens.FlxTween;
|
import flixel.tweens.FlxTween;
|
||||||
|
|
||||||
class ModSwitchMenu extends MusicBeatSubstate {
|
class ModSwitchMenu extends MusicBeatSubstate {
|
||||||
var mods:Array<String> = [];
|
var mods:Array<String> = [];
|
||||||
var alphabets:FlxTypedGroup<Alphabet>;
|
var alphabets:FlxTypedGroup<Alphabet>;
|
||||||
var curSelected:Int = 0;
|
var curSelected:Int = 0;
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
var bg = new FlxSprite(0, 0).makeGraphic(1, 1, 0xFF000000);
|
var bg = new FlxSprite(0, 0).makeGraphic(1, 1, 0xFF000000);
|
||||||
bg.scale.set(FlxG.width, FlxG.height);
|
bg.scale.set(FlxG.width, FlxG.height);
|
||||||
bg.updateHitbox();
|
bg.updateHitbox();
|
||||||
bg.scrollFactor.set();
|
bg.scrollFactor.set();
|
||||||
add(bg);
|
add(bg);
|
||||||
|
|
||||||
bg.alpha = 0;
|
bg.alpha = 0;
|
||||||
FlxTween.tween(bg, {alpha: 0.5}, 0.25, {ease: FlxEase.cubeOut});
|
FlxTween.tween(bg, {alpha: 0.5}, 0.25, {ease: FlxEase.cubeOut});
|
||||||
|
|
||||||
for(modFolder in FileSystem.readDirectory(ModsFolder.modsPath)) {
|
for(modFolder in FileSystem.readDirectory(ModsFolder.modsPath)) {
|
||||||
if (FileSystem.isDirectory('${ModsFolder.modsPath}${modFolder}')) {
|
if (FileSystem.isDirectory('${ModsFolder.modsPath}${modFolder}')) {
|
||||||
mods.push(modFolder);
|
mods.push(modFolder);
|
||||||
} else {
|
} else {
|
||||||
var ext = Path.extension(modFolder).toLowerCase();
|
var ext = Path.extension(modFolder).toLowerCase();
|
||||||
switch(ext) {
|
switch(ext) {
|
||||||
case 'zip':
|
case 'zip':
|
||||||
// is a zip mod!!
|
// is a zip mod!!
|
||||||
mods.push(Path.withoutExtension(modFolder));
|
mods.push(Path.withoutExtension(modFolder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
alphabets = new FlxTypedGroup<Alphabet>();
|
alphabets = new FlxTypedGroup<Alphabet>();
|
||||||
for(mod in mods) {
|
for(mod in mods) {
|
||||||
var a = new Alphabet(0, 0, mod, true);
|
var a = new Alphabet(0, 0, mod, true);
|
||||||
a.isMenuItem = true;
|
a.isMenuItem = true;
|
||||||
a.scrollFactor.set();
|
a.scrollFactor.set();
|
||||||
alphabets.add(a);
|
alphabets.add(a);
|
||||||
}
|
}
|
||||||
add(alphabets);
|
add(alphabets);
|
||||||
changeSelection(0, true);
|
changeSelection(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
changeSelection((controls.DOWN_P ? 1 : 0) + (controls.UP_P ? -1 : 0));
|
changeSelection((controls.DOWN_P ? 1 : 0) + (controls.UP_P ? -1 : 0));
|
||||||
|
|
||||||
if (controls.ACCEPT) {
|
if (controls.ACCEPT) {
|
||||||
ModsFolder.switchMod(mods[curSelected]);
|
ModsFolder.switchMod(mods[curSelected]);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controls.BACK)
|
if (controls.BACK)
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changeSelection(change:Int, force:Bool = false) {
|
public function changeSelection(change:Int, force:Bool = false) {
|
||||||
if (change == 0 && !force) return;
|
if (change == 0 && !force) return;
|
||||||
|
|
||||||
curSelected = FlxMath.wrap(curSelected + change, 0, alphabets.length-1);
|
curSelected = FlxMath.wrap(curSelected + change, 0, alphabets.length-1);
|
||||||
|
|
||||||
CoolUtil.playMenuSFX(SCROLL, 0.7);
|
CoolUtil.playMenuSFX(SCROLL, 0.7);
|
||||||
|
|
||||||
for(k=>alphabet in alphabets.members) {
|
for(k=>alphabet in alphabets.members) {
|
||||||
alphabet.alpha = 0.6;
|
alphabet.alpha = 0.6;
|
||||||
alphabet.targetY = k - curSelected;
|
alphabet.targetY = k - curSelected;
|
||||||
}
|
}
|
||||||
alphabets.members[curSelected].alpha = 1;
|
alphabets.members[curSelected].alpha = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@@ -41,7 +41,7 @@ class PauseSubState extends MusicBeatSubstate
|
|||||||
|
|
||||||
pauseScript = Script.create(Paths.script(script));
|
pauseScript = Script.create(Paths.script(script));
|
||||||
pauseScript.setParent(this);
|
pauseScript.setParent(this);
|
||||||
pauseScript.load();
|
pauseScript.load();
|
||||||
|
|
||||||
var event = EventManager.get(PauseCreationEvent).recycle('breakfast', menuItems);
|
var event = EventManager.get(PauseCreationEvent).recycle('breakfast', menuItems);
|
||||||
pauseScript.call('create', [event]);
|
pauseScript.call('create', [event]);
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ class TitleState extends MusicBeatState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Failed to load titlescreen XML: $e', ERROR);
|
Logs.trace('Failed to load titlescreen XML: $e', ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|||||||
@@ -15,120 +15,120 @@ import funkin.menus.MainMenuState;
|
|||||||
using funkin.utils.BitmapUtil;
|
using funkin.utils.BitmapUtil;
|
||||||
|
|
||||||
class CreditsCodename extends OptionsScreen {
|
class CreditsCodename extends OptionsScreen {
|
||||||
public var contributorsSprites:Array<FlxSprite> = [];
|
public var contributorsSprites:Array<FlxSprite> = [];
|
||||||
public var contributorsAvatars:Array<FlxGraphic> = [];
|
public var contributorsAvatars:Array<FlxGraphic> = [];
|
||||||
public var contributorsColors:Array<FlxColor> = [];
|
public var contributorsColors:Array<FlxColor> = [];
|
||||||
public var avatarLoadListId:Int = 0;
|
public var avatarLoadListId:Int = 0;
|
||||||
public var contributors:Array<GitHubContributor>;
|
public var contributors:Array<GitHubContributor>;
|
||||||
|
|
||||||
public var interpColor:FlxInterpolateColor;
|
public var interpColor:FlxInterpolateColor;
|
||||||
|
|
||||||
public var errorMessage:String = "";
|
public var errorMessage:String = "";
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
contributors = GitHub.getContributors("YoshiCrafter29", "CodenameEngine", function(e) {
|
contributors = GitHub.getContributors("YoshiCrafter29", "CodenameEngine", function(e) {
|
||||||
errorMessage = Std.string(e);
|
errorMessage = Std.string(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var totalContributions = 0;
|
var totalContributions = 0;
|
||||||
|
|
||||||
for(c in contributors)
|
for(c in contributors)
|
||||||
totalContributions += c.contributions;
|
totalContributions += c.contributions;
|
||||||
|
|
||||||
options = [for(c in contributors) new TextOption(
|
options = [for(c in contributors) new TextOption(
|
||||||
c.login,
|
c.login,
|
||||||
'Total Contributions: ${c.contributions} / ${totalContributions} (${FlxMath.roundDecimal(c.contributions / totalContributions * 100, 2)}%) - Select to open GitHub account',
|
'Total Contributions: ${c.contributions} / ${totalContributions} (${FlxMath.roundDecimal(c.contributions / totalContributions * 100, 2)}%) - Select to open GitHub account',
|
||||||
function() {
|
function() {
|
||||||
// open the link
|
// open the link
|
||||||
CoolUtil.openURL(c.html_url);
|
CoolUtil.openURL(c.html_url);
|
||||||
})];
|
})];
|
||||||
|
|
||||||
|
|
||||||
super.create();
|
super.create();
|
||||||
interpColor = new FlxInterpolateColor(bg.color);
|
interpColor = new FlxInterpolateColor(bg.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function changeSelection(change:Int) {
|
public override function changeSelection(change:Int) {
|
||||||
if (contributors.length <= 0)
|
if (contributors.length <= 0)
|
||||||
return;
|
return;
|
||||||
super.changeSelection(change);
|
super.changeSelection(change);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function createAdditional() {
|
public override function createAdditional() {
|
||||||
if (contributors.length <= 0) {
|
if (contributors.length <= 0) {
|
||||||
var t = new FunkinText(0, 0, FlxG.width, 'Could not load engine contributors.\nMake sure you\'re connected to the Internet.\n\n${errorMessage}\n\nPress BACK to go back.', 40, true);
|
var t = new FunkinText(0, 0, FlxG.width, 'Could not load engine contributors.\nMake sure you\'re connected to the Internet.\n\n${errorMessage}\n\nPress BACK to go back.', 40, true);
|
||||||
t.alignment = CENTER;
|
t.alignment = CENTER;
|
||||||
t.borderSize *= 1.75;
|
t.borderSize *= 1.75;
|
||||||
t.screenCenter();
|
t.screenCenter();
|
||||||
|
|
||||||
var bg = new FlxSprite(0, 0).makeGraphic(1, 1, 0xFF000000);
|
var bg = new FlxSprite(0, 0).makeGraphic(1, 1, 0xFF000000);
|
||||||
bg.alpha = 0.5;
|
bg.alpha = 0.5;
|
||||||
bg.scale.set(FlxG.width - 80, t.height + 40);
|
bg.scale.set(FlxG.width - 80, t.height + 40);
|
||||||
bg.updateHitbox();
|
bg.updateHitbox();
|
||||||
bg.screenCenter();
|
bg.screenCenter();
|
||||||
add(bg);
|
add(bg);
|
||||||
add(t);
|
add(t);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(k=>c in contributors) {
|
for(k=>c in contributors) {
|
||||||
var spr = new FlxSprite(0, (OptionsScreen.optionHeight * (k+0.5)) - 48);
|
var spr = new FlxSprite(0, (OptionsScreen.optionHeight * (k+0.5)) - 48);
|
||||||
spr.antialiasing = true;
|
spr.antialiasing = true;
|
||||||
spr.setUnstretchedGraphicSize(96, 96, false);
|
spr.setUnstretchedGraphicSize(96, 96, false);
|
||||||
spr.updateHitbox();
|
spr.updateHitbox();
|
||||||
spr.shader = new CustomShader('engine/circleProfilePicture');
|
spr.shader = new CustomShader('engine/circleProfilePicture');
|
||||||
contributorsSprites.push(spr);
|
contributorsSprites.push(spr);
|
||||||
add(spr);
|
add(spr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// asynchronous pfp loading
|
// asynchronous pfp loading
|
||||||
Main.execAsync(function() {
|
Main.execAsync(function() {
|
||||||
for(k=>c in contributors) {
|
for(k=>c in contributors) {
|
||||||
var bytes = GitHub.__requestBytesOnGitHubServers('${c.avatar_url}&size=96');
|
var bytes = GitHub.__requestBytesOnGitHubServers('${c.avatar_url}&size=96');
|
||||||
var bmap = BitmapData.fromBytes(bytes);
|
var bmap = BitmapData.fromBytes(bytes);
|
||||||
var color = bmap.getMostPresentSaturatedColor();
|
var color = bmap.getMostPresentSaturatedColor();
|
||||||
contributorsAvatars.push(FlxG.bitmap.add(bmap, false, 'GITHUB-USER:${c.login}'));
|
contributorsAvatars.push(FlxG.bitmap.add(bmap, false, 'GITHUB-USER:${c.login}'));
|
||||||
contributorsColors.push(color);
|
contributorsColors.push(color);
|
||||||
if (destroyed) return;
|
if (destroyed) return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
if (contributors.length <= 0) {
|
if (contributors.length <= 0) {
|
||||||
if (controls.BACK)
|
if (controls.BACK)
|
||||||
exit();
|
exit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avatarLoadListId < contributorsAvatars.length) {
|
if (avatarLoadListId < contributorsAvatars.length) {
|
||||||
for(i in avatarLoadListId...contributorsAvatars.length) {
|
for(i in avatarLoadListId...contributorsAvatars.length) {
|
||||||
var v = contributorsSprites[i];
|
var v = contributorsSprites[i];
|
||||||
v.loadGraphic(contributorsAvatars[i]);
|
v.loadGraphic(contributorsAvatars[i]);
|
||||||
v.setUnstretchedGraphicSize(96, 96, false);
|
v.setUnstretchedGraphicSize(96, 96, false);
|
||||||
v.updateHitbox();
|
v.updateHitbox();
|
||||||
}
|
}
|
||||||
avatarLoadListId = contributorsAvatars.length;
|
avatarLoadListId = contributorsAvatars.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(k=>spr in contributorsSprites) {
|
for(k=>spr in contributorsSprites) {
|
||||||
var alpha = options[k];
|
var alpha = options[k];
|
||||||
spr.x = alpha.x - 10;
|
spr.x = alpha.x - 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
interpColor.fpsLerpTo(contributorsColors[curSelected], 0.0625);
|
interpColor.fpsLerpTo(contributorsColors[curSelected], 0.0625);
|
||||||
bg.color = interpColor.color;
|
bg.color = interpColor.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function exit() {
|
public override function exit() {
|
||||||
FlxTransitionableState.skipNextTransOut = true;
|
FlxTransitionableState.skipNextTransOut = true;
|
||||||
FlxG.switchState(new CreditsMain());
|
FlxG.switchState(new CreditsMain());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,21 +5,21 @@ import funkin.options.OptionsScreen;
|
|||||||
import funkin.options.type.*;
|
import funkin.options.type.*;
|
||||||
|
|
||||||
class CreditsMain extends OptionsScreen {
|
class CreditsMain extends OptionsScreen {
|
||||||
public override function create() {
|
public override function create() {
|
||||||
options = [
|
options = [
|
||||||
// TODO: Custom Credits
|
// TODO: Custom Credits
|
||||||
new TextOption("Codename Engine", "Select this to see all of the contributors of the engine!", function() {
|
new TextOption("Codename Engine", "Select this to see all of the contributors of the engine!", function() {
|
||||||
FlxTransitionableState.skipNextTransIn = FlxTransitionableState.skipNextTransOut = true;
|
FlxTransitionableState.skipNextTransIn = FlxTransitionableState.skipNextTransOut = true;
|
||||||
FlxG.switchState(new CreditsCodename());
|
FlxG.switchState(new CreditsCodename());
|
||||||
}),
|
}),
|
||||||
new TextOption("Friday Night Funkin'", "Select this to open the itch.io page of the original game to donate!", function() {
|
new TextOption("Friday Night Funkin'", "Select this to open the itch.io page of the original game to donate!", function() {
|
||||||
CoolUtil.openURL("https://ninja-muffin24.itch.io/funkin");
|
CoolUtil.openURL("https://ninja-muffin24.itch.io/funkin");
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
super.create();
|
super.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function exit() {
|
public override function exit() {
|
||||||
FlxG.switchState(new MainMenuState());
|
FlxG.switchState(new MainMenuState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,34 +6,34 @@ import lime.utils.AssetLibrary;
|
|||||||
* Used to prevent crashes
|
* Used to prevent crashes
|
||||||
*/
|
*/
|
||||||
class ModdableAssetsFolder extends ModsFolderLibrary {
|
class ModdableAssetsFolder extends ModsFolderLibrary {
|
||||||
public var oldLibrary:AssetLibrary;
|
public var oldLibrary:AssetLibrary;
|
||||||
|
|
||||||
public override function exists(id:String, type:String) {
|
public override function exists(id:String, type:String) {
|
||||||
if (!id.startsWith("assets/") && !exists('assets/$id', type))
|
if (!id.startsWith("assets/") && !exists('assets/$id', type))
|
||||||
return oldLibrary.exists(id, type);
|
return oldLibrary.exists(id, type);
|
||||||
return super.exists(id, type);
|
return super.exists(id, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getAsset(id:String, type:String) {
|
public override function getAsset(id:String, type:String) {
|
||||||
if (!id.startsWith("assets/")) {
|
if (!id.startsWith("assets/")) {
|
||||||
var possibleReplacement = getAsset('assets/$id', type);
|
var possibleReplacement = getAsset('assets/$id', type);
|
||||||
if (possibleReplacement != null)
|
if (possibleReplacement != null)
|
||||||
return possibleReplacement;
|
return possibleReplacement;
|
||||||
return oldLibrary.getAsset(id, type);
|
return oldLibrary.getAsset(id, type);
|
||||||
}
|
}
|
||||||
return super.getAsset(id, type);
|
return super.getAsset(id, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function new(folder:String, libName:String, oldLib:AssetLibrary) {
|
public function new(folder:String, libName:String, oldLib:AssetLibrary) {
|
||||||
super(folder, libName);
|
super(folder, libName);
|
||||||
oldLibrary = oldLib;
|
oldLibrary = oldLib;
|
||||||
trace(Type.getClassName(Type.getClass(oldLibrary)));
|
trace(Type.getClassName(Type.getClass(oldLibrary)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private override function __parseAsset(asset:String):Bool {
|
private override function __parseAsset(asset:String):Bool {
|
||||||
var prefix = 'assets/';
|
var prefix = 'assets/';
|
||||||
if (!asset.startsWith(prefix)) return false;
|
if (!asset.startsWith(prefix)) return false;
|
||||||
_parsedAsset = asset.substr(prefix.length);
|
_parsedAsset = asset.substr(prefix.length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,20 +22,20 @@ import sys.FileSystem;
|
|||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
interface ModsAssetLibrary {
|
interface ModsAssetLibrary {
|
||||||
public var prefix:String;
|
public var prefix:String;
|
||||||
public var libName:String;
|
public var libName:String;
|
||||||
|
|
||||||
#if MOD_SUPPORT
|
#if MOD_SUPPORT
|
||||||
public var _parsedAsset:String;
|
public var _parsedAsset:String;
|
||||||
|
|
||||||
private function getAssetPath():String;
|
private function getAssetPath():String;
|
||||||
|
|
||||||
private function __isCacheValid(cache:Map<String, Dynamic>, asset:String, isLocal:Bool = false):Bool;
|
private function __isCacheValid(cache:Map<String, Dynamic>, asset:String, isLocal:Bool = false):Bool;
|
||||||
|
|
||||||
private function __parseAsset(asset:String):Bool;
|
private function __parseAsset(asset:String):Bool;
|
||||||
|
|
||||||
public function getFiles(folder:String):Array<String>;
|
public function getFiles(folder:String):Array<String>;
|
||||||
|
|
||||||
public function getFolders(folder:String):Array<String>;
|
public function getFolders(folder:String):Array<String>;
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
@@ -19,115 +19,115 @@ import haxe.io.Path;
|
|||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
class ModsFolder {
|
class ModsFolder {
|
||||||
/**
|
/**
|
||||||
* INTERNAL - Only use when editing source mods!!
|
* INTERNAL - Only use when editing source mods!!
|
||||||
*/
|
*/
|
||||||
@:dox(hide) public static var onModSwitch:FlxTypedSignal<String->Void> = new FlxTypedSignal<String->Void>();
|
@:dox(hide) public static var onModSwitch:FlxTypedSignal<String->Void> = new FlxTypedSignal<String->Void>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current mod folder. Will affect `Paths`.
|
* Current mod folder. Will affect `Paths`.
|
||||||
*/
|
*/
|
||||||
public static var currentModFolder:String = null;
|
public static var currentModFolder:String = null;
|
||||||
/**
|
/**
|
||||||
* Map all loaded mods' folder libraries.
|
* Map all loaded mods' folder libraries.
|
||||||
*/
|
*/
|
||||||
public static var loadedMods:Map<String, lime.utils.AssetLibrary> = [];
|
public static var loadedMods:Map<String, lime.utils.AssetLibrary> = [];
|
||||||
/**
|
/**
|
||||||
* Path to the `mods` folder.
|
* Path to the `mods` folder.
|
||||||
*/
|
*/
|
||||||
public static var modsPath:String = "./mods/";
|
public static var modsPath:String = "./mods/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises `mods` folder by adding callbacks and such.
|
* Initialises `mods` folder by adding callbacks and such.
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
public static function init() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a mod with the specified name.
|
* Loads a mod with the specified name.
|
||||||
* @param modName Name of the mod
|
* @param modName Name of the mod
|
||||||
* @param force Whenever the mod should be reloaded if it has already been loaded
|
* @param force Whenever the mod should be reloaded if it has already been loaded
|
||||||
*/
|
*/
|
||||||
public static function loadMod(mod:String, force:Bool = false) {
|
public static function loadMod(mod:String, force:Bool = false) {
|
||||||
#if MOD_SUPPORT
|
#if MOD_SUPPORT
|
||||||
if (mod == null) return null; // may be loading base game
|
if (mod == null) return null; // may be loading base game
|
||||||
|
|
||||||
if (FileSystem.exists('${modsPath}$mod.zip'))
|
if (FileSystem.exists('${modsPath}$mod.zip'))
|
||||||
return loadedMods[mod] = loadLibraryFromZip('mods/$mod'.toLowerCase(), '${modsPath}$mod.zip', force);
|
return loadedMods[mod] = loadLibraryFromZip('mods/$mod'.toLowerCase(), '${modsPath}$mod.zip', force);
|
||||||
else
|
else
|
||||||
return loadedMods[mod] = loadLibraryFromFolder('mods/$mod'.toLowerCase(), '${modsPath}$mod', force);
|
return loadedMods[mod] = loadLibraryFromFolder('mods/$mod'.toLowerCase(), '${modsPath}$mod', force);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
return null;
|
return null;
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switches mod - unloads all the other mods, then load this one.
|
* Switches mod - unloads all the other mods, then load this one.
|
||||||
* @param libName
|
* @param libName
|
||||||
*/
|
*/
|
||||||
public static function switchMod(mod:String) {
|
public static function switchMod(mod:String) {
|
||||||
unloadMod(ModsFolder.currentModFolder);
|
unloadMod(ModsFolder.currentModFolder);
|
||||||
Options.lastLoadedMod = ModsFolder.currentModFolder = mod;
|
Options.lastLoadedMod = ModsFolder.currentModFolder = mod;
|
||||||
Options.save();
|
Options.save();
|
||||||
if (ModsFolder.currentModFolder == null) return;
|
if (ModsFolder.currentModFolder == null) return;
|
||||||
|
|
||||||
Paths.assetsTree.addLibrary(loadMod(ModsFolder.currentModFolder));
|
Paths.assetsTree.addLibrary(loadMod(ModsFolder.currentModFolder));
|
||||||
|
|
||||||
Main.refreshAssets();
|
Main.refreshAssets();
|
||||||
onModSwitch.dispatch(ModsFolder.currentModFolder);
|
onModSwitch.dispatch(ModsFolder.currentModFolder);
|
||||||
if (FlxG.sound.music != null && FlxG.sound.music.playing)
|
if (FlxG.sound.music != null && FlxG.sound.music.playing)
|
||||||
FlxG.sound.music.fadeOut(0.25, 0, function(t) {
|
FlxG.sound.music.fadeOut(0.25, 0, function(t) {
|
||||||
FlxG.sound.music.stop();
|
FlxG.sound.music.stop();
|
||||||
});
|
});
|
||||||
DiscordUtil.reloadJsonData();
|
DiscordUtil.reloadJsonData();
|
||||||
TitleState.initialized = false;
|
TitleState.initialized = false;
|
||||||
FlxG.switchState(new TitleState());
|
FlxG.switchState(new TitleState());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function unloadMod(mod:String) {
|
public static function unloadMod(mod:String) {
|
||||||
if (mod == null) return;
|
if (mod == null) return;
|
||||||
|
|
||||||
Paths.assetsTree.clearCache();
|
Paths.assetsTree.clearCache();
|
||||||
FlxG.bitmap.reset();
|
FlxG.bitmap.reset();
|
||||||
Paths.assetsTree.removeLibrary(loadedMods[mod]);
|
Paths.assetsTree.removeLibrary(loadedMods[mod]);
|
||||||
Assets.unloadLibrary('mods/$mod'.toLowerCase());
|
Assets.unloadLibrary('mods/$mod'.toLowerCase());
|
||||||
|
|
||||||
loadedMods[mod] = null;
|
loadedMods[mod] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function prepareLibrary(libName:String, force:Bool = false) {
|
public static function prepareLibrary(libName:String, force:Bool = false) {
|
||||||
if (Assets.hasLibrary(libName)) {
|
if (Assets.hasLibrary(libName)) {
|
||||||
if (force)
|
if (force)
|
||||||
Assets.unloadLibrary(libName);
|
Assets.unloadLibrary(libName);
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var assets:AssetManifest = new AssetManifest();
|
var assets:AssetManifest = new AssetManifest();
|
||||||
assets.name = libName;
|
assets.name = libName;
|
||||||
assets.version = 2;
|
assets.version = 2;
|
||||||
assets.libraryArgs = [];
|
assets.libraryArgs = [];
|
||||||
assets.assets = [];
|
assets.assets = [];
|
||||||
|
|
||||||
return AssetLibrary.fromManifest(assets);
|
return AssetLibrary.fromManifest(assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function prepareModLibrary(libName:String, lib:ModsAssetLibrary, force:Bool = false) {
|
public static function prepareModLibrary(libName:String, lib:ModsAssetLibrary, force:Bool = false) {
|
||||||
var openLib = prepareLibrary(libName, force);
|
var openLib = prepareLibrary(libName, force);
|
||||||
lib.prefix = 'assets/';
|
lib.prefix = 'assets/';
|
||||||
@:privateAccess
|
@:privateAccess
|
||||||
openLib.__proxy = cast(lib, lime.utils.AssetLibrary);
|
openLib.__proxy = cast(lib, lime.utils.AssetLibrary);
|
||||||
Assets.registerLibrary(libName, openLib);
|
Assets.registerLibrary(libName, openLib);
|
||||||
return openLib;
|
return openLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function loadLibraryFromFolder(libName:String, folder:String, force:Bool = false) {
|
public static function loadLibraryFromFolder(libName:String, folder:String, force:Bool = false) {
|
||||||
return prepareModLibrary(libName, new ModsFolderLibrary(folder, libName), force);
|
return prepareModLibrary(libName, new ModsFolderLibrary(folder, libName), force);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function loadLibraryFromZip(libName:String, zipPath:String, force:Bool = false) {
|
public static function loadLibraryFromZip(libName:String, zipPath:String, force:Bool = false) {
|
||||||
return prepareModLibrary(libName, new ZipFolderLibrary(zipPath, libName), force);
|
return prepareModLibrary(libName, new ZipFolderLibrary(zipPath, libName), force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,27 +16,27 @@ import sys.FileSystem;
|
|||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||||
public var folderPath:String;
|
public var folderPath:String;
|
||||||
public var libName:String;
|
public var libName:String;
|
||||||
public var useImageCache:Bool = true;
|
public var useImageCache:Bool = true;
|
||||||
public var prefix = 'assets/';
|
public var prefix = 'assets/';
|
||||||
|
|
||||||
public function new(folderPath:String, libName:String) {
|
public function new(folderPath:String, libName:String) {
|
||||||
this.folderPath = folderPath;
|
this.folderPath = folderPath;
|
||||||
this.libName = libName;
|
this.libName = libName;
|
||||||
this.prefix = 'assets/$libName/';
|
this.prefix = 'assets/$libName/';
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MOD_SUPPORT
|
#if MOD_SUPPORT
|
||||||
private var editedTimes:Map<String, Float> = [];
|
private var editedTimes:Map<String, Float> = [];
|
||||||
public var _parsedAsset:String = null;
|
public var _parsedAsset:String = null;
|
||||||
|
|
||||||
public function getEditedTime(asset:String):Null<Float> {
|
public function getEditedTime(asset:String):Null<Float> {
|
||||||
return editedTimes[asset];
|
return editedTimes[asset];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getAudioBuffer(id:String):AudioBuffer {
|
public override function getAudioBuffer(id:String):AudioBuffer {
|
||||||
if (!exists(id, "SOUND"))
|
if (!exists(id, "SOUND"))
|
||||||
return null;
|
return null;
|
||||||
var path = getAssetPath();
|
var path = getAssetPath();
|
||||||
@@ -44,9 +44,9 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
|||||||
var e = AudioBuffer.fromFile(path);
|
var e = AudioBuffer.fromFile(path);
|
||||||
// LimeAssets.cache.audio.set('$libName:$id', e);
|
// LimeAssets.cache.audio.set('$libName:$id', e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getBytes(id:String):Bytes {
|
public override function getBytes(id:String):Bytes {
|
||||||
if (!exists(id, "BINARY"))
|
if (!exists(id, "BINARY"))
|
||||||
return null;
|
return null;
|
||||||
var path = getAssetPath();
|
var path = getAssetPath();
|
||||||
@@ -54,18 +54,18 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
|||||||
var e = Bytes.fromFile(path);
|
var e = Bytes.fromFile(path);
|
||||||
cachedBytes.set(id, e);
|
cachedBytes.set(id, e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getFont(id:String):Font {
|
public override function getFont(id:String):Font {
|
||||||
if (!exists(id, "FONT"))
|
if (!exists(id, "FONT"))
|
||||||
return null;
|
return null;
|
||||||
var path = getAssetPath();
|
var path = getAssetPath();
|
||||||
editedTimes[id] = FileSystem.stat(path).mtime.getTime();
|
editedTimes[id] = FileSystem.stat(path).mtime.getTime();
|
||||||
var e = Font.fromFile(path);
|
var e = Font.fromFile(path);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getImage(id:String):Image {
|
public override function getImage(id:String):Image {
|
||||||
if (!exists(id, "IMAGE"))
|
if (!exists(id, "IMAGE"))
|
||||||
return null;
|
return null;
|
||||||
var path = getAssetPath();
|
var path = getAssetPath();
|
||||||
@@ -73,69 +73,69 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
|||||||
|
|
||||||
var e = Image.fromFile(path);
|
var e = Image.fromFile(path);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getPath(id:String):String {
|
public override function getPath(id:String):String {
|
||||||
if (!__parseAsset(id)) return null;
|
if (!__parseAsset(id)) return null;
|
||||||
return getAssetPath();
|
return getAssetPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline function getFolders(folder:String):Array<String>
|
public inline function getFolders(folder:String):Array<String>
|
||||||
return __getFiles(folder, true);
|
return __getFiles(folder, true);
|
||||||
|
|
||||||
public inline function getFiles(folder:String):Array<String>
|
public inline function getFiles(folder:String):Array<String>
|
||||||
return __getFiles(folder, false);
|
return __getFiles(folder, false);
|
||||||
|
|
||||||
public function __getFiles(folder:String, folders:Bool = false) {
|
public function __getFiles(folder:String, folders:Bool = false) {
|
||||||
if (!folder.endsWith("/")) folder = folder + "/";
|
if (!folder.endsWith("/")) folder = folder + "/";
|
||||||
if (!__parseAsset(folder)) return [];
|
if (!__parseAsset(folder)) return [];
|
||||||
var path = getAssetPath();
|
var path = getAssetPath();
|
||||||
try {
|
try {
|
||||||
var result:Array<String> = [];
|
var result:Array<String> = [];
|
||||||
for(e in FileSystem.readDirectory(path))
|
for(e in FileSystem.readDirectory(path))
|
||||||
if (FileSystem.isDirectory('$path$e') == folders)
|
if (FileSystem.isDirectory('$path$e') == folders)
|
||||||
result.push(e);
|
result.push(e);
|
||||||
return result;
|
return result;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// woops!!
|
// woops!!
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function exists(asset:String, type:String):Bool {
|
public override function exists(asset:String, type:String):Bool {
|
||||||
if(!__parseAsset(asset)) return false;
|
if(!__parseAsset(asset)) return false;
|
||||||
return FileSystem.exists(getAssetPath());
|
return FileSystem.exists(getAssetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAssetPath() {
|
private function getAssetPath() {
|
||||||
return '$folderPath/$_parsedAsset';
|
return '$folderPath/$_parsedAsset';
|
||||||
}
|
}
|
||||||
|
|
||||||
private function __isCacheValid(cache:Map<String, Dynamic>, asset:String, isLocalCache:Bool = false) {
|
private function __isCacheValid(cache:Map<String, Dynamic>, asset:String, isLocalCache:Bool = false) {
|
||||||
if (!editedTimes.exists(asset))
|
if (!editedTimes.exists(asset))
|
||||||
return false;
|
return false;
|
||||||
if (editedTimes[asset] == null || editedTimes[asset] < FileSystem.stat(getPath(asset)).mtime.getTime()) {
|
if (editedTimes[asset] == null || editedTimes[asset] < FileSystem.stat(getPath(asset)).mtime.getTime()) {
|
||||||
// destroy already existing to prevent memory leak!!!
|
// destroy already existing to prevent memory leak!!!
|
||||||
var asset = cache[asset];
|
var asset = cache[asset];
|
||||||
if (asset != null) {
|
if (asset != null) {
|
||||||
switch(Type.getClass(asset)) {
|
switch(Type.getClass(asset)) {
|
||||||
case lime.graphics.Image:
|
case lime.graphics.Image:
|
||||||
trace("getting rid of image cause replaced");
|
trace("getting rid of image cause replaced");
|
||||||
cast(asset, lime.graphics.Image);
|
cast(asset, lime.graphics.Image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isLocalCache) asset = '$libName:$asset';
|
if (!isLocalCache) asset = '$libName:$asset';
|
||||||
|
|
||||||
return cache.exists(asset) && cache[asset] != null;
|
return cache.exists(asset) && cache[asset] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function __parseAsset(asset:String):Bool {
|
private function __parseAsset(asset:String):Bool {
|
||||||
if (!asset.startsWith(prefix)) return false;
|
if (!asset.startsWith(prefix)) return false;
|
||||||
_parsedAsset = asset.substr(prefix.length);
|
_parsedAsset = asset.substr(prefix.length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
@@ -25,64 +25,64 @@ import haxe.zip.Entry;
|
|||||||
#end
|
#end
|
||||||
|
|
||||||
class ZipFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
class ZipFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||||
public var zipPath:String;
|
public var zipPath:String;
|
||||||
public var libName:String;
|
public var libName:String;
|
||||||
public var useImageCache:Bool = false;
|
public var useImageCache:Bool = false;
|
||||||
public var prefix = 'assets/';
|
public var prefix = 'assets/';
|
||||||
|
|
||||||
#if MOD_SUPPORT
|
#if MOD_SUPPORT
|
||||||
public var zip:Reader;
|
public var zip:Reader;
|
||||||
public var assets:Map<String, Entry> = [];
|
public var assets:Map<String, Entry> = [];
|
||||||
#end
|
#end
|
||||||
|
|
||||||
public function new(zipPath:String, libName:String) {
|
public function new(zipPath:String, libName:String) {
|
||||||
this.zipPath = zipPath;
|
this.zipPath = zipPath;
|
||||||
this.libName = libName;
|
this.libName = libName;
|
||||||
this.prefix = 'assets/$libName/';
|
this.prefix = 'assets/$libName/';
|
||||||
|
|
||||||
#if MOD_SUPPORT
|
#if MOD_SUPPORT
|
||||||
zip = new Reader(File.read(zipPath, true));
|
zip = new Reader(File.read(zipPath, true));
|
||||||
var entries = zip.read();
|
var entries = zip.read();
|
||||||
for(entry in entries) {
|
for(entry in entries) {
|
||||||
assets[entry.fileName.toLowerCase()] = entry;
|
assets[entry.fileName.toLowerCase()] = entry;
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MOD_SUPPORT
|
#if MOD_SUPPORT
|
||||||
public var _parsedAsset:String;
|
public var _parsedAsset:String;
|
||||||
|
|
||||||
public override function getAudioBuffer(id:String):AudioBuffer {
|
public override function getAudioBuffer(id:String):AudioBuffer {
|
||||||
if (__isCacheValid(LimeAssets.cache.audio, id))
|
if (__isCacheValid(LimeAssets.cache.audio, id))
|
||||||
return LimeAssets.cache.audio.get('$libName:$id');
|
return LimeAssets.cache.audio.get('$libName:$id');
|
||||||
else {
|
else {
|
||||||
if (!exists(id, "SOUND")) {
|
if (!exists(id, "SOUND")) {
|
||||||
Log.error('ZipFolderLibrary: Audio Buffer at $id does not exist.');
|
Log.error('ZipFolderLibrary: Audio Buffer at $id does not exist.');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var e = AudioBuffer.fromBytes(unzip(assets[_parsedAsset]));
|
var e = AudioBuffer.fromBytes(unzip(assets[_parsedAsset]));
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getBytes(id:String):Bytes {
|
public override function getBytes(id:String):Bytes {
|
||||||
if (__isCacheValid(cachedBytes, id, true))
|
if (__isCacheValid(cachedBytes, id, true))
|
||||||
return cachedBytes.get(id);
|
return cachedBytes.get(id);
|
||||||
else {
|
else {
|
||||||
if (!exists(id, "BINARY")) {
|
if (!exists(id, "BINARY")) {
|
||||||
Log.error('ZipFolderLibrary: Bytes at $id does not exist.');
|
Log.error('ZipFolderLibrary: Bytes at $id does not exist.');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var e = Bytes.fromBytes(unzip(assets[_parsedAsset]));
|
var e = Bytes.fromBytes(unzip(assets[_parsedAsset]));
|
||||||
cachedBytes.set(id, e);
|
cachedBytes.set(id, e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function unzip(f:Entry) {
|
public static function unzip(f:Entry) {
|
||||||
if (!f.compressed)
|
if (!f.compressed)
|
||||||
return f.data;
|
return f.data;
|
||||||
var c = new haxe.zip.Uncompress(-15);
|
var c = new haxe.zip.Uncompress(-15);
|
||||||
@@ -97,86 +97,86 @@ class ZipFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
|||||||
return f.data;
|
return f.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getFont(id:String):Font {
|
public override function getFont(id:String):Font {
|
||||||
if (__isCacheValid(LimeAssets.cache.font, id))
|
if (__isCacheValid(LimeAssets.cache.font, id))
|
||||||
return LimeAssets.cache.font.get('$libName:$id');
|
return LimeAssets.cache.font.get('$libName:$id');
|
||||||
else {
|
else {
|
||||||
if (!exists(id, "FONT")) {
|
if (!exists(id, "FONT")) {
|
||||||
Log.error('ZipFolderLibrary: Font at $id does not exist.');
|
Log.error('ZipFolderLibrary: Font at $id does not exist.');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var e = Font.fromBytes(unzip(assets[_parsedAsset]));
|
var e = Font.fromBytes(unzip(assets[_parsedAsset]));
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function getImage(id:String):Image {
|
public override function getImage(id:String):Image {
|
||||||
if (useImageCache && __isCacheValid(LimeAssets.cache.image, id))
|
if (useImageCache && __isCacheValid(LimeAssets.cache.image, id))
|
||||||
return LimeAssets.cache.image.get('$libName:$id');
|
return LimeAssets.cache.image.get('$libName:$id');
|
||||||
else {
|
else {
|
||||||
if (!exists(id, "IMAGE")) {
|
if (!exists(id, "IMAGE")) {
|
||||||
Log.error('ZipFolderLibrary: Image at $id does not exist.');
|
Log.error('ZipFolderLibrary: Image at $id does not exist.');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var e = Image.fromBytes(unzip(assets[_parsedAsset]));
|
var e = Image.fromBytes(unzip(assets[_parsedAsset]));
|
||||||
if (useImageCache) cachedImages.set(id, e);
|
if (useImageCache) cachedImages.set(id, e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __parseAsset(asset:String):Bool {
|
public function __parseAsset(asset:String):Bool {
|
||||||
if (!asset.startsWith(prefix)) return false;
|
if (!asset.startsWith(prefix)) return false;
|
||||||
_parsedAsset = asset.substr(prefix.length).toLowerCase();
|
_parsedAsset = asset.substr(prefix.length).toLowerCase();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __isCacheValid(cache:Map<String, Dynamic>, asset:String, isLocal:Bool = false) {
|
public function __isCacheValid(cache:Map<String, Dynamic>, asset:String, isLocal:Bool = false) {
|
||||||
if (cache.exists(isLocal ? '$libName:$asset': asset)) return true;
|
if (cache.exists(isLocal ? '$libName:$asset': asset)) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function exists(asset:String, type:String):Bool {
|
public override function exists(asset:String, type:String):Bool {
|
||||||
if(!__parseAsset(asset)) return false;
|
if(!__parseAsset(asset)) return false;
|
||||||
|
|
||||||
return assets[_parsedAsset] != null;
|
return assets[_parsedAsset] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAssetPath() {
|
private function getAssetPath() {
|
||||||
return _parsedAsset;
|
return _parsedAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFiles(folder:String):Array<String> {
|
public function getFiles(folder:String):Array<String> {
|
||||||
var content:Array<String> = [];
|
var content:Array<String> = [];
|
||||||
|
|
||||||
if (!folder.endsWith("/")) folder = folder + "/";
|
if (!folder.endsWith("/")) folder = folder + "/";
|
||||||
if (!__parseAsset(folder)) return [];
|
if (!__parseAsset(folder)) return [];
|
||||||
|
|
||||||
@:privateAccess
|
@:privateAccess
|
||||||
for(k=>e in assets) {
|
for(k=>e in assets) {
|
||||||
if (k.toLowerCase().startsWith(_parsedAsset)) {
|
if (k.toLowerCase().startsWith(_parsedAsset)) {
|
||||||
var fileName = k.substr(_parsedAsset.length);
|
var fileName = k.substr(_parsedAsset.length);
|
||||||
if (!fileName.contains("/"))
|
if (!fileName.contains("/"))
|
||||||
content.push(fileName);
|
content.push(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFolders(folder:String):Array<String> {
|
public function getFolders(folder:String):Array<String> {
|
||||||
var content:Array<String> = [];
|
var content:Array<String> = [];
|
||||||
|
|
||||||
if (!folder.endsWith("/")) folder = folder + "/";
|
if (!folder.endsWith("/")) folder = folder + "/";
|
||||||
if (!__parseAsset(folder)) return [];
|
if (!__parseAsset(folder)) return [];
|
||||||
|
|
||||||
@:privateAccess
|
@:privateAccess
|
||||||
for(k=>e in assets) {
|
for(k=>e in assets) {
|
||||||
if (k.toLowerCase().startsWith(_parsedAsset)) {
|
if (k.toLowerCase().startsWith(_parsedAsset)) {
|
||||||
var fileName = k.substr(_parsedAsset.length);
|
var fileName = k.substr(_parsedAsset.length);
|
||||||
if (fileName.contains("/"))
|
if (fileName.contains("/"))
|
||||||
content.push(fileName.split("/")[0]);
|
content.push(fileName.split("/")[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
+122
-122
@@ -4,11 +4,11 @@ import funkin.windows.WindowsAPI.MessageBoxIcon;
|
|||||||
#if windows
|
#if windows
|
||||||
@:buildXml('
|
@:buildXml('
|
||||||
<target id="haxe">
|
<target id="haxe">
|
||||||
<lib name="dwmapi.lib" if="windows" />
|
<lib name="dwmapi.lib" if="windows" />
|
||||||
<lib name="shell32.lib" if="windows" />
|
<lib name="shell32.lib" if="windows" />
|
||||||
<lib name="gdi32.lib" if="windows" />
|
<lib name="gdi32.lib" if="windows" />
|
||||||
<lib name="ole32.lib" if="windows" />
|
<lib name="ole32.lib" if="windows" />
|
||||||
<lib name="uxtheme.lib" if="windows" />
|
<lib name="uxtheme.lib" if="windows" />
|
||||||
</target>
|
</target>
|
||||||
')
|
')
|
||||||
|
|
||||||
@@ -28,86 +28,86 @@ import funkin.windows.WindowsAPI.MessageBoxIcon;
|
|||||||
#include <uxtheme.h>
|
#include <uxtheme.h>
|
||||||
|
|
||||||
#define SAFE_RELEASE(punk) \\
|
#define SAFE_RELEASE(punk) \\
|
||||||
if ((punk) != NULL) \\
|
if ((punk) != NULL) \\
|
||||||
{ (punk)->Release(); (punk) = NULL; }
|
{ (punk)->Release(); (punk) = NULL; }
|
||||||
|
|
||||||
static long lastDefId = 0;
|
static long lastDefId = 0;
|
||||||
|
|
||||||
class AudioFixClient : public IMMNotificationClient {
|
class AudioFixClient : public IMMNotificationClient {
|
||||||
LONG _cRef;
|
LONG _cRef;
|
||||||
IMMDeviceEnumerator *_pEnumerator;
|
IMMDeviceEnumerator *_pEnumerator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioFixClient() :
|
AudioFixClient() :
|
||||||
_cRef(1),
|
_cRef(1),
|
||||||
_pEnumerator(NULL)
|
_pEnumerator(NULL)
|
||||||
{
|
{
|
||||||
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator),
|
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator),
|
||||||
NULL, CLSCTX_INPROC_SERVER,
|
NULL, CLSCTX_INPROC_SERVER,
|
||||||
__uuidof(IMMDeviceEnumerator),
|
__uuidof(IMMDeviceEnumerator),
|
||||||
(void**)&_pEnumerator);
|
(void**)&_pEnumerator);
|
||||||
if (result == S_OK) {
|
if (result == S_OK) {
|
||||||
_pEnumerator->RegisterEndpointNotificationCallback(this);
|
_pEnumerator->RegisterEndpointNotificationCallback(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~AudioFixClient()
|
~AudioFixClient()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(_pEnumerator);
|
SAFE_RELEASE(_pEnumerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE AddRef()
|
ULONG STDMETHODCALLTYPE AddRef()
|
||||||
{
|
{
|
||||||
return InterlockedIncrement(&_cRef);
|
return InterlockedIncrement(&_cRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE Release()
|
ULONG STDMETHODCALLTYPE Release()
|
||||||
{
|
{
|
||||||
ULONG ulRef = InterlockedDecrement(&_cRef);
|
ULONG ulRef = InterlockedDecrement(&_cRef);
|
||||||
if (0 == ulRef)
|
if (0 == ulRef)
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
return ulRef;
|
return ulRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
REFIID riid, VOID **ppvInterface)
|
REFIID riid, VOID **ppvInterface)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId)
|
HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId)
|
HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(
|
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(
|
||||||
LPCWSTR pwstrDeviceId,
|
LPCWSTR pwstrDeviceId,
|
||||||
DWORD dwNewState)
|
DWORD dwNewState)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(
|
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(
|
||||||
LPCWSTR pwstrDeviceId,
|
LPCWSTR pwstrDeviceId,
|
||||||
const PROPERTYKEY key)
|
const PROPERTYKEY key)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(
|
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(
|
||||||
EDataFlow flow, ERole role,
|
EDataFlow flow, ERole role,
|
||||||
LPCWSTR pwstrDeviceId)
|
LPCWSTR pwstrDeviceId)
|
||||||
{
|
{
|
||||||
::funkin::_hx_system::Main_obj::audioDisconnected = true;
|
::funkin::_hx_system::Main_obj::audioDisconnected = true;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
AudioFixClient *curAudioFix;
|
AudioFixClient *curAudioFix;
|
||||||
@@ -115,69 +115,69 @@ AudioFixClient *curAudioFix;
|
|||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
class Windows {
|
class Windows {
|
||||||
|
|
||||||
public static var __audioChangeCallback:Void->Void = function() {
|
public static var __audioChangeCallback:Void->Void = function() {
|
||||||
trace("test");
|
trace("test");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@:functionCode('
|
@:functionCode('
|
||||||
if (!curAudioFix) curAudioFix = new AudioFixClient();
|
if (!curAudioFix) curAudioFix = new AudioFixClient();
|
||||||
')
|
')
|
||||||
public static function registerAudio() {
|
public static function registerAudio() {
|
||||||
funkin.system.Main.audioDisconnected = false;
|
funkin.system.Main.audioDisconnected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@:functionCode('
|
@:functionCode('
|
||||||
int darkMode = enable ? 1 : 0;
|
int darkMode = enable ? 1 : 0;
|
||||||
HWND window = GetActiveWindow();
|
HWND window = GetActiveWindow();
|
||||||
if (S_OK != DwmSetWindowAttribute(window, 19, &darkMode, sizeof(darkMode))) {
|
if (S_OK != DwmSetWindowAttribute(window, 19, &darkMode, sizeof(darkMode))) {
|
||||||
DwmSetWindowAttribute(window, 20, &darkMode, sizeof(darkMode));
|
DwmSetWindowAttribute(window, 20, &darkMode, sizeof(darkMode));
|
||||||
}
|
}
|
||||||
')
|
')
|
||||||
public static function setDarkMode(enable:Bool) {}
|
public static function setDarkMode(enable:Bool) {}
|
||||||
|
|
||||||
@:functionCode('
|
@:functionCode('
|
||||||
// https://stackoverflow.com/questions/15543571/allocconsole-not-displaying-cout
|
// https://stackoverflow.com/questions/15543571/allocconsole-not-displaying-cout
|
||||||
|
|
||||||
if (!AllocConsole())
|
if (!AllocConsole())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
freopen("CONIN$", "r", stdin);
|
freopen("CONIN$", "r", stdin);
|
||||||
freopen("CONOUT$", "w", stdout);
|
freopen("CONOUT$", "w", stdout);
|
||||||
freopen("CONOUT$", "w", stderr);
|
freopen("CONOUT$", "w", stderr);
|
||||||
')
|
')
|
||||||
public static function allocConsole() {
|
public static function allocConsole() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@:functionCode('
|
@:functionCode('
|
||||||
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
SetConsoleTextAttribute(console, color);
|
SetConsoleTextAttribute(console, color);
|
||||||
')
|
')
|
||||||
public static function setConsoleColors(color:Int) {
|
public static function setConsoleColors(color:Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@:functionCode('
|
@:functionCode('
|
||||||
system("CLS");
|
system("CLS");
|
||||||
std::cout<< "" <<std::flush;
|
std::cout<< "" <<std::flush;
|
||||||
')
|
')
|
||||||
public static function clearScreen() {
|
public static function clearScreen() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@:functionCode('
|
@:functionCode('
|
||||||
MessageBox(GetActiveWindow(), message, caption, icon | MB_SETFOREGROUND);
|
MessageBox(GetActiveWindow(), message, caption, icon | MB_SETFOREGROUND);
|
||||||
')
|
')
|
||||||
public static function showMessageBox(caption:String, message:String, icon:MessageBoxIcon = MSG_WARNING) {
|
public static function showMessageBox(caption:String, message:String, icon:MessageBoxIcon = MSG_WARNING) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@:functionCode('
|
@:functionCode('
|
||||||
SetProcessDPIAware();
|
SetProcessDPIAware();
|
||||||
')
|
')
|
||||||
public static function registerAsDPICompatible() {}
|
public static function registerAsDPICompatible() {}
|
||||||
|
|
||||||
@:functionCode("
|
@:functionCode("
|
||||||
// simple but effective code
|
// simple but effective code
|
||||||
|
|||||||
@@ -10,114 +10,114 @@ import funkin.options.categories.*;
|
|||||||
import funkin.options.TreeMenu;
|
import funkin.options.TreeMenu;
|
||||||
|
|
||||||
class OptionsMenu extends TreeMenu {
|
class OptionsMenu extends TreeMenu {
|
||||||
public static var mainOptions:Array<OptionCategory> = [
|
public static var mainOptions:Array<OptionCategory> = [
|
||||||
{
|
{
|
||||||
name: 'Controls',
|
name: 'Controls',
|
||||||
desc: 'Change Controls for Player 1 and Player 2!',
|
desc: 'Change Controls for Player 1 and Player 2!',
|
||||||
state: null,
|
state: null,
|
||||||
substate: funkin.options.keybinds.KeybindsOptions
|
substate: funkin.options.keybinds.KeybindsOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Gameplay >',
|
name: 'Gameplay >',
|
||||||
desc: 'Change Gameplay options such as Downscroll, Scroll Speed, Naughtyness...',
|
desc: 'Change Gameplay options such as Downscroll, Scroll Speed, Naughtyness...',
|
||||||
state: GameplayOptions
|
state: GameplayOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Appearance >',
|
name: 'Appearance >',
|
||||||
desc: 'Change Appearance options such as Flashing menus...',
|
desc: 'Change Appearance options such as Flashing menus...',
|
||||||
state: AppearanceOptions
|
state: AppearanceOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Miscellaneous >',
|
name: 'Miscellaneous >',
|
||||||
desc: 'Use this menu to reset save data or engine settings.',
|
desc: 'Use this menu to reset save data or engine settings.',
|
||||||
state: MiscOptions
|
state: MiscOptions
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
CoolUtil.playMenuSong();
|
CoolUtil.playMenuSong();
|
||||||
|
|
||||||
var bg:FlxSprite = new FlxSprite(-80).loadAnimatedGraphic(Paths.image('menus/menuBGBlue'));
|
var bg:FlxSprite = new FlxSprite(-80).loadAnimatedGraphic(Paths.image('menus/menuBGBlue'));
|
||||||
// bg.scrollFactor.set();
|
// bg.scrollFactor.set();
|
||||||
bg.scale.set(1.15, 1.15);
|
bg.scale.set(1.15, 1.15);
|
||||||
bg.updateHitbox();
|
bg.updateHitbox();
|
||||||
bg.screenCenter();
|
bg.screenCenter();
|
||||||
bg.scrollFactor.set();
|
bg.scrollFactor.set();
|
||||||
bg.antialiasing = true;
|
bg.antialiasing = true;
|
||||||
add(bg);
|
add(bg);
|
||||||
|
|
||||||
main = new OptionsScreen("Options", "Select a category to continue.", [for(o in mainOptions) new TextOption(o.name, o.desc, function() {
|
main = new OptionsScreen("Options", "Select a category to continue.", [for(o in mainOptions) new TextOption(o.name, o.desc, function() {
|
||||||
if (o.substate != null) {
|
if (o.substate != null) {
|
||||||
persistentUpdate = false;
|
persistentUpdate = false;
|
||||||
persistentDraw = true;
|
persistentDraw = true;
|
||||||
if (o.substate is MusicBeatSubstate) {
|
if (o.substate is MusicBeatSubstate) {
|
||||||
openSubState(o.substate);
|
openSubState(o.substate);
|
||||||
} else {
|
} else {
|
||||||
openSubState(Type.createInstance(o.substate, []));
|
openSubState(Type.createInstance(o.substate, []));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (o.state is OptionsScreen) {
|
if (o.state is OptionsScreen) {
|
||||||
optionsTree.add(o.state);
|
optionsTree.add(o.state);
|
||||||
} else {
|
} else {
|
||||||
optionsTree.add(Type.createInstance(o.state, []));
|
optionsTree.add(Type.createInstance(o.state, []));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})]);
|
})]);
|
||||||
|
|
||||||
var xmlPath = Paths.xml("config/options");
|
var xmlPath = Paths.xml("config/options");
|
||||||
for(source in [funkin.system.AssetsLibraryList.AssetSource.SOURCE, funkin.system.AssetsLibraryList.AssetSource.MODS]) {
|
for(source in [funkin.system.AssetsLibraryList.AssetSource.SOURCE, funkin.system.AssetsLibraryList.AssetSource.MODS]) {
|
||||||
if (Paths.assetsTree.existsSpecific(xmlPath, "TEXT", source)) {
|
if (Paths.assetsTree.existsSpecific(xmlPath, "TEXT", source)) {
|
||||||
var access:Access = null;
|
var access:Access = null;
|
||||||
try {
|
try {
|
||||||
access = new Access(Xml.parse(Paths.assetsTree.getSpecificAsset(xmlPath, "TEXT", source)));
|
access = new Access(Xml.parse(Paths.assetsTree.getSpecificAsset(xmlPath, "TEXT", source)));
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Error while parsing options.xml: ${Std.string(e)}', ERROR);
|
Logs.trace('Error while parsing options.xml: ${Std.string(e)}', ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access != null)
|
if (access != null)
|
||||||
for(o in parseOptionsFromXML(access))
|
for(o in parseOptionsFromXML(access))
|
||||||
main.add(o);
|
main.add(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function exit() {
|
public override function exit() {
|
||||||
Options.save();
|
Options.save();
|
||||||
Options.applySettings();
|
Options.applySettings();
|
||||||
super.exit();
|
super.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XML STUFF
|
* XML STUFF
|
||||||
*/
|
*/
|
||||||
public function parseOptionsFromXML(xml:Access):Array<OptionType> {
|
public function parseOptionsFromXML(xml:Access):Array<OptionType> {
|
||||||
var options:Array<OptionType> = [];
|
var options:Array<OptionType> = [];
|
||||||
|
|
||||||
for(node in xml.elements) {
|
for(node in xml.elements) {
|
||||||
if (!node.has.name) {
|
if (!node.has.name) {
|
||||||
Logs.trace("An option node requires a name attribute.", WARNING);
|
Logs.trace("An option node requires a name attribute.", WARNING);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var name = node.getAtt("name");
|
var name = node.getAtt("name");
|
||||||
var desc = node.getAtt("desc").getDefault("No Description");
|
var desc = node.getAtt("desc").getDefault("No Description");
|
||||||
|
|
||||||
switch(node.name) {
|
switch(node.name) {
|
||||||
case "checkbox":
|
case "checkbox":
|
||||||
if (!node.has.id) {
|
if (!node.has.id) {
|
||||||
Logs.trace("A checkbox option requires an \"id\" for option saving.", WARNING);
|
Logs.trace("A checkbox option requires an \"id\" for option saving.", WARNING);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
options.push(new Checkbox(name, desc, node.att.id, FlxG.save.data));
|
options.push(new Checkbox(name, desc, node.att.id, FlxG.save.data));
|
||||||
case "menu":
|
case "menu":
|
||||||
options.push(new TextOption(name + " >", desc, function() {
|
options.push(new TextOption(name + " >", desc, function() {
|
||||||
optionsTree.add(new OptionsScreen(name, desc, parseOptionsFromXML(node)));
|
optionsTree.add(new OptionsScreen(name, desc, parseOptionsFromXML(node)));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,67 +3,67 @@ package funkin.options;
|
|||||||
import funkin.options.type.OptionType;
|
import funkin.options.type.OptionType;
|
||||||
|
|
||||||
class OptionsScreen extends FlxTypedSpriteGroup<OptionType> {
|
class OptionsScreen extends FlxTypedSpriteGroup<OptionType> {
|
||||||
public static var optionHeight:Float = 120;
|
public static var optionHeight:Float = 120;
|
||||||
|
|
||||||
public var parent:OptionsTree;
|
public var parent:OptionsTree;
|
||||||
|
|
||||||
public var curSelected:Int = 0;
|
public var curSelected:Int = 0;
|
||||||
public var id:Int = 0;
|
public var id:Int = 0;
|
||||||
|
|
||||||
private var __firstFrame:Bool = true;
|
private var __firstFrame:Bool = true;
|
||||||
|
|
||||||
public var name:String;
|
public var name:String;
|
||||||
public var desc:String;
|
public var desc:String;
|
||||||
|
|
||||||
public function new(name:String, desc:String, ?options:Array<OptionType>) {
|
public function new(name:String, desc:String, ?options:Array<OptionType>) {
|
||||||
super();
|
super();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.desc = desc;
|
this.desc = desc;
|
||||||
if (options != null) for(o in options) add(o);
|
if (options != null) for(o in options) add(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
var controls = PlayerSettings.solo.controls;
|
var controls = PlayerSettings.solo.controls;
|
||||||
|
|
||||||
changeSelection((controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0) - FlxG.mouse.wheel);
|
changeSelection((controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0) - FlxG.mouse.wheel);
|
||||||
x = id * FlxG.width;
|
x = id * FlxG.width;
|
||||||
for(k=>option in members) {
|
for(k=>option in members) {
|
||||||
var y:Float = ((FlxG.height - optionHeight) / 2) + ((k - curSelected) * optionHeight);
|
var y:Float = ((FlxG.height - optionHeight) / 2) + ((k - curSelected) * optionHeight);
|
||||||
|
|
||||||
option.selected = false;
|
option.selected = false;
|
||||||
option.y = __firstFrame ? y : CoolUtil.fpsLerp(option.y, y, 0.25);
|
option.y = __firstFrame ? y : CoolUtil.fpsLerp(option.y, y, 0.25);
|
||||||
option.x = x + (-50 + (Math.abs(Math.cos((option.y + (optionHeight / 2) - (FlxG.camera.scroll.y + (FlxG.height / 2))) / (FlxG.height * 1.25) * Math.PI)) * 150));
|
option.x = x + (-50 + (Math.abs(Math.cos((option.y + (optionHeight / 2) - (FlxG.camera.scroll.y + (FlxG.height / 2))) / (FlxG.height * 1.25) * Math.PI)) * 150));
|
||||||
}
|
}
|
||||||
if (__firstFrame) {
|
if (__firstFrame) {
|
||||||
__firstFrame = false;
|
__firstFrame = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (members.length > 0) {
|
if (members.length > 0) {
|
||||||
members[curSelected].selected = true;
|
members[curSelected].selected = true;
|
||||||
if (controls.ACCEPT || FlxG.mouse.justReleased)
|
if (controls.ACCEPT || FlxG.mouse.justReleased)
|
||||||
members[curSelected].onSelect();
|
members[curSelected].onSelect();
|
||||||
}
|
}
|
||||||
if (controls.BACK || FlxG.mouse.justReleasedRight)
|
if (controls.BACK || FlxG.mouse.justReleasedRight)
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close() {
|
public function close() {
|
||||||
onClose(this);
|
onClose(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changeSelection(sel:Int) {
|
public function changeSelection(sel:Int) {
|
||||||
if (members.length <= 0 || sel == 0) return;
|
if (members.length <= 0 || sel == 0) return;
|
||||||
|
|
||||||
CoolUtil.playMenuSFX(SCROLL);
|
CoolUtil.playMenuSFX(SCROLL);
|
||||||
|
|
||||||
curSelected = FlxMath.wrap(curSelected + sel, 0, members.length-1);
|
curSelected = FlxMath.wrap(curSelected + sel, 0, members.length-1);
|
||||||
|
|
||||||
for(o in members)
|
for(o in members)
|
||||||
members[curSelected].selected = true;
|
members[curSelected].selected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public dynamic function onClose(o:OptionsScreen) {}
|
public dynamic function onClose(o:OptionsScreen) {}
|
||||||
}
|
}
|
||||||
@@ -2,73 +2,73 @@ package funkin.options;
|
|||||||
|
|
||||||
import flixel.util.FlxDestroyUtil;
|
import flixel.util.FlxDestroyUtil;
|
||||||
class OptionsTree extends FlxTypedGroup<OptionsScreen> {
|
class OptionsTree extends FlxTypedGroup<OptionsScreen> {
|
||||||
public var lastMenu:OptionsScreen;
|
public var lastMenu:OptionsScreen;
|
||||||
public override function new() {
|
public override function new() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
var last = members.last();
|
var last = members.last();
|
||||||
if (last != null)
|
if (last != null)
|
||||||
last.update(elapsed);
|
last.update(elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
super.draw();
|
super.draw();
|
||||||
if (lastMenu != null) {
|
if (lastMenu != null) {
|
||||||
lastMenu.draw();
|
lastMenu.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function add(m:OptionsScreen) {
|
public override function add(m:OptionsScreen) {
|
||||||
super.add(m);
|
super.add(m);
|
||||||
setup(m);
|
setup(m);
|
||||||
clearLastMenu();
|
clearLastMenu();
|
||||||
onMenuChange();
|
onMenuChange();
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
public override function insert(pos:Int, m:OptionsScreen) {
|
public override function insert(pos:Int, m:OptionsScreen) {
|
||||||
var last = members.last();
|
var last = members.last();
|
||||||
super.insert(pos, m);
|
super.insert(pos, m);
|
||||||
setup(m);
|
setup(m);
|
||||||
if (last != members.last())
|
if (last != members.last())
|
||||||
onMenuChange();
|
onMenuChange();
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setup(m:OptionsScreen) {
|
public function setup(m:OptionsScreen) {
|
||||||
m.onClose = __subMenuClose;
|
m.onClose = __subMenuClose;
|
||||||
m.id = members.indexOf(m);
|
m.id = members.indexOf(m);
|
||||||
m.parent = this;
|
m.parent = this;
|
||||||
m.update(0);
|
m.update(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __subMenuClose(m:OptionsScreen) {
|
function __subMenuClose(m:OptionsScreen) {
|
||||||
clearLastMenu();
|
clearLastMenu();
|
||||||
lastMenu = m;
|
lastMenu = m;
|
||||||
remove(m, true);
|
remove(m, true);
|
||||||
onMenuChange();
|
onMenuChange();
|
||||||
onMenuClose(m);
|
onMenuClose(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clearLastMenu() {
|
public function clearLastMenu() {
|
||||||
if (lastMenu != null) {
|
if (lastMenu != null) {
|
||||||
lastMenu.destroy();
|
lastMenu.destroy();
|
||||||
lastMenu = null;
|
lastMenu = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
lastMenu = FlxDestroyUtil.destroy(lastMenu);
|
lastMenu = FlxDestroyUtil.destroy(lastMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
public dynamic function onMenuChange() {
|
public dynamic function onMenuChange() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public dynamic function onMenuClose(m:OptionsScreen) {
|
public dynamic function onMenuClose(m:OptionsScreen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,102 +10,102 @@ import funkin.options.type.OptionType;
|
|||||||
import funkin.options.categories.*;
|
import funkin.options.categories.*;
|
||||||
|
|
||||||
class TreeMenu extends MusicBeatState {
|
class TreeMenu extends MusicBeatState {
|
||||||
|
|
||||||
public var main:OptionsScreen;
|
public var main:OptionsScreen;
|
||||||
public var optionsTree:OptionsTree;
|
public var optionsTree:OptionsTree;
|
||||||
public var pathLabel:FunkinText;
|
public var pathLabel:FunkinText;
|
||||||
public var pathDesc:FunkinText;
|
public var pathDesc:FunkinText;
|
||||||
public var pathBG:FlxSprite;
|
public var pathBG:FlxSprite;
|
||||||
|
|
||||||
public var lastState:Class<FlxState> = Type.getClass(FlxG.state);
|
public var lastState:Class<FlxState> = Type.getClass(FlxG.state);
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function createPost() {
|
public override function createPost() {
|
||||||
if (main == null) throw "\"main\" variable has not been set in extended class!";
|
if (main == null) throw "\"main\" variable has not been set in extended class!";
|
||||||
|
|
||||||
FlxG.camera.scroll.set(-FlxG.width, 0);
|
FlxG.camera.scroll.set(-FlxG.width, 0);
|
||||||
|
|
||||||
pathLabel = new FunkinText(4, 4, FlxG.width - 8, "> Tree Menu", 32, false);
|
pathLabel = new FunkinText(4, 4, FlxG.width - 8, "> Tree Menu", 32, false);
|
||||||
pathLabel.scrollFactor.set();
|
pathLabel.scrollFactor.set();
|
||||||
|
|
||||||
pathDesc = new FunkinText(4, pathLabel.y + pathLabel.height + 2, FlxG.width - 8, "Current Tree Menu Description", 16, false);
|
pathDesc = new FunkinText(4, pathLabel.y + pathLabel.height + 2, FlxG.width - 8, "Current Tree Menu Description", 16, false);
|
||||||
pathDesc.scrollFactor.set();
|
pathDesc.scrollFactor.set();
|
||||||
|
|
||||||
pathBG = new FlxSprite().makeGraphic(1, 1, 0xFF000000);
|
pathBG = new FlxSprite().makeGraphic(1, 1, 0xFF000000);
|
||||||
pathBG.scale.set(FlxG.width, pathDesc.y + pathDesc.height + 2);
|
pathBG.scale.set(FlxG.width, pathDesc.y + pathDesc.height + 2);
|
||||||
pathBG.updateHitbox();
|
pathBG.updateHitbox();
|
||||||
pathBG.alpha = 0.25;
|
pathBG.alpha = 0.25;
|
||||||
pathBG.scrollFactor.set();
|
pathBG.scrollFactor.set();
|
||||||
|
|
||||||
optionsTree = new OptionsTree();
|
optionsTree = new OptionsTree();
|
||||||
optionsTree.onMenuChange = onMenuChange;
|
optionsTree.onMenuChange = onMenuChange;
|
||||||
optionsTree.onMenuClose = onMenuClose;
|
optionsTree.onMenuClose = onMenuClose;
|
||||||
optionsTree.add(main);
|
optionsTree.add(main);
|
||||||
|
|
||||||
|
|
||||||
add(optionsTree);
|
add(optionsTree);
|
||||||
add(pathBG);
|
add(pathBG);
|
||||||
add(pathLabel);
|
add(pathLabel);
|
||||||
add(pathDesc);
|
add(pathDesc);
|
||||||
|
|
||||||
|
|
||||||
super.createPost();
|
super.createPost();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onMenuChange() {
|
public function onMenuChange() {
|
||||||
if (optionsTree.members.length <= 0) {
|
if (optionsTree.members.length <= 0) {
|
||||||
exit();
|
exit();
|
||||||
} else {
|
} else {
|
||||||
if (menuChangeTween != null)
|
if (menuChangeTween != null)
|
||||||
menuChangeTween.cancel();
|
menuChangeTween.cancel();
|
||||||
|
|
||||||
menuChangeTween = FlxTween.tween(FlxG.camera.scroll, {x: FlxG.width * Math.max(0, (optionsTree.members.length-1))}, 1.5, {ease: menuTransitionEase, onComplete: function(t) {
|
menuChangeTween = FlxTween.tween(FlxG.camera.scroll, {x: FlxG.width * Math.max(0, (optionsTree.members.length-1))}, 1.5, {ease: menuTransitionEase, onComplete: function(t) {
|
||||||
optionsTree.clearLastMenu();
|
optionsTree.clearLastMenu();
|
||||||
menuChangeTween = null;
|
menuChangeTween = null;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
var t = "";
|
var t = "";
|
||||||
for(o in optionsTree.members)
|
for(o in optionsTree.members)
|
||||||
t += '${o.name} > ';
|
t += '${o.name} > ';
|
||||||
pathLabel.text = t;
|
pathLabel.text = t;
|
||||||
|
|
||||||
pathDesc.text = optionsTree.members.last().desc;
|
pathDesc.text = optionsTree.members.last().desc;
|
||||||
pathBG.scale.set(FlxG.width, pathDesc.y + pathDesc.height + 2);
|
pathBG.scale.set(FlxG.width, pathDesc.y + pathDesc.height + 2);
|
||||||
pathBG.updateHitbox();
|
pathBG.updateHitbox();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exit() {
|
public function exit() {
|
||||||
FlxG.switchState((lastState != null) ? Type.createInstance(lastState, []) : new MainMenuState());
|
FlxG.switchState((lastState != null) ? Type.createInstance(lastState, []) : new MainMenuState());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onMenuClose(m:OptionsScreen) {
|
public function onMenuClose(m:OptionsScreen) {
|
||||||
CoolUtil.playMenuSFX(CANCEL);
|
CoolUtil.playMenuSFX(CANCEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
var menuChangeTween:FlxTween;
|
var menuChangeTween:FlxTween;
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
// in case path gets so long it goes offscreen
|
// in case path gets so long it goes offscreen
|
||||||
pathLabel.x = lerp(pathLabel.x, Math.max(0, FlxG.width - 4 - pathLabel.width), 0.125);
|
pathLabel.x = lerp(pathLabel.x, Math.max(0, FlxG.width - 4 - pathLabel.width), 0.125);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static inline function menuTransitionEase(e:Float)
|
public static inline function menuTransitionEase(e:Float)
|
||||||
return FlxEase.quintInOut(FlxEase.cubeOut(e));
|
return FlxEase.quintInOut(FlxEase.cubeOut(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef OptionCategory = {
|
typedef OptionCategory = {
|
||||||
var name:String;
|
var name:String;
|
||||||
var desc:String;
|
var desc:String;
|
||||||
var state:OneOfTwo<OptionsScreen, Class<OptionsScreen>>;
|
var state:OneOfTwo<OptionsScreen, Class<OptionsScreen>>;
|
||||||
var ?substate:OneOfTwo<MusicBeatSubstate, Class<MusicBeatSubstate>>;
|
var ?substate:OneOfTwo<MusicBeatSubstate, Class<MusicBeatSubstate>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef OptionTypeDef = {
|
typedef OptionTypeDef = {
|
||||||
var type:Class<OptionType>;
|
var type:Class<OptionType>;
|
||||||
var args:Array<Dynamic>;
|
var args:Array<Dynamic>;
|
||||||
}
|
}
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
package funkin.options.categories;
|
package funkin.options.categories;
|
||||||
|
|
||||||
class AppearanceOptions extends OptionsScreen {
|
class AppearanceOptions extends OptionsScreen {
|
||||||
public override function new() {
|
public override function new() {
|
||||||
super("Appearance", "Change Appearance options such as Flashing menus...");
|
super("Appearance", "Change Appearance options such as Flashing menus...");
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Antialiasing",
|
"Antialiasing",
|
||||||
"If unchecked, will disable antialiasing on every sprite. Can boost performances at the cost of sharper, more pixely sprites",
|
"If unchecked, will disable antialiasing on every sprite. Can boost performances at the cost of sharper, more pixely sprites",
|
||||||
"antialiasing"));
|
"antialiasing"));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Pixel Perfect Effect",
|
"Pixel Perfect Effect",
|
||||||
"If checked, Week 6 will have a pixel perfect effect to it enabled, aligning every pixel on the screen.",
|
"If checked, Week 6 will have a pixel perfect effect to it enabled, aligning every pixel on the screen.",
|
||||||
"week6PixelPerfect"));
|
"week6PixelPerfect"));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Flashing Menu",
|
"Flashing Menu",
|
||||||
"If unchecked, will disable menu flashing when you select an option in the Main Menu, and other flashs will be slower",
|
"If unchecked, will disable menu flashing when you select an option in the Main Menu, and other flashs will be slower",
|
||||||
"flashingMenu"));
|
"flashingMenu"));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Low Memory Mode",
|
"Low Memory Mode",
|
||||||
"If checked, will disable certain background elements in stages to reduce memory usage.",
|
"If checked, will disable certain background elements in stages to reduce memory usage.",
|
||||||
"lowMemoryMode"));
|
"lowMemoryMode"));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Auto Pause",
|
"Auto Pause",
|
||||||
"If checked, switching windows will pause the game",
|
"If checked, switching windows will pause the game",
|
||||||
"autoPause"));
|
"autoPause"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
package funkin.options.categories;
|
package funkin.options.categories;
|
||||||
|
|
||||||
class GameplayOptions extends OptionsScreen {
|
class GameplayOptions extends OptionsScreen {
|
||||||
public override function new() {
|
public override function new() {
|
||||||
super("Gameplay", 'Change Gameplay options such as Downscroll, Scroll Speed, Naughtyness...');
|
super("Gameplay", 'Change Gameplay options such as Downscroll, Scroll Speed, Naughtyness...');
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Downscroll",
|
"Downscroll",
|
||||||
"If checked, notes will go from up to down instead of down to up, like if they were falling",
|
"If checked, notes will go from up to down instead of down to up, like if they were falling",
|
||||||
"downscroll"));
|
"downscroll"));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Ghost Tapping",
|
"Ghost Tapping",
|
||||||
"If unchecked, trying to hit any strum that have no note that can be hit will cause a miss.",
|
"If unchecked, trying to hit any strum that have no note that can be hit will cause a miss.",
|
||||||
"ghostTapping"));
|
"ghostTapping"));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Naughtyness",
|
"Naughtyness",
|
||||||
"If unchecked, will censor Week 7 cutscenes",
|
"If unchecked, will censor Week 7 cutscenes",
|
||||||
"naughtyness"));
|
"naughtyness"));
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Camera Zoom on Beat",
|
"Camera Zoom on Beat",
|
||||||
"If unchecked, will disable camera zooming every 4 beats",
|
"If unchecked, will disable camera zooming every 4 beats",
|
||||||
"camZoomOnBeat"));
|
"camZoomOnBeat"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,31 +2,31 @@ package funkin.options.categories;
|
|||||||
|
|
||||||
|
|
||||||
class MiscOptions extends OptionsScreen {
|
class MiscOptions extends OptionsScreen {
|
||||||
public override function new() {
|
public override function new() {
|
||||||
super("Miscellaneous", "Use this menu to reset save data or engine settings.");
|
super("Miscellaneous", "Use this menu to reset save data or engine settings.");
|
||||||
#if UPDATE_CHECKING
|
#if UPDATE_CHECKING
|
||||||
add(new Checkbox(
|
add(new Checkbox(
|
||||||
"Enable Beta Updates",
|
"Enable Beta Updates",
|
||||||
"If checked, will also include beta (prereleases) updates in the update checking.",
|
"If checked, will also include beta (prereleases) updates in the update checking.",
|
||||||
"betaUpdates"));,
|
"betaUpdates"));,
|
||||||
add(new TextOption(
|
add(new TextOption(
|
||||||
"Check for Updates",
|
"Check for Updates",
|
||||||
"Select this option to check for new engine updates.",
|
"Select this option to check for new engine updates.",
|
||||||
function() {
|
function() {
|
||||||
var report = funkin.updating.UpdateUtil.checkForUpdates();
|
var report = funkin.updating.UpdateUtil.checkForUpdates();
|
||||||
if (report.newUpdate) {
|
if (report.newUpdate) {
|
||||||
FlxG.switchState(new funkin.updating.UpdateAvailableScreen(report));
|
FlxG.switchState(new funkin.updating.UpdateAvailableScreen(report));
|
||||||
} else {
|
} else {
|
||||||
CoolUtil.playMenuSFX(CANCEL);
|
CoolUtil.playMenuSFX(CANCEL);
|
||||||
updateDescText("No update found.");
|
updateDescText("No update found.");
|
||||||
}
|
}
|
||||||
}));,
|
}));,
|
||||||
#end
|
#end
|
||||||
add(new TextOption(
|
add(new TextOption(
|
||||||
"Reset Save Data",
|
"Reset Save Data",
|
||||||
"Select this option to reset save data. This will remove all of your highscores",
|
"Select this option to reset save data. This will remove all of your highscores",
|
||||||
function() {
|
function() {
|
||||||
// TODO: SAVE DATA RESETTING
|
// TODO: SAVE DATA RESETTING
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,32 +7,32 @@ import flixel.util.FlxColor;
|
|||||||
import flixel.input.keyboard.FlxKey;
|
import flixel.input.keyboard.FlxKey;
|
||||||
|
|
||||||
class ChangeKeybindSubState extends MusicBeatSubstate {
|
class ChangeKeybindSubState extends MusicBeatSubstate {
|
||||||
var callback:FlxKey->Void;
|
var callback:FlxKey->Void;
|
||||||
var cancelCallback:Void->Void;
|
var cancelCallback:Void->Void;
|
||||||
|
|
||||||
var stillPressed:Bool = true;
|
var stillPressed:Bool = true;
|
||||||
public override function new(callback:FlxKey->Void, cancelCallback:Void->Void) {
|
public override function new(callback:FlxKey->Void, cancelCallback:Void->Void) {
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.cancelCallback = cancelCallback;
|
this.cancelCallback = cancelCallback;
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
if (stillPressed && controls.ACCEPT)
|
if (stillPressed && controls.ACCEPT)
|
||||||
return;
|
return;
|
||||||
stillPressed = false;
|
stillPressed = false;
|
||||||
|
|
||||||
var key:FlxKey = FlxG.keys.firstJustPressed();
|
var key:FlxKey = FlxG.keys.firstJustPressed();
|
||||||
if (cast(key, Int) <= 0) return;
|
if (cast(key, Int) <= 0) return;
|
||||||
|
|
||||||
if (key == ESCAPE && !FlxG.keys.pressed.SHIFT) {
|
if (key == ESCAPE && !FlxG.keys.pressed.SHIFT) {
|
||||||
close();
|
close();
|
||||||
cancelCallback();
|
cancelCallback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
callback(key);
|
callback(key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,95 +9,95 @@ import flixel.input.keyboard.FlxKey;
|
|||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
class KeybindSetting extends FlxTypedSpriteGroup<FlxSprite> {
|
class KeybindSetting extends FlxTypedSpriteGroup<FlxSprite> {
|
||||||
public var title:Alphabet;
|
public var title:Alphabet;
|
||||||
public var bind1:Alphabet;
|
public var bind1:Alphabet;
|
||||||
public var bind2:Alphabet;
|
public var bind2:Alphabet;
|
||||||
public var icon:FlxSprite;
|
public var icon:FlxSprite;
|
||||||
|
|
||||||
public var changingKeybind:Int = -1;
|
public var changingKeybind:Int = -1;
|
||||||
public var p2Selected:Bool = false;
|
public var p2Selected:Bool = false;
|
||||||
public var value:String;
|
public var value:String;
|
||||||
|
|
||||||
public var option1:Null<FlxKey>;
|
public var option1:Null<FlxKey>;
|
||||||
public var option2:Null<FlxKey>;
|
public var option2:Null<FlxKey>;
|
||||||
public function new(x:Float, y:Float, name:String, value:String, ?sparrowIcon:String, ?sparrowAnim:String) {
|
public function new(x:Float, y:Float, name:String, value:String, ?sparrowIcon:String, ?sparrowAnim:String) {
|
||||||
super();
|
super();
|
||||||
this.value = value;
|
this.value = value;
|
||||||
title = new Alphabet(0, 0, name, true);
|
title = new Alphabet(0, 0, name, true);
|
||||||
add(title);
|
add(title);
|
||||||
|
|
||||||
var controlArrayP1:Array<FlxKey> = Reflect.field(Options, 'P1_${value}');
|
var controlArrayP1:Array<FlxKey> = Reflect.field(Options, 'P1_${value}');
|
||||||
var controlArrayP2:Array<FlxKey> = Reflect.field(Options, 'P2_${value}');
|
var controlArrayP2:Array<FlxKey> = Reflect.field(Options, 'P2_${value}');
|
||||||
|
|
||||||
option1 = controlArrayP1[0];
|
option1 = controlArrayP1[0];
|
||||||
option2 = controlArrayP2[0];
|
option2 = controlArrayP2[0];
|
||||||
|
|
||||||
for(i in 1...3) {
|
for(i in 1...3) {
|
||||||
var b = null;
|
var b = null;
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
b = bind1 = new Alphabet(0, 0, "", false);
|
b = bind1 = new Alphabet(0, 0, "", false);
|
||||||
else
|
else
|
||||||
b = bind2 = new Alphabet(0, 0, "", false);
|
b = bind2 = new Alphabet(0, 0, "", false);
|
||||||
|
|
||||||
b.setPosition(FlxG.width * (0.25 * (i+1)) - x, -60);
|
b.setPosition(FlxG.width * (0.25 * (i+1)) - x, -60);
|
||||||
add(b);
|
add(b);
|
||||||
}
|
}
|
||||||
updateText();
|
updateText();
|
||||||
|
|
||||||
if (sparrowIcon != null) {
|
if (sparrowIcon != null) {
|
||||||
icon = new FlxSprite();
|
icon = new FlxSprite();
|
||||||
icon.frames = Paths.getFrames(sparrowIcon);
|
icon.frames = Paths.getFrames(sparrowIcon);
|
||||||
icon.antialiasing = true;
|
icon.antialiasing = true;
|
||||||
icon.animation.addByPrefix('icon', sparrowAnim, 24, true);
|
icon.animation.addByPrefix('icon', sparrowAnim, 24, true);
|
||||||
icon.animation.play('icon');
|
icon.animation.play('icon');
|
||||||
icon.setGraphicSize(75, 75);
|
icon.setGraphicSize(75, 75);
|
||||||
icon.updateHitbox();
|
icon.updateHitbox();
|
||||||
var min = Math.min(icon.scale.x, icon.scale.y);
|
var min = Math.min(icon.scale.x, icon.scale.y);
|
||||||
icon.scale.set(min, min);
|
icon.scale.set(min, min);
|
||||||
add(icon);
|
add(icon);
|
||||||
|
|
||||||
title.setPosition(100, 0);
|
title.setPosition(100, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
setPosition(x, y);
|
setPosition(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
bind1.alpha = (p2Selected ? 0.2 : 1) / alpha;
|
bind1.alpha = (p2Selected ? 0.2 : 1) / alpha;
|
||||||
bind2.alpha = (p2Selected ? 1 : 0.2) / alpha;
|
bind2.alpha = (p2Selected ? 1 : 0.2) / alpha;
|
||||||
bind1.alpha *= alpha;
|
bind1.alpha *= alpha;
|
||||||
bind2.alpha *= alpha;
|
bind2.alpha *= alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changeKeybind(callback:Void->Void, cancelCallback:Void->Void, p2:Bool = false) {
|
public function changeKeybind(callback:Void->Void, cancelCallback:Void->Void, p2:Bool = false) {
|
||||||
var flicker = FlxFlicker.flicker(this, 0, Options.flashingMenu ? 0.06 : 0.15, true, false, function(t) {});
|
var flicker = FlxFlicker.flicker(this, 0, Options.flashingMenu ? 0.06 : 0.15, true, false, function(t) {});
|
||||||
|
|
||||||
KeybindsOptions.instance.persistentDraw = true;
|
KeybindsOptions.instance.persistentDraw = true;
|
||||||
KeybindsOptions.instance.persistentUpdate = false;
|
KeybindsOptions.instance.persistentUpdate = false;
|
||||||
|
|
||||||
KeybindsOptions.instance.openSubState(new ChangeKeybindSubState(function(key:FlxKey) {
|
KeybindsOptions.instance.openSubState(new ChangeKeybindSubState(function(key:FlxKey) {
|
||||||
flicker.stop();
|
flicker.stop();
|
||||||
flicker.destroy();
|
flicker.destroy();
|
||||||
if (p2)
|
if (p2)
|
||||||
Reflect.setField(Options, 'P2_$value', [option2 = key]);
|
Reflect.setField(Options, 'P2_$value', [option2 = key]);
|
||||||
else
|
else
|
||||||
Reflect.setField(Options, 'P1_$value', [option1 = key]);
|
Reflect.setField(Options, 'P1_$value', [option1 = key]);
|
||||||
updateText();
|
updateText();
|
||||||
callback();
|
callback();
|
||||||
}, function() {
|
}, function() {
|
||||||
flicker.stop();
|
flicker.stop();
|
||||||
flicker.destroy();
|
flicker.destroy();
|
||||||
if (p2)
|
if (p2)
|
||||||
Reflect.setField(Options, 'P2_$value', [option2 = 0]);
|
Reflect.setField(Options, 'P2_$value', [option2 = 0]);
|
||||||
else
|
else
|
||||||
Reflect.setField(Options, 'P1_$value', [option1 = 0]);
|
Reflect.setField(Options, 'P1_$value', [option1 = 0]);
|
||||||
cancelCallback();
|
cancelCallback();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateText() {
|
public function updateText() {
|
||||||
bind1.text = '${CoolUtil.keyToString(option1)}';
|
bind1.text = '${CoolUtil.keyToString(option1)}';
|
||||||
bind2.text = '${CoolUtil.keyToString(option2)}';
|
bind2.text = '${CoolUtil.keyToString(option2)}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,247 +8,247 @@ import flixel.input.keyboard.FlxKey;
|
|||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
class KeybindsOptions extends MusicBeatSubstate {
|
class KeybindsOptions extends MusicBeatSubstate {
|
||||||
public static var instance:KeybindsOptions;
|
public static var instance:KeybindsOptions;
|
||||||
|
|
||||||
public var categories = [
|
public var categories = [
|
||||||
{
|
{
|
||||||
name: 'Notes',
|
name: 'Notes',
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
name: '{noteLeft}',
|
name: '{noteLeft}',
|
||||||
control: 'NOTE_LEFT'
|
control: 'NOTE_LEFT'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '{noteDown}',
|
name: '{noteDown}',
|
||||||
control: 'NOTE_DOWN'
|
control: 'NOTE_DOWN'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '{noteUp}',
|
name: '{noteUp}',
|
||||||
control: 'NOTE_UP'
|
control: 'NOTE_UP'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '{noteRight}',
|
name: '{noteRight}',
|
||||||
control: 'NOTE_RIGHT'
|
control: 'NOTE_RIGHT'
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'UI',
|
name: 'UI',
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
name: 'Left',
|
name: 'Left',
|
||||||
control: 'LEFT'
|
control: 'LEFT'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Down',
|
name: 'Down',
|
||||||
control: 'DOWN'
|
control: 'DOWN'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Up',
|
name: 'Up',
|
||||||
control: 'UP'
|
control: 'UP'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Right',
|
name: 'Right',
|
||||||
control: 'RIGHT'
|
control: 'RIGHT'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Accept',
|
name: 'Accept',
|
||||||
control: 'ACCEPT'
|
control: 'ACCEPT'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Back',
|
name: 'Back',
|
||||||
control: 'BACK'
|
control: 'BACK'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Reset',
|
name: 'Reset',
|
||||||
control: 'RESET'
|
control: 'RESET'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Pause',
|
name: 'Pause',
|
||||||
control: 'PAUSE'
|
control: 'PAUSE'
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Engine',
|
name: 'Engine',
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
name: 'Switch Mod',
|
name: 'Switch Mod',
|
||||||
control: 'SWITCHMOD'
|
control: 'SWITCHMOD'
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
public var settingCam:FlxCamera;
|
public var settingCam:FlxCamera;
|
||||||
|
|
||||||
public var p2Selected:Bool = false;
|
public var p2Selected:Bool = false;
|
||||||
public var curSelected:Int = 0;
|
public var curSelected:Int = 0;
|
||||||
public var canSelect:Bool = true;
|
public var canSelect:Bool = true;
|
||||||
public var alphabets:FlxTypedGroup<KeybindSetting>;
|
public var alphabets:FlxTypedGroup<KeybindSetting>;
|
||||||
public var bg:FlxSprite;
|
public var bg:FlxSprite;
|
||||||
public var coloredBG:FlxSprite;
|
public var coloredBG:FlxSprite;
|
||||||
public var noteColors:Array<FlxColor> = [
|
public var noteColors:Array<FlxColor> = [
|
||||||
0xFFC24B99,
|
0xFFC24B99,
|
||||||
0xFF00FFFF,
|
0xFF00FFFF,
|
||||||
0xFF12FA05,
|
0xFF12FA05,
|
||||||
0xFFF9393F
|
0xFFF9393F
|
||||||
];
|
];
|
||||||
public var camFollow:FlxObject = new FlxObject(0, 0, 2, 2);
|
public var camFollow:FlxObject = new FlxObject(0, 0, 2, 2);
|
||||||
|
|
||||||
var isSubState:Bool = false;
|
var isSubState:Bool = false;
|
||||||
|
|
||||||
public override function create() {
|
public override function create() {
|
||||||
super.create();
|
super.create();
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
isSubState = FlxG.state != this;
|
isSubState = FlxG.state != this;
|
||||||
alphabets = new FlxTypedGroup<KeybindSetting>();
|
alphabets = new FlxTypedGroup<KeybindSetting>();
|
||||||
bg = new FlxSprite(-80).loadAnimatedGraphic(Paths.image(isSubState ? 'menus/menuTransparent' : 'menus/menuBGBlue'));
|
bg = new FlxSprite(-80).loadAnimatedGraphic(Paths.image(isSubState ? 'menus/menuTransparent' : 'menus/menuBGBlue'));
|
||||||
coloredBG = new FlxSprite(-80).loadAnimatedGraphic(Paths.image('menus/menuDesat'));
|
coloredBG = new FlxSprite(-80).loadAnimatedGraphic(Paths.image('menus/menuDesat'));
|
||||||
for(bg in [bg, coloredBG]) {
|
for(bg in [bg, coloredBG]) {
|
||||||
bg.scrollFactor.set();
|
bg.scrollFactor.set();
|
||||||
bg.scale.set(1.15, 1.15);
|
bg.scale.set(1.15, 1.15);
|
||||||
bg.updateHitbox();
|
bg.updateHitbox();
|
||||||
bg.screenCenter();
|
bg.screenCenter();
|
||||||
bg.antialiasing = true;
|
bg.antialiasing = true;
|
||||||
add(bg);
|
add(bg);
|
||||||
}
|
}
|
||||||
coloredBG.alpha = 0;
|
coloredBG.alpha = 0;
|
||||||
|
|
||||||
if (isSubState) {
|
if (isSubState) {
|
||||||
// is substate, opened from pause menu
|
// is substate, opened from pause menu
|
||||||
if (settingCam == null) {
|
if (settingCam == null) {
|
||||||
settingCam = new FlxCamera();
|
settingCam = new FlxCamera();
|
||||||
settingCam.bgColor = 0xAA000000;
|
settingCam.bgColor = 0xAA000000;
|
||||||
FlxG.cameras.add(settingCam, false);
|
FlxG.cameras.add(settingCam, false);
|
||||||
}
|
}
|
||||||
cameras = [settingCam];
|
cameras = [settingCam];
|
||||||
bg.alpha = 0;
|
bg.alpha = 0;
|
||||||
settingCam.follow(camFollow, LOCKON, 0.125);
|
settingCam.follow(camFollow, LOCKON, 0.125);
|
||||||
} else {
|
} else {
|
||||||
FlxG.camera.follow(camFollow, LOCKON, 0.125);
|
FlxG.camera.follow(camFollow, LOCKON, 0.125);
|
||||||
}
|
}
|
||||||
|
|
||||||
var k:Int = 0;
|
var k:Int = 0;
|
||||||
for(category in categories) {
|
for(category in categories) {
|
||||||
k++;
|
k++;
|
||||||
var title = new Alphabet(0, k * 75, category.name, true);
|
var title = new Alphabet(0, k * 75, category.name, true);
|
||||||
title.screenCenter(X);
|
title.screenCenter(X);
|
||||||
add(title);
|
add(title);
|
||||||
|
|
||||||
k++;
|
k++;
|
||||||
for(e in category.settings) {
|
for(e in category.settings) {
|
||||||
var sparrowIcon:String = null;
|
var sparrowIcon:String = null;
|
||||||
var sparrowAnim:String = null;
|
var sparrowAnim:String = null;
|
||||||
if (e.name.startsWith('{note')) {// is actually a note!!
|
if (e.name.startsWith('{note')) {// is actually a note!!
|
||||||
sparrowIcon = "game/notes/default";
|
sparrowIcon = "game/notes/default";
|
||||||
sparrowAnim = switch(e.name) {
|
sparrowAnim = switch(e.name) {
|
||||||
case '{noteLeft}':
|
case '{noteLeft}':
|
||||||
"purple0";
|
"purple0";
|
||||||
case '{noteDown}':
|
case '{noteDown}':
|
||||||
"blue0";
|
"blue0";
|
||||||
case '{noteUp}':
|
case '{noteUp}':
|
||||||
"green0";
|
"green0";
|
||||||
default:
|
default:
|
||||||
"red0";
|
"red0";
|
||||||
};
|
};
|
||||||
e.name = e.name.substring(5, e.name.length - 1);
|
e.name = e.name.substring(5, e.name.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var text = new KeybindSetting(100, k * 75, e.name, e.control, sparrowIcon, sparrowAnim);
|
var text = new KeybindSetting(100, k * 75, e.name, e.control, sparrowIcon, sparrowAnim);
|
||||||
if (!isSubState)
|
if (!isSubState)
|
||||||
text.bind1.color = text.bind2.color = FlxColor.BLACK;
|
text.bind1.color = text.bind2.color = FlxColor.BLACK;
|
||||||
alphabets.add(text);
|
alphabets.add(text);
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add(alphabets);
|
add(alphabets);
|
||||||
add(camFollow);
|
add(camFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
if (settingCam != null) FlxG.cameras.remove(settingCam);
|
if (settingCam != null) FlxG.cameras.remove(settingCam);
|
||||||
instance = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var skipThisFrame:Bool = true;
|
var skipThisFrame:Bool = true;
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
|
|
||||||
if (isSubState) {
|
if (isSubState) {
|
||||||
bg.alpha = lerp(bg.alpha, 0.1, 0.125);
|
bg.alpha = lerp(bg.alpha, 0.1, 0.125);
|
||||||
} else {
|
} else {
|
||||||
if (curSelected < 4) {
|
if (curSelected < 4) {
|
||||||
if (coloredBG.alpha == 0)
|
if (coloredBG.alpha == 0)
|
||||||
coloredBG.color = noteColors[curSelected];
|
coloredBG.color = noteColors[curSelected];
|
||||||
else
|
else
|
||||||
coloredBG.color = CoolUtil.lerpColor(coloredBG.color, noteColors[curSelected], 0.0625);
|
coloredBG.color = CoolUtil.lerpColor(coloredBG.color, noteColors[curSelected], 0.0625);
|
||||||
|
|
||||||
coloredBG.alpha = lerp(coloredBG.alpha, 1, 0.0625);
|
coloredBG.alpha = lerp(coloredBG.alpha, 1, 0.0625);
|
||||||
} else
|
} else
|
||||||
coloredBG.alpha = lerp(coloredBG.alpha, 0, 0.0625);
|
coloredBG.alpha = lerp(coloredBG.alpha, 0, 0.0625);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canSelect) {
|
if (canSelect) {
|
||||||
changeSelection((controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0));
|
changeSelection((controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0));
|
||||||
|
|
||||||
if (controls.BACK) {
|
if (controls.BACK) {
|
||||||
FlxTransitionableState.skipNextTransIn = true;
|
FlxTransitionableState.skipNextTransIn = true;
|
||||||
if (isSubState)
|
if (isSubState)
|
||||||
close();
|
close();
|
||||||
else
|
else
|
||||||
FlxG.switchState(new OptionsMenu());
|
FlxG.switchState(new OptionsMenu());
|
||||||
Options.applyKeybinds();
|
Options.applyKeybinds();
|
||||||
Options.save();
|
Options.save();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controls.ACCEPT && !skipThisFrame) {
|
if (controls.ACCEPT && !skipThisFrame) {
|
||||||
if (alphabets.members[curSelected] != null) {
|
if (alphabets.members[curSelected] != null) {
|
||||||
canSelect = false;
|
canSelect = false;
|
||||||
CoolUtil.playMenuSFX(CONFIRM);
|
CoolUtil.playMenuSFX(CONFIRM);
|
||||||
alphabets.members[curSelected].changeKeybind(function() {
|
alphabets.members[curSelected].changeKeybind(function() {
|
||||||
canSelect = true;
|
canSelect = true;
|
||||||
}, function() {
|
}, function() {
|
||||||
canSelect = true;
|
canSelect = true;
|
||||||
}, p2Selected);
|
}, p2Selected);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controls.LEFT_P || controls.RIGHT_P) {
|
if (controls.LEFT_P || controls.RIGHT_P) {
|
||||||
if (alphabets.members[curSelected] != null) {
|
if (alphabets.members[curSelected] != null) {
|
||||||
CoolUtil.playMenuSFX(SCROLL, 0.7);
|
CoolUtil.playMenuSFX(SCROLL, 0.7);
|
||||||
alphabets.members[curSelected].p2Selected = (p2Selected = !p2Selected);
|
alphabets.members[curSelected].p2Selected = (p2Selected = !p2Selected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
skipThisFrame = false;
|
skipThisFrame = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changeSelection(change:Int) {
|
public function changeSelection(change:Int) {
|
||||||
if (change != 0) CoolUtil.playMenuSFX(SCROLL, 0.4);
|
if (change != 0) CoolUtil.playMenuSFX(SCROLL, 0.4);
|
||||||
|
|
||||||
curSelected = FlxMath.wrap(curSelected + change, 0, alphabets.length-1);
|
curSelected = FlxMath.wrap(curSelected + change, 0, alphabets.length-1);
|
||||||
alphabets.forEach(function(e) {
|
alphabets.forEach(function(e) {
|
||||||
e.alpha = 0.2;
|
e.alpha = 0.2;
|
||||||
});
|
});
|
||||||
if (alphabets.members[curSelected] != null) {
|
if (alphabets.members[curSelected] != null) {
|
||||||
var alphabet = alphabets.members[curSelected];
|
var alphabet = alphabets.members[curSelected];
|
||||||
alphabet.p2Selected = p2Selected;
|
alphabet.p2Selected = p2Selected;
|
||||||
alphabet.alpha = 1;
|
alphabet.alpha = 1;
|
||||||
var minH = FlxG.height / 2;
|
var minH = FlxG.height / 2;
|
||||||
var maxH = alphabets.members[alphabets.length-1].y + alphabets.members[alphabets.length-1].height - (FlxG.height / 2);
|
var maxH = alphabets.members[alphabets.length-1].y + alphabets.members[alphabets.length-1].height - (FlxG.height / 2);
|
||||||
if (minH < maxH)
|
if (minH < maxH)
|
||||||
camFollow.setPosition(FlxG.width / 2, FlxMath.bound(alphabet.y + (alphabet.height / 2) - (35), minH, maxH));
|
camFollow.setPosition(FlxG.width / 2, FlxMath.bound(alphabet.y + (alphabet.height / 2) - (35), minH, maxH));
|
||||||
else
|
else
|
||||||
camFollow.setPosition(FlxG.width / 2, FlxG.height / 2);
|
camFollow.setPosition(FlxG.width / 2, FlxG.height / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,67 +5,67 @@ import flixel.math.FlxPoint;
|
|||||||
@:allow()
|
@:allow()
|
||||||
class Checkbox extends TextOption {
|
class Checkbox extends TextOption {
|
||||||
|
|
||||||
public var checkbox:FlxSprite;
|
public var checkbox:FlxSprite;
|
||||||
public var checked:Bool;
|
public var checked:Bool;
|
||||||
|
|
||||||
public var parent:Dynamic;
|
public var parent:Dynamic;
|
||||||
|
|
||||||
private function get_selected() {
|
private function get_selected() {
|
||||||
|
|
||||||
}
|
}
|
||||||
public var optionName:String;
|
public var optionName:String;
|
||||||
|
|
||||||
private var offsets:Map<String, FlxPoint> = [
|
private var offsets:Map<String, FlxPoint> = [
|
||||||
"checked" => FlxPoint.get(1, -1),
|
"checked" => FlxPoint.get(1, -1),
|
||||||
"unchecked" => FlxPoint.get(-12, -72),
|
"unchecked" => FlxPoint.get(-12, -72),
|
||||||
"checking" => FlxPoint.get(12, 30)
|
"checking" => FlxPoint.get(12, 30)
|
||||||
];
|
];
|
||||||
private var baseCheckboxOffset:FlxPoint = FlxPoint.get();
|
private var baseCheckboxOffset:FlxPoint = FlxPoint.get();
|
||||||
|
|
||||||
public function new(text:String, desc:String, optionName:String, ?parent:Dynamic) {
|
public function new(text:String, desc:String, optionName:String, ?parent:Dynamic) {
|
||||||
super(text, desc, null);
|
super(text, desc, null);
|
||||||
|
|
||||||
if (parent == null)
|
if (parent == null)
|
||||||
parent = Options;
|
parent = Options;
|
||||||
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
|
||||||
checkbox = new FlxSprite(10, -40);
|
checkbox = new FlxSprite(10, -40);
|
||||||
checkbox.frames = Paths.getFrames('menus/options/checkboxThingie');
|
checkbox.frames = Paths.getFrames('menus/options/checkboxThingie');
|
||||||
checkbox.animation.addByPrefix("checked", "Check Box Selected Static", 24);
|
checkbox.animation.addByPrefix("checked", "Check Box Selected Static", 24);
|
||||||
checkbox.animation.addByPrefix("unchecked", "Check Box unselected", 24);
|
checkbox.animation.addByPrefix("unchecked", "Check Box unselected", 24);
|
||||||
checkbox.animation.addByPrefix("checking", "Check Box selecting animation", 24, false);
|
checkbox.animation.addByPrefix("checking", "Check Box selecting animation", 24, false);
|
||||||
checkbox.antialiasing = true;
|
checkbox.antialiasing = true;
|
||||||
checkbox.scale.set(0.75, 0.75);
|
checkbox.scale.set(0.75, 0.75);
|
||||||
checkbox.updateHitbox();
|
checkbox.updateHitbox();
|
||||||
add(checkbox);
|
add(checkbox);
|
||||||
|
|
||||||
baseCheckboxOffset.set(checkbox.offset.x, checkbox.offset.y);
|
baseCheckboxOffset.set(checkbox.offset.x, checkbox.offset.y);
|
||||||
|
|
||||||
this.optionName = optionName;
|
this.optionName = optionName;
|
||||||
checked = Reflect.field(parent, optionName);
|
checked = Reflect.field(parent, optionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
if (checkbox.animation.curAnim == null || (checkbox.animation.curAnim.finished || (checkbox.animation.curAnim.reversed && checkbox.animation.curAnim.curFrame <= 0))) {
|
if (checkbox.animation.curAnim == null || (checkbox.animation.curAnim.finished || (checkbox.animation.curAnim.reversed && checkbox.animation.curAnim.curFrame <= 0))) {
|
||||||
checkbox.animation.play(checked ? "checked" : "unchecked", true);
|
checkbox.animation.play(checked ? "checked" : "unchecked", true);
|
||||||
}
|
}
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
var offset = offsets[checkbox.animation.curAnim.name];
|
var offset = offsets[checkbox.animation.curAnim.name];
|
||||||
if (offset != null)
|
if (offset != null)
|
||||||
checkbox.offset.set(
|
checkbox.offset.set(
|
||||||
(offset.x * checkbox.scale.x) + baseCheckboxOffset.x,
|
(offset.x * checkbox.scale.x) + baseCheckboxOffset.x,
|
||||||
(offset.y * checkbox.scale.y) + baseCheckboxOffset.y);
|
(offset.y * checkbox.scale.y) + baseCheckboxOffset.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function onSelect() {
|
public override function onSelect() {
|
||||||
Reflect.setField(parent, optionName, checked = !checked);
|
Reflect.setField(parent, optionName, checked = !checked);
|
||||||
checkbox.animation.play("checking", true, !checked);
|
checkbox.animation.play("checking", true, !checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
for(e in offsets) e.put();
|
for(e in offsets) e.put();
|
||||||
baseCheckboxOffset.put();
|
baseCheckboxOffset.put();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,13 +3,13 @@ package funkin.options.type;
|
|||||||
import funkin.game.HealthIcon;
|
import funkin.game.HealthIcon;
|
||||||
|
|
||||||
class IconOption extends TextOption {
|
class IconOption extends TextOption {
|
||||||
public var iconSpr:HealthIcon;
|
public var iconSpr:HealthIcon;
|
||||||
|
|
||||||
public function new(name:String, desc:String, icon:String, callback:Void->Void) {
|
public function new(name:String, desc:String, icon:String, callback:Void->Void) {
|
||||||
super(name, desc, callback);
|
super(name, desc, callback);
|
||||||
|
|
||||||
iconSpr = new HealthIcon(icon, false);
|
iconSpr = new HealthIcon(icon, false);
|
||||||
iconSpr.setPosition(90 - iconSpr.width, (__text.height - iconSpr.height) / 2);
|
iconSpr.setPosition(90 - iconSpr.width, (__text.height - iconSpr.height) / 2);
|
||||||
add(iconSpr);
|
add(iconSpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,24 +5,24 @@ import flixel.group.FlxSpriteGroup;
|
|||||||
import funkin.options.OptionsScreen;
|
import funkin.options.OptionsScreen;
|
||||||
|
|
||||||
class OptionType extends FlxSpriteGroup {
|
class OptionType extends FlxSpriteGroup {
|
||||||
public var controls(get, null):Controls;
|
public var controls(get, null):Controls;
|
||||||
public var selected:Bool = false;
|
public var selected:Bool = false;
|
||||||
public var desc:String;
|
public var desc:String;
|
||||||
|
|
||||||
public function new(desc:String) {
|
public function new(desc:String) {
|
||||||
super();
|
super();
|
||||||
this.desc = desc;
|
this.desc = desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function get_controls() {return PlayerSettings.solo.controls;}
|
private function get_controls() {return PlayerSettings.solo.controls;}
|
||||||
|
|
||||||
public function onSelect() {
|
public function onSelect() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
alpha = (selected ? 1 : 0.6);
|
alpha = (selected ? 1 : 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3,29 +3,29 @@ package funkin.options.type;
|
|||||||
import flixel.effects.FlxFlicker;
|
import flixel.effects.FlxFlicker;
|
||||||
|
|
||||||
class TextOption extends OptionType {
|
class TextOption extends OptionType {
|
||||||
public var selectCallback:Void->Void;
|
public var selectCallback:Void->Void;
|
||||||
|
|
||||||
private var __text:Alphabet;
|
private var __text:Alphabet;
|
||||||
|
|
||||||
public var text(get, set):String;
|
public var text(get, set):String;
|
||||||
private function get_text() {return __text.text;}
|
private function get_text() {return __text.text;}
|
||||||
private function set_text(v:String) {return __text.text = v;}
|
private function set_text(v:String) {return __text.text = v;}
|
||||||
|
|
||||||
public function new(text:String, desc:String, selectCallback:Void->Void) {
|
public function new(text:String, desc:String, selectCallback:Void->Void) {
|
||||||
super(desc);
|
super(desc);
|
||||||
this.selectCallback = selectCallback;
|
this.selectCallback = selectCallback;
|
||||||
add(__text = new Alphabet(100, 20, text, true));
|
add(__text = new Alphabet(100, 20, text, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function draw() {
|
public override function draw() {
|
||||||
super.draw();
|
super.draw();
|
||||||
}
|
}
|
||||||
public override function onSelect() {
|
public override function onSelect() {
|
||||||
super.onSelect();
|
super.onSelect();
|
||||||
CoolUtil.playMenuSFX(CONFIRM);
|
CoolUtil.playMenuSFX(CONFIRM);
|
||||||
FlxFlicker.flicker(this, 1, Options.flashingMenu ? 0.06 : 0.15, true, false, function(t) {
|
FlxFlicker.flicker(this, 1, Options.flashingMenu ? 0.06 : 0.15, true, false, function(t) {
|
||||||
|
|
||||||
});
|
});
|
||||||
selectCallback();
|
selectCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,15 +4,15 @@ package funkin.scripting;
|
|||||||
* Simple class for empty scripts or scripts whose language isn't imported yet.
|
* Simple class for empty scripts or scripts whose language isn't imported yet.
|
||||||
*/
|
*/
|
||||||
class DummyScript extends Script {
|
class DummyScript extends Script {
|
||||||
public var variables:Map<String, Dynamic> = [];
|
public var variables:Map<String, Dynamic> = [];
|
||||||
|
|
||||||
public override function get(v:String) {return variables.get(v);}
|
public override function get(v:String) {return variables.get(v);}
|
||||||
public override function set(v:String, v2:Dynamic) {return variables.set(v, v2);}
|
public override function set(v:String, v2:Dynamic) {return variables.set(v, v2);}
|
||||||
public override function onCall(method:String, parameters:Array<Dynamic>):Dynamic {
|
public override function onCall(method:String, parameters:Array<Dynamic>):Dynamic {
|
||||||
var func = variables.get(method);
|
var func = variables.get(method);
|
||||||
if (Reflect.isFunction(func))
|
if (Reflect.isFunction(func))
|
||||||
return (parameters != null && parameters.length > 0) ? Reflect.callMethod(null, func, parameters) : func();
|
return (parameters != null && parameters.length > 0) ? Reflect.callMethod(null, func, parameters) : func();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,35 +4,35 @@ import flixel.FlxState;
|
|||||||
import funkin.scripting.events.*;
|
import funkin.scripting.events.*;
|
||||||
|
|
||||||
class EventManager {
|
class EventManager {
|
||||||
// map doesnt work for that
|
// map doesnt work for that
|
||||||
public static var eventValues:Array<CancellableEvent> = [];
|
public static var eventValues:Array<CancellableEvent> = [];
|
||||||
public static var eventKeys:Array<Class<CancellableEvent>> = [];
|
public static var eventKeys:Array<Class<CancellableEvent>> = [];
|
||||||
|
|
||||||
public static function get<T:CancellableEvent>(cl:Class<T>):T {
|
public static function get<T:CancellableEvent>(cl:Class<T>):T {
|
||||||
var c:Class<CancellableEvent> = cast cl;
|
var c:Class<CancellableEvent> = cast cl;
|
||||||
|
|
||||||
var index = eventKeys.indexOf(c);
|
var index = eventKeys.indexOf(c);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
eventKeys.push(c);
|
eventKeys.push(c);
|
||||||
eventValues.push(Type.createInstance(c, []));
|
eventValues.push(Type.createInstance(c, []));
|
||||||
return cast eventValues.last();
|
return cast eventValues.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
return cast eventValues[index];
|
return cast eventValues[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function reset() {
|
public static function reset() {
|
||||||
for(v in eventValues)
|
for(v in eventValues)
|
||||||
v.destroy();
|
v.destroy();
|
||||||
eventValues = [];
|
eventValues = [];
|
||||||
eventKeys = [];
|
eventKeys = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function init() {
|
public static function init() {
|
||||||
|
|
||||||
FlxG.signals.preStateCreate.add(onStateSwitch);
|
FlxG.signals.preStateCreate.add(onStateSwitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static inline function onStateSwitch(newState:FlxState)
|
private static inline function onStateSwitch(newState:FlxState)
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@@ -9,103 +9,103 @@ import funkin.mods.ModsFolder;
|
|||||||
* Class for THE Global Script, aka script that runs in the background at all times.
|
* Class for THE Global Script, aka script that runs in the background at all times.
|
||||||
*/
|
*/
|
||||||
class GlobalScript {
|
class GlobalScript {
|
||||||
public static var script:Script;
|
public static var script:Script;
|
||||||
|
|
||||||
public static function init() {
|
public static function init() {
|
||||||
#if MOD_SUPPORT
|
#if MOD_SUPPORT
|
||||||
ModsFolder.onModSwitch.add(onModSwitch);
|
ModsFolder.onModSwitch.add(onModSwitch);
|
||||||
#end
|
#end
|
||||||
|
|
||||||
Conductor.onBeatHit.add(beatHit);
|
Conductor.onBeatHit.add(beatHit);
|
||||||
Conductor.onStepHit.add(stepHit);
|
Conductor.onStepHit.add(stepHit);
|
||||||
|
|
||||||
FlxG.signals.focusGained.add(function() {
|
FlxG.signals.focusGained.add(function() {
|
||||||
call("focusGained");
|
call("focusGained");
|
||||||
});
|
});
|
||||||
FlxG.signals.focusLost.add(function() {
|
FlxG.signals.focusLost.add(function() {
|
||||||
call("focusLost");
|
call("focusLost");
|
||||||
});
|
});
|
||||||
FlxG.signals.gameResized.add(function(w:Int, h:Int) {
|
FlxG.signals.gameResized.add(function(w:Int, h:Int) {
|
||||||
call("gameResized", [w, h]);
|
call("gameResized", [w, h]);
|
||||||
});
|
});
|
||||||
FlxG.signals.postDraw.add(function() {
|
FlxG.signals.postDraw.add(function() {
|
||||||
call("postDraw");
|
call("postDraw");
|
||||||
});
|
});
|
||||||
FlxG.signals.postGameReset.add(function() {
|
FlxG.signals.postGameReset.add(function() {
|
||||||
call("postGameReset");
|
call("postGameReset");
|
||||||
});
|
});
|
||||||
FlxG.signals.postGameStart.add(function() {
|
FlxG.signals.postGameStart.add(function() {
|
||||||
call("postGameStart");
|
call("postGameStart");
|
||||||
});
|
});
|
||||||
FlxG.signals.postStateSwitch.add(function() {
|
FlxG.signals.postStateSwitch.add(function() {
|
||||||
call("postStateSwitch");
|
call("postStateSwitch");
|
||||||
});
|
});
|
||||||
FlxG.signals.postUpdate.add(function() {
|
FlxG.signals.postUpdate.add(function() {
|
||||||
call("postUpdate", [FlxG.elapsed]);
|
call("postUpdate", [FlxG.elapsed]);
|
||||||
if (FlxG.keys.justPressed.F5) {
|
if (FlxG.keys.justPressed.F5) {
|
||||||
if (script != null && !(script is DummyScript)) {
|
if (script != null && !(script is DummyScript)) {
|
||||||
Logs.trace('Reloading global script...', WARNING, YELLOW);
|
Logs.trace('Reloading global script...', WARNING, YELLOW);
|
||||||
script.reload();
|
script.reload();
|
||||||
Logs.trace('Global script successfully reloaded.', WARNING, GREEN);
|
Logs.trace('Global script successfully reloaded.', WARNING, GREEN);
|
||||||
} else {
|
} else {
|
||||||
Logs.trace('Loading global script...', WARNING, YELLOW);
|
Logs.trace('Loading global script...', WARNING, YELLOW);
|
||||||
onModSwitch(#if MOD_SUPPORT ModsFolder.currentModFolder #else null #end);
|
onModSwitch(#if MOD_SUPPORT ModsFolder.currentModFolder #else null #end);
|
||||||
if (script is DummyScript)
|
if (script is DummyScript)
|
||||||
Logs.trace('Global script not found. Are you sure "data/global.hx" exists?', ERROR, RED);
|
Logs.trace('Global script not found. Are you sure "data/global.hx" exists?', ERROR, RED);
|
||||||
else
|
else
|
||||||
Logs.trace('Global script successfully loaded.', WARNING, GREEN);
|
Logs.trace('Global script successfully loaded.', WARNING, GREEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
FlxG.signals.preDraw.add(function() {
|
FlxG.signals.preDraw.add(function() {
|
||||||
call("preDraw");
|
call("preDraw");
|
||||||
});
|
});
|
||||||
FlxG.signals.preGameReset.add(function() {
|
FlxG.signals.preGameReset.add(function() {
|
||||||
call("preGameReset");
|
call("preGameReset");
|
||||||
});
|
});
|
||||||
FlxG.signals.preGameStart.add(function() {
|
FlxG.signals.preGameStart.add(function() {
|
||||||
call("preGameStart");
|
call("preGameStart");
|
||||||
});
|
});
|
||||||
FlxG.signals.preStateCreate.add(function(state:FlxState) {
|
FlxG.signals.preStateCreate.add(function(state:FlxState) {
|
||||||
call("preStateCreate", [state]);
|
call("preStateCreate", [state]);
|
||||||
});
|
});
|
||||||
FlxG.signals.preStateSwitch.add(function() {
|
FlxG.signals.preStateSwitch.add(function() {
|
||||||
call("preStateSwitch", []);
|
call("preStateSwitch", []);
|
||||||
});
|
});
|
||||||
FlxG.signals.preUpdate.add(function() {
|
FlxG.signals.preUpdate.add(function() {
|
||||||
call("preUpdate", [FlxG.elapsed]);
|
call("preUpdate", [FlxG.elapsed]);
|
||||||
call("update", [FlxG.elapsed]);
|
call("update", [FlxG.elapsed]);
|
||||||
});
|
});
|
||||||
|
|
||||||
onModSwitch(#if MOD_SUPPORT ModsFolder.currentModFolder #else null #end);
|
onModSwitch(#if MOD_SUPPORT ModsFolder.currentModFolder #else null #end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function event<T:CancellableEvent>(name:String, event:T):T {
|
public static function event<T:CancellableEvent>(name:String, event:T):T {
|
||||||
if (script == null) return event;
|
if (script == null) return event;
|
||||||
script.call(name, [event]);
|
script.call(name, [event]);
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function call(name:String, ?args:Array<Dynamic>) {
|
public static function call(name:String, ?args:Array<Dynamic>) {
|
||||||
if (script == null) return;
|
if (script == null) return;
|
||||||
script.call(name, args);
|
script.call(name, args);
|
||||||
}
|
}
|
||||||
public static function onModSwitch(newMod:String) {
|
public static function onModSwitch(newMod:String) {
|
||||||
call("onDestroy");
|
call("onDestroy");
|
||||||
if (script != null) {
|
if (script != null) {
|
||||||
script.destroy();
|
script.destroy();
|
||||||
script = null;
|
script = null;
|
||||||
}
|
}
|
||||||
script = Script.create(Paths.script('data/global'));
|
script = Script.create(Paths.script('data/global'));
|
||||||
script.load();
|
script.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function beatHit(curBeat:Int) {
|
public static function beatHit(curBeat:Int) {
|
||||||
call("beatHit", [curBeat]);
|
call("beatHit", [curBeat]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function stepHit(curStep:Int) {
|
public static function stepHit(curStep:Int) {
|
||||||
call("stepHit", [curStep]);
|
call("stepHit", [curStep]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@@ -5,112 +5,112 @@ import openfl.Assets;
|
|||||||
import hscript.*;
|
import hscript.*;
|
||||||
|
|
||||||
class HScript extends Script {
|
class HScript extends Script {
|
||||||
public var interp:Interp;
|
public var interp:Interp;
|
||||||
public var expr:Expr;
|
public var expr:Expr;
|
||||||
|
|
||||||
public override function onCreate(path:String) {
|
public override function onCreate(path:String) {
|
||||||
super.onCreate(path);
|
super.onCreate(path);
|
||||||
|
|
||||||
interp = new Interp();
|
interp = new Interp();
|
||||||
|
|
||||||
var code:String = Assets.getText(path);
|
var code:String = Assets.getText(path);
|
||||||
var parser = new hscript.Parser();
|
var parser = new hscript.Parser();
|
||||||
parser.allowJSON = parser.allowMetadata = parser.allowTypes = true;
|
parser.allowJSON = parser.allowMetadata = parser.allowTypes = true;
|
||||||
parser.preprocesorValues = Script.getDefaultPreprocessors();
|
parser.preprocesorValues = Script.getDefaultPreprocessors();
|
||||||
interp.errorHandler = _errorHandler;
|
interp.errorHandler = _errorHandler;
|
||||||
interp.staticVariables = Script.staticVariables;
|
interp.staticVariables = Script.staticVariables;
|
||||||
interp.allowStaticVariables = interp.allowPublicVariables = true;
|
interp.allowStaticVariables = interp.allowPublicVariables = true;
|
||||||
|
|
||||||
interp.variables.set("trace", Reflect.makeVarArgs((args) -> {
|
interp.variables.set("trace", Reflect.makeVarArgs((args) -> {
|
||||||
var v:String = Std.string(args.shift());
|
var v:String = Std.string(args.shift());
|
||||||
for (a in args) v += ", " + Std.string(a);
|
for (a in args) v += ", " + Std.string(a);
|
||||||
this.trace(v);
|
this.trace(v);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expr = parser.parseString(code, fileName);
|
expr = parser.parseString(code, fileName);
|
||||||
} catch(e:Error) {
|
} catch(e:Error) {
|
||||||
_errorHandler(e);
|
_errorHandler(e);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
_errorHandler(new Error(ECustom(e.toString()), 0, 0, fileName, 0));
|
_errorHandler(new Error(ECustom(e.toString()), 0, 0, fileName, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _errorHandler(error:Error) {
|
private function _errorHandler(error:Error) {
|
||||||
|
|
||||||
var fn = '$fileName:${error.line}: ';
|
var fn = '$fileName:${error.line}: ';
|
||||||
var err = error.toString();
|
var err = error.toString();
|
||||||
if (err.startsWith(fn)) err = err.substr(fn.length);
|
if (err.startsWith(fn)) err = err.substr(fn.length);
|
||||||
|
|
||||||
Logs.traceColored([
|
Logs.traceColored([
|
||||||
Logs.logText(fn, GREEN),
|
Logs.logText(fn, GREEN),
|
||||||
Logs.logText(err, RED)
|
Logs.logText(err, RED)
|
||||||
], ERROR);
|
], ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function setParent(parent:Dynamic) {
|
public override function setParent(parent:Dynamic) {
|
||||||
interp.scriptObject = parent;
|
interp.scriptObject = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function onLoad() {
|
public override function onLoad() {
|
||||||
if (expr != null) {
|
if (expr != null) {
|
||||||
interp.execute(expr);
|
interp.execute(expr);
|
||||||
call("new", []);
|
call("new", []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function reload() {
|
public override function reload() {
|
||||||
// save variables
|
// save variables
|
||||||
|
|
||||||
interp.allowStaticVariables = interp.allowPublicVariables = false;
|
interp.allowStaticVariables = interp.allowPublicVariables = false;
|
||||||
var savedVariables:Map<String, Dynamic> = [];
|
var savedVariables:Map<String, Dynamic> = [];
|
||||||
for(k=>e in interp.variables) {
|
for(k=>e in interp.variables) {
|
||||||
if (!Reflect.isFunction(e)) {
|
if (!Reflect.isFunction(e)) {
|
||||||
savedVariables[k] = e;
|
savedVariables[k] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var oldParent = interp.scriptObject;
|
var oldParent = interp.scriptObject;
|
||||||
onCreate(path);
|
onCreate(path);
|
||||||
|
|
||||||
for(k=>e in Script.getDefaultVariables(this))
|
for(k=>e in Script.getDefaultVariables(this))
|
||||||
set(k, e);
|
set(k, e);
|
||||||
|
|
||||||
load();
|
load();
|
||||||
setParent(oldParent);
|
setParent(oldParent);
|
||||||
|
|
||||||
for(k=>e in savedVariables)
|
for(k=>e in savedVariables)
|
||||||
interp.variables.set(k, e);
|
interp.variables.set(k, e);
|
||||||
|
|
||||||
interp.allowStaticVariables = interp.allowPublicVariables = true;
|
interp.allowStaticVariables = interp.allowPublicVariables = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private override function onCall(funcName:String, parameters:Array<Dynamic>):Dynamic {
|
private override function onCall(funcName:String, parameters:Array<Dynamic>):Dynamic {
|
||||||
if (interp == null) return null;
|
if (interp == null) return null;
|
||||||
|
|
||||||
var func = interp.variables.get(funcName);
|
var func = interp.variables.get(funcName);
|
||||||
if (func != null && Reflect.isFunction(func))
|
if (func != null && Reflect.isFunction(func))
|
||||||
return (parameters != null && parameters.length > 0) ? Reflect.callMethod(null, func, parameters) : func();
|
return (parameters != null && parameters.length > 0) ? Reflect.callMethod(null, func, parameters) : func();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function get(val:String):Dynamic {
|
public override function get(val:String):Dynamic {
|
||||||
return interp.variables.get(val);
|
return interp.variables.get(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function set(val:String, value:Dynamic) {
|
public override function set(val:String, value:Dynamic) {
|
||||||
interp.variables.set(val, value);
|
interp.variables.set(val, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function trace(v:Dynamic) {
|
public override function trace(v:Dynamic) {
|
||||||
var posInfo = interp.posInfos();
|
var posInfo = interp.posInfos();
|
||||||
Logs.traceColored([
|
Logs.traceColored([
|
||||||
Logs.logText('${fileName}:${posInfo.lineNumber}: ', GREEN),
|
Logs.logText('${fileName}:${posInfo.lineNumber}: ', GREEN),
|
||||||
Logs.logText(Std.isOfType(v, String) ? v : Std.string(v))
|
Logs.logText(Std.isOfType(v, String) ? v : Std.string(v))
|
||||||
], TRACE);
|
], TRACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function setPublicMap(map:Map<String, Dynamic>) {
|
public override function setPublicMap(map:Map<String, Dynamic>) {
|
||||||
this.interp.publicVariables = map;
|
this.interp.publicVariables = map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package funkin.scripting;
|
package funkin.scripting;
|
||||||
|
|
||||||
class ModState extends MusicBeatState {
|
class ModState extends MusicBeatState {
|
||||||
public function new(stateName:String) {
|
public function new(stateName:String) {
|
||||||
super(true, stateName);
|
super(true, stateName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package funkin.scripting;
|
package funkin.scripting;
|
||||||
|
|
||||||
class ModSubState extends MusicBeatSubstate {
|
class ModSubState extends MusicBeatSubstate {
|
||||||
public function new(scriptName:String) {
|
public function new(scriptName:String) {
|
||||||
super(true, scriptName);
|
super(true, scriptName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,91 +8,91 @@ import hscript.IHScriptCustomBehaviour;
|
|||||||
import flixel.util.FlxDestroyUtil;
|
import flixel.util.FlxDestroyUtil;
|
||||||
|
|
||||||
class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour {
|
class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour {
|
||||||
var thread:#if ALLOW_MULTITHREADING Thread #else Dynamic #end;
|
var thread:#if ALLOW_MULTITHREADING Thread #else Dynamic #end;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Script being ran.
|
* Script being ran.
|
||||||
*/
|
*/
|
||||||
public var script:Script;
|
public var script:Script;
|
||||||
|
|
||||||
private var __variables:Array<String>;
|
private var __variables:Array<String>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return value of the last call.
|
* Return value of the last call.
|
||||||
*/
|
*/
|
||||||
public var returnValue:Dynamic = null;
|
public var returnValue:Dynamic = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever the current call has ended.
|
* Whenever the current call has ended.
|
||||||
*/
|
*/
|
||||||
public var callEnded:Bool = true;
|
public var callEnded:Bool = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function new(path:String, ?parentScript:Script) {
|
public function new(path:String, ?parentScript:Script) {
|
||||||
script = Script.create(path);
|
script = Script.create(path);
|
||||||
|
|
||||||
if (parentScript != null) {
|
if (parentScript != null) {
|
||||||
if (script is HScript && parentScript is HScript) {
|
if (script is HScript && parentScript is HScript) {
|
||||||
var hscript = cast(script, HScript);
|
var hscript = cast(script, HScript);
|
||||||
var parentHScript = cast(parentScript, HScript);
|
var parentHScript = cast(parentScript, HScript);
|
||||||
|
|
||||||
hscript.interp.variables = parentHScript.interp.variables;
|
hscript.interp.variables = parentHScript.interp.variables;
|
||||||
hscript.interp.publicVariables = parentHScript.interp.publicVariables;
|
hscript.interp.publicVariables = parentHScript.interp.publicVariables;
|
||||||
hscript.interp.staticVariables = parentHScript.interp.staticVariables;
|
hscript.interp.staticVariables = parentHScript.interp.staticVariables;
|
||||||
|
|
||||||
script.setParent(parentHScript.interp.scriptObject);
|
script.setParent(parentHScript.interp.scriptObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
script.load();
|
script.load();
|
||||||
|
|
||||||
#if ALLOW_MULTITHREADING
|
#if ALLOW_MULTITHREADING
|
||||||
thread = Thread.createWithEventLoop(function() {
|
thread = Thread.createWithEventLoop(function() {
|
||||||
// Prevent the thread from being auto deleted
|
// Prevent the thread from being auto deleted
|
||||||
Thread.current().events.promise();
|
Thread.current().events.promise();
|
||||||
});
|
});
|
||||||
#end
|
#end
|
||||||
|
|
||||||
__variables = Type.getInstanceFields(Type.getClass(this));
|
__variables = Type.getInstanceFields(Type.getClass(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline function hget(name:String):Dynamic
|
public inline function hget(name:String):Dynamic
|
||||||
return __variables.contains(name) ? Reflect.getProperty(this, name) : script.get(name);
|
return __variables.contains(name) ? Reflect.getProperty(this, name) : script.get(name);
|
||||||
|
|
||||||
public inline function hset(name:String, val:Dynamic):Dynamic {
|
public inline function hset(name:String, val:Dynamic):Dynamic {
|
||||||
if (__variables.contains(name))
|
if (__variables.contains(name))
|
||||||
Reflect.setProperty(this, name, val);
|
Reflect.setProperty(this, name, val);
|
||||||
else
|
else
|
||||||
script.set(name, val);
|
script.set(name, val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function call(func:String, args:Array<Dynamic>) {
|
public function call(func:String, args:Array<Dynamic>) {
|
||||||
#if ALLOW_MULTITHREADING
|
#if ALLOW_MULTITHREADING
|
||||||
thread.events.run(function() {
|
thread.events.run(function() {
|
||||||
callEnded = false;
|
callEnded = false;
|
||||||
returnValue = script.call(func, args);
|
returnValue = script.call(func, args);
|
||||||
callEnded = true;
|
callEnded = true;
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
returnValue = script.call(func, args);
|
returnValue = script.call(func, args);
|
||||||
callEnded = true;
|
callEnded = true;
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy() {
|
public function destroy() {
|
||||||
if (script != null) {
|
if (script != null) {
|
||||||
script.call("onDestroy");
|
script.call("onDestroy");
|
||||||
script.destroy();
|
script.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ALLOW_MULTITHREADING
|
#if ALLOW_MULTITHREADING
|
||||||
if (thread != null) {
|
if (thread != null) {
|
||||||
thread.events.runPromised(function() {
|
thread.events.runPromised(function() {
|
||||||
// close the thing
|
// close the thing
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+230
-230
@@ -8,266 +8,266 @@ import haxe.io.Path;
|
|||||||
* Class used for scripting.
|
* Class used for scripting.
|
||||||
*/
|
*/
|
||||||
class Script extends FlxBasic implements IFlxDestroyable {
|
class Script extends FlxBasic implements IFlxDestroyable {
|
||||||
/**
|
/**
|
||||||
* Use "static var thing = true;" in hscript to use those!!
|
* Use "static var thing = true;" in hscript to use those!!
|
||||||
* are reset every mod switch so once you're done with them make sure to make them null!!
|
* are reset every mod switch so once you're done with them make sure to make them null!!
|
||||||
*/
|
*/
|
||||||
public static var staticVariables:Map<String, Dynamic> = [];
|
public static var staticVariables:Map<String, Dynamic> = [];
|
||||||
|
|
||||||
|
|
||||||
public static function getDefaultVariables(?script:Script):Map<String, Dynamic> {
|
public static function getDefaultVariables(?script:Script):Map<String, Dynamic> {
|
||||||
return [
|
return [
|
||||||
// Haxe related stuff
|
// Haxe related stuff
|
||||||
"Std" => Std,
|
"Std" => Std,
|
||||||
"Math" => Math,
|
"Math" => Math,
|
||||||
"StringTools" => StringTools,
|
"StringTools" => StringTools,
|
||||||
"Json" => haxe.Json,
|
"Json" => haxe.Json,
|
||||||
|
|
||||||
// OpenFL & Lime related stuff
|
// OpenFL & Lime related stuff
|
||||||
"Assets" => openfl.utils.Assets,
|
"Assets" => openfl.utils.Assets,
|
||||||
"Application" => lime.app.Application,
|
"Application" => lime.app.Application,
|
||||||
"window" => lime.app.Application.current.window,
|
"window" => lime.app.Application.current.window,
|
||||||
|
|
||||||
// Flixel related stuff
|
// Flixel related stuff
|
||||||
"FlxG" => flixel.FlxG,
|
"FlxG" => flixel.FlxG,
|
||||||
"FlxSprite" => flixel.FlxSprite,
|
"FlxSprite" => flixel.FlxSprite,
|
||||||
"FlxBasic" => flixel.FlxBasic,
|
"FlxBasic" => flixel.FlxBasic,
|
||||||
"FlxCamera" => flixel.FlxCamera,
|
"FlxCamera" => flixel.FlxCamera,
|
||||||
"state" => flixel.FlxG.state,
|
"state" => flixel.FlxG.state,
|
||||||
"FlxEase" => flixel.tweens.FlxEase,
|
"FlxEase" => flixel.tweens.FlxEase,
|
||||||
"FlxTween" => flixel.tweens.FlxTween,
|
"FlxTween" => flixel.tweens.FlxTween,
|
||||||
"FlxSound" => flixel.system.FlxSound,
|
"FlxSound" => flixel.system.FlxSound,
|
||||||
"FlxAssets" => flixel.system.FlxAssets,
|
"FlxAssets" => flixel.system.FlxAssets,
|
||||||
"FlxMath" => flixel.math.FlxMath,
|
"FlxMath" => flixel.math.FlxMath,
|
||||||
"FlxGroup" => flixel.group.FlxGroup,
|
"FlxGroup" => flixel.group.FlxGroup,
|
||||||
"FlxTypedGroup" => flixel.group.FlxGroup.FlxTypedGroup,
|
"FlxTypedGroup" => flixel.group.FlxGroup.FlxTypedGroup,
|
||||||
"FlxSpriteGroup" => flixel.group.FlxSpriteGroup,
|
"FlxSpriteGroup" => flixel.group.FlxSpriteGroup,
|
||||||
"FlxTypeText" => flixel.addons.text.FlxTypeText,
|
"FlxTypeText" => flixel.addons.text.FlxTypeText,
|
||||||
"FlxText" => flixel.text.FlxText,
|
"FlxText" => flixel.text.FlxText,
|
||||||
"FlxTimer" => flixel.util.FlxTimer,
|
"FlxTimer" => flixel.util.FlxTimer,
|
||||||
"FlxPoint" => CoolUtil.getMacroAbstractClass("flixel.math.FlxPoint"),
|
"FlxPoint" => CoolUtil.getMacroAbstractClass("flixel.math.FlxPoint"),
|
||||||
"FlxAxes" => CoolUtil.getMacroAbstractClass("flixel.util.FlxAxes"),
|
"FlxAxes" => CoolUtil.getMacroAbstractClass("flixel.util.FlxAxes"),
|
||||||
"FlxColor" => CoolUtil.getMacroAbstractClass("flixel.util.FlxColor"),
|
"FlxColor" => CoolUtil.getMacroAbstractClass("flixel.util.FlxColor"),
|
||||||
|
|
||||||
// Engine related stuff
|
// Engine related stuff
|
||||||
"engine" => {
|
"engine" => {
|
||||||
commit: funkin.macros.GitCommitMacro.commitNumber,
|
commit: funkin.macros.GitCommitMacro.commitNumber,
|
||||||
build: 2675, // 2675 being the last build num before it was removed
|
build: 2675, // 2675 being the last build num before it was removed
|
||||||
name: "Codename Engine"
|
name: "Codename Engine"
|
||||||
},
|
},
|
||||||
"ModState" => funkin.scripting.ModState,
|
"ModState" => funkin.scripting.ModState,
|
||||||
"ModSubState" => funkin.scripting.ModSubState,
|
"ModSubState" => funkin.scripting.ModSubState,
|
||||||
"PlayState" => funkin.game.PlayState,
|
"PlayState" => funkin.game.PlayState,
|
||||||
"GameOverSubstate" => funkin.game.GameOverSubstate,
|
"GameOverSubstate" => funkin.game.GameOverSubstate,
|
||||||
"HealthIcon" => funkin.game.HealthIcon,
|
"HealthIcon" => funkin.game.HealthIcon,
|
||||||
"HudCamera" => funkin.game.HudCamera,
|
"HudCamera" => funkin.game.HudCamera,
|
||||||
"Note" => funkin.game.Note,
|
"Note" => funkin.game.Note,
|
||||||
"Strum" => funkin.game.Strum,
|
"Strum" => funkin.game.Strum,
|
||||||
"StrumLine" => funkin.game.StrumLine,
|
"StrumLine" => funkin.game.StrumLine,
|
||||||
"Character" => funkin.game.Character,
|
"Character" => funkin.game.Character,
|
||||||
"Boyfriend" => funkin.game.Character, // for compatibility
|
"Boyfriend" => funkin.game.Character, // for compatibility
|
||||||
"PauseSubstate" => funkin.menus.PauseSubState,
|
"PauseSubstate" => funkin.menus.PauseSubState,
|
||||||
"FreeplayState" => funkin.menus.FreeplayState,
|
"FreeplayState" => funkin.menus.FreeplayState,
|
||||||
"MainMenuState" => funkin.menus.MainMenuState,
|
"MainMenuState" => funkin.menus.MainMenuState,
|
||||||
"PauseSubState" => funkin.menus.PauseSubState,
|
"PauseSubState" => funkin.menus.PauseSubState,
|
||||||
"StoryMenuState" => funkin.menus.StoryMenuState,
|
"StoryMenuState" => funkin.menus.StoryMenuState,
|
||||||
"TitleState" => funkin.menus.TitleState,
|
"TitleState" => funkin.menus.TitleState,
|
||||||
"Options" => funkin.options.Options,
|
"Options" => funkin.options.Options,
|
||||||
"Paths" => funkin.system.Paths,
|
"Paths" => funkin.system.Paths,
|
||||||
"Conductor" => funkin.system.Conductor,
|
"Conductor" => funkin.system.Conductor,
|
||||||
"FunkinShader" => funkin.shaders.FunkinShader,
|
"FunkinShader" => funkin.shaders.FunkinShader,
|
||||||
"CustomShader" => funkin.shaders.CustomShader,
|
"CustomShader" => funkin.shaders.CustomShader,
|
||||||
"FunkinText" => funkin.ui.FunkinText,
|
"FunkinText" => funkin.ui.FunkinText,
|
||||||
"Alphabet" => funkin.ui.Alphabet,
|
"Alphabet" => funkin.ui.Alphabet,
|
||||||
|
|
||||||
"CoolUtil" => funkin.utils.CoolUtil,
|
"CoolUtil" => funkin.utils.CoolUtil,
|
||||||
"IniUtil" => funkin.utils.IniUtil,
|
"IniUtil" => funkin.utils.IniUtil,
|
||||||
"XMLUtil" => funkin.utils.XMLUtil,
|
"XMLUtil" => funkin.utils.XMLUtil,
|
||||||
#if sys "ZipUtil" => funkin.utils.ZipUtil, #end
|
#if sys "ZipUtil" => funkin.utils.ZipUtil, #end
|
||||||
"MarkdownUtil" => funkin.utils.MarkdownUtil,
|
"MarkdownUtil" => funkin.utils.MarkdownUtil,
|
||||||
"EngineUtil" => funkin.utils.EngineUtil,
|
"EngineUtil" => funkin.utils.EngineUtil,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
public static function getDefaultPreprocessors():Map<String, Dynamic> {
|
public static function getDefaultPreprocessors():Map<String, Dynamic> {
|
||||||
return [
|
return [
|
||||||
"CODENAME_ENGINE" => true,
|
"CODENAME_ENGINE" => true,
|
||||||
"CODENAME_VER" => Application.current.meta.get('version'),
|
"CODENAME_VER" => Application.current.meta.get('version'),
|
||||||
"CODENAME_BUILD" => 2675,
|
"CODENAME_BUILD" => 2675,
|
||||||
"CODENAME_COMMIT" => funkin.macros.GitCommitMacro.commitNumber,
|
"CODENAME_COMMIT" => funkin.macros.GitCommitMacro.commitNumber,
|
||||||
"desktop" => #if desktop true #else false #end,
|
"desktop" => #if desktop true #else false #end,
|
||||||
"windows" => #if windows true #else false #end,
|
"windows" => #if windows true #else false #end,
|
||||||
"hl" => #if hl true #else false #end,
|
"hl" => #if hl true #else false #end,
|
||||||
"neko" => #if neko true #else false #end,
|
"neko" => #if neko true #else false #end,
|
||||||
"linux" => #if linux true #else false #end,
|
"linux" => #if linux true #else false #end,
|
||||||
"mac" => #if mac true #else false #end,
|
"mac" => #if mac true #else false #end,
|
||||||
"macos" => #if macos true #else false #end,
|
"macos" => #if macos true #else false #end,
|
||||||
"android" => #if android true #else false #end,
|
"android" => #if android true #else false #end,
|
||||||
"web" => #if web true #else false #end,
|
"web" => #if web true #else false #end,
|
||||||
"debug" => #if debug true #else false #end,
|
"debug" => #if debug true #else false #end,
|
||||||
"release" => #if release true #else false #end,
|
"release" => #if release true #else false #end,
|
||||||
"final" => #if final true #else false #end,
|
"final" => #if final true #else false #end,
|
||||||
"MOD_SUPPORT" => #if MOD_SUPPORT true #else false #end,
|
"MOD_SUPPORT" => #if MOD_SUPPORT true #else false #end,
|
||||||
"GLOBAL_SCRIPT" => #if GLOBAL_SCRIPT true #else false #end,
|
"GLOBAL_SCRIPT" => #if GLOBAL_SCRIPT true #else false #end,
|
||||||
"SOFTCODED_STATES" => #if SOFTCODED_STATES true #else false #end,
|
"SOFTCODED_STATES" => #if SOFTCODED_STATES true #else false #end,
|
||||||
"USE_SOURCE_ASSETS" => #if USE_SOURCE_ASSETS true #else false #end,
|
"USE_SOURCE_ASSETS" => #if USE_SOURCE_ASSETS true #else false #end,
|
||||||
"USE_ADAPTED_ASSETS" => #if USE_ADAPTED_ASSETS true #else false #end,
|
"USE_ADAPTED_ASSETS" => #if USE_ADAPTED_ASSETS true #else false #end,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* All available script extensions
|
* All available script extensions
|
||||||
*/
|
*/
|
||||||
public static var scriptExtensions:Array<String> = [
|
public static var scriptExtensions:Array<String> = [
|
||||||
"hx", "hscript", "hsc", "hxs", "lua" /** ACTUALLY NOT SUPPORTED, ONLY FOR THE MESSAGE **/
|
"hx", "hscript", "hsc", "hxs", "lua" /** ACTUALLY NOT SUPPORTED, ONLY FOR THE MESSAGE **/
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently executing script.
|
* Currently executing script.
|
||||||
*/
|
*/
|
||||||
public static var curScript:Script = null;
|
public static var curScript:Script = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Script name (with extension)
|
* Script name (with extension)
|
||||||
*/
|
*/
|
||||||
public var fileName:String;
|
public var fileName:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path to the script.
|
* Path to the script.
|
||||||
*/
|
*/
|
||||||
public var path:String = null;
|
public var path:String = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a script from the specified asset path. The language is automatically determined.
|
* Creates a script from the specified asset path. The language is automatically determined.
|
||||||
* @param path Path in assets
|
* @param path Path in assets
|
||||||
*/
|
*/
|
||||||
public static function create(path:String):Script {
|
public static function create(path:String):Script {
|
||||||
if (Assets.exists(path)) {
|
if (Assets.exists(path)) {
|
||||||
return switch(Path.extension(path).toLowerCase()) {
|
return switch(Path.extension(path).toLowerCase()) {
|
||||||
case "hx" | "hscript" | "hsc" | "hxs":
|
case "hx" | "hscript" | "hsc" | "hxs":
|
||||||
new HScript(path);
|
new HScript(path);
|
||||||
case "lua":
|
case "lua":
|
||||||
Logs.trace("Lua is not supported in this engine. Use HScript instead.", ERROR);
|
Logs.trace("Lua is not supported in this engine. Use HScript instead.", ERROR);
|
||||||
new DummyScript(path);
|
new DummyScript(path);
|
||||||
default:
|
default:
|
||||||
new DummyScript(path);
|
new DummyScript(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new DummyScript(path);
|
return new DummyScript(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of the script class.
|
* Creates a new instance of the script class.
|
||||||
* @param path
|
* @param path
|
||||||
*/
|
*/
|
||||||
public function new(path:String) {
|
public function new(path:String) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
fileName = Path.withoutDirectory(path);
|
fileName = Path.withoutDirectory(path);
|
||||||
this.path = path;
|
this.path = path;
|
||||||
onCreate(path);
|
onCreate(path);
|
||||||
for(k=>e in getDefaultVariables(this)) {
|
for(k=>e in getDefaultVariables(this)) {
|
||||||
set(k, e);
|
set(k, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the script
|
* Loads the script
|
||||||
*/
|
*/
|
||||||
public function load() {
|
public function load() {
|
||||||
var oldScript = curScript;
|
var oldScript = curScript;
|
||||||
curScript = this;
|
curScript = this;
|
||||||
onLoad();
|
onLoad();
|
||||||
curScript = oldScript;
|
curScript = oldScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HSCRIPT ONLY FOR NOW
|
* HSCRIPT ONLY FOR NOW
|
||||||
* Sets the "public" variables map for ScriptPack
|
* Sets the "public" variables map for ScriptPack
|
||||||
*/
|
*/
|
||||||
public function setPublicMap(map:Map<String, Dynamic>) {
|
public function setPublicMap(map:Map<String, Dynamic>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hot-reloads the script, if possible
|
* Hot-reloads the script, if possible
|
||||||
*/
|
*/
|
||||||
public function reload() {
|
public function reload() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traces something as this script.
|
* Traces something as this script.
|
||||||
*/
|
*/
|
||||||
public function trace(v:Dynamic) {
|
public function trace(v:Dynamic) {
|
||||||
Logs.traceColored([
|
Logs.traceColored([
|
||||||
Logs.logText('${fileName}: ', GREEN),
|
Logs.logText('${fileName}: ', GREEN),
|
||||||
Logs.logText(Std.string(v))
|
Logs.logText(Std.string(v))
|
||||||
], TRACE);
|
], TRACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the function `func` defined in the script.
|
* Calls the function `func` defined in the script.
|
||||||
* @param func Name of the function
|
* @param func Name of the function
|
||||||
* @param parameters (Optional) Parameters of the function.
|
* @param parameters (Optional) Parameters of the function.
|
||||||
* @return Result (if void, then null)
|
* @return Result (if void, then null)
|
||||||
*/
|
*/
|
||||||
public function call(func:String, ?parameters:Array<Dynamic>):Dynamic {
|
public function call(func:String, ?parameters:Array<Dynamic>):Dynamic {
|
||||||
var oldScript = curScript;
|
var oldScript = curScript;
|
||||||
curScript = this;
|
curScript = this;
|
||||||
|
|
||||||
var result = onCall(func, parameters == null ? [] : parameters);
|
var result = onCall(func, parameters == null ? [] : parameters);
|
||||||
|
|
||||||
curScript = oldScript;
|
curScript = oldScript;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a script's parent object so that its properties can be accessed easily. Ex: Passing `PlayState.instance` will allow `boyfriend` to be typed instead of `PlayState.instance.boyfriend`.
|
* Sets a script's parent object so that its properties can be accessed easily. Ex: Passing `PlayState.instance` will allow `boyfriend` to be typed instead of `PlayState.instance.boyfriend`.
|
||||||
* @param variable Parent variable.
|
* @param variable Parent variable.
|
||||||
*/
|
*/
|
||||||
public function setParent(variable:Dynamic) {}
|
public function setParent(variable:Dynamic) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the variable `variable` from the script's variables.
|
* Gets the variable `variable` from the script's variables.
|
||||||
* @param variable Name of the variable.
|
* @param variable Name of the variable.
|
||||||
* @return Variable (or null if it doesn't exists)
|
* @return Variable (or null if it doesn't exists)
|
||||||
*/
|
*/
|
||||||
public function get(variable:String):Dynamic {return null;}
|
public function get(variable:String):Dynamic {return null;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the variable `variable` from the script's variables.
|
* Gets the variable `variable` from the script's variables.
|
||||||
* @param variable Name of the variable.
|
* @param variable Name of the variable.
|
||||||
* @return Variable (or null if it doesn't exists)
|
* @return Variable (or null if it doesn't exists)
|
||||||
*/
|
*/
|
||||||
public function set(variable:String, value:Dynamic):Void {}
|
public function set(variable:String, value:Dynamic):Void {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows an error from this script.
|
* Shows an error from this script.
|
||||||
* @param text Text of the error (ex: Null Object Reference).
|
* @param text Text of the error (ex: Null Object Reference).
|
||||||
* @param additionalInfo Additional information you could provide.
|
* @param additionalInfo Additional information you could provide.
|
||||||
*/
|
*/
|
||||||
public function error(text:String, ?additionalInfo:Dynamic):Void {
|
public function error(text:String, ?additionalInfo:Dynamic):Void {
|
||||||
Logs.traceColored([
|
Logs.traceColored([
|
||||||
Logs.logText(fileName, RED),
|
Logs.logText(fileName, RED),
|
||||||
Logs.logText(text)
|
Logs.logText(text)
|
||||||
], ERROR);
|
], ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PRIVATE HANDLERS - DO NOT TOUCH
|
* PRIVATE HANDLERS - DO NOT TOUCH
|
||||||
*/
|
*/
|
||||||
private function onCall(func:String, parameters:Array<Dynamic>):Dynamic {
|
private function onCall(func:String, parameters:Array<Dynamic>):Dynamic {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public function onCreate(path:String) {}
|
public function onCreate(path:String) {}
|
||||||
|
|
||||||
public function onLoad() {}
|
public function onLoad() {}
|
||||||
|
|
||||||
public function onDestroy() {};
|
public function onDestroy() {};
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
onDestroy();
|
onDestroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,117 +4,117 @@ import funkin.scripting.events.CancellableEvent;
|
|||||||
|
|
||||||
@:access(CancellableEvent)
|
@:access(CancellableEvent)
|
||||||
class ScriptPack extends Script {
|
class ScriptPack extends Script {
|
||||||
public var scripts:Array<Script> = [];
|
public var scripts:Array<Script> = [];
|
||||||
public var additionalDefaultVariables:Map<String, Dynamic> = [];
|
public var additionalDefaultVariables:Map<String, Dynamic> = [];
|
||||||
public var publicVariables:Map<String, Dynamic> = [];
|
public var publicVariables:Map<String, Dynamic> = [];
|
||||||
public var parent:Dynamic = null;
|
public var parent:Dynamic = null;
|
||||||
|
|
||||||
public override function load() {
|
public override function load() {
|
||||||
for(e in scripts) {
|
for(e in scripts) {
|
||||||
e.load();
|
e.load();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contains(path:String) {
|
public function contains(path:String) {
|
||||||
for(e in scripts)
|
for(e in scripts)
|
||||||
if (e.path == path)
|
if (e.path == path)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public function new(name:String) {
|
public function new(name:String) {
|
||||||
additionalDefaultVariables["importScript"] = importScript;
|
additionalDefaultVariables["importScript"] = importScript;
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByPath(name:String) {
|
public function getByPath(name:String) {
|
||||||
for(s in scripts)
|
for(s in scripts)
|
||||||
if (s.path == name)
|
if (s.path == name)
|
||||||
return s;
|
return s;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByName(name:String) {
|
public function getByName(name:String) {
|
||||||
for(s in scripts)
|
for(s in scripts)
|
||||||
if (s.fileName == name)
|
if (s.fileName == name)
|
||||||
return s;
|
return s;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public function importScript(path:String):Script {
|
public function importScript(path:String):Script {
|
||||||
var script = Script.create(Paths.script(path));
|
var script = Script.create(Paths.script(path));
|
||||||
if (script is DummyScript) {
|
if (script is DummyScript) {
|
||||||
throw 'Script at ${path} does not exist.';
|
throw 'Script at ${path} does not exist.';
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
add(script);
|
add(script);
|
||||||
script.load();
|
script.load();
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function call(func:String, ?parameters:Array<Dynamic>):Dynamic {
|
public override function call(func:String, ?parameters:Array<Dynamic>):Dynamic {
|
||||||
for(e in scripts)
|
for(e in scripts)
|
||||||
e.call(func, parameters);
|
e.call(func, parameters);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an event to every single script, and returns the event.
|
* Sends an event to every single script, and returns the event.
|
||||||
* @param func Function to call
|
* @param func Function to call
|
||||||
* @param event Event (will be the first parameter of the function)
|
* @param event Event (will be the first parameter of the function)
|
||||||
* @return (modified by scripts)
|
* @return (modified by scripts)
|
||||||
*/
|
*/
|
||||||
public function event<T:CancellableEvent>(func:String, event:T):T {
|
public function event<T:CancellableEvent>(func:String, event:T):T {
|
||||||
for(e in scripts) {
|
for(e in scripts) {
|
||||||
e.call(func, [event]);
|
e.call(func, [event]);
|
||||||
@:privateAccess
|
@:privateAccess
|
||||||
if (event.cancelled && !event.__continueCalls) break;
|
if (event.cancelled && !event.__continueCalls) break;
|
||||||
}
|
}
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function get(val:String):Dynamic {
|
public override function get(val:String):Dynamic {
|
||||||
for(e in scripts) {
|
for(e in scripts) {
|
||||||
var v = e.get(val);
|
var v = e.get(val);
|
||||||
if (v != null) return v;
|
if (v != null) return v;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function reload() {
|
public override function reload() {
|
||||||
for(e in scripts) e.reload();
|
for(e in scripts) e.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function set(val:String, value:Dynamic) {
|
public override function set(val:String, value:Dynamic) {
|
||||||
for(e in scripts) e.set(val, value);
|
for(e in scripts) e.set(val, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function setParent(parent:Dynamic) {
|
public override function setParent(parent:Dynamic) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
for(e in scripts) e.setParent(parent);
|
for(e in scripts) e.setParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function onDestroy() {
|
public override function onDestroy() {
|
||||||
for(e in scripts) e.destroy();
|
for(e in scripts) e.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function onCreate(path:String) {}
|
public override function onCreate(path:String) {}
|
||||||
|
|
||||||
public function add(script:Script) {
|
public function add(script:Script) {
|
||||||
scripts.push(script);
|
scripts.push(script);
|
||||||
__configureNewScript(script);
|
__configureNewScript(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function remove(script:Script) {
|
public function remove(script:Script) {
|
||||||
scripts.remove(script);
|
scripts.remove(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function insert(pos:Int, script:Script) {
|
public function insert(pos:Int, script:Script) {
|
||||||
scripts.insert(pos, script);
|
scripts.insert(pos, script);
|
||||||
__configureNewScript(script);
|
__configureNewScript(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function __configureNewScript(script:Script) {
|
private function __configureNewScript(script:Script) {
|
||||||
if (parent != null) script.setParent(parent);
|
if (parent != null) script.setParent(parent);
|
||||||
script.setPublicMap(publicVariables);
|
script.setPublicMap(publicVariables);
|
||||||
for(k=>e in additionalDefaultVariables) script.set(k, e);
|
for(k=>e in additionalDefaultVariables) script.set(k, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,18 +4,18 @@ import funkin.game.StrumLine;
|
|||||||
import flixel.math.FlxPoint;
|
import flixel.math.FlxPoint;
|
||||||
|
|
||||||
class CamMoveEvent extends CancellableEvent {
|
class CamMoveEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Final camera position.
|
* Final camera position.
|
||||||
*/
|
*/
|
||||||
public var position:FlxPoint;
|
public var position:FlxPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently focused strumline.
|
* Currently focused strumline.
|
||||||
*/
|
*/
|
||||||
public var strumLine:StrumLine;
|
public var strumLine:StrumLine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of focused characters
|
* Number of focused characters
|
||||||
*/
|
*/
|
||||||
public var focusedCharacters:Int;
|
public var focusedCharacters:Int;
|
||||||
}
|
}
|
||||||
@@ -5,52 +5,52 @@ import flixel.util.FlxDestroyUtil.IFlxDestroyable;
|
|||||||
@:allow(ScriptPack)
|
@:allow(ScriptPack)
|
||||||
@:autoBuild(funkin.macros.EventMacro.build())
|
@:autoBuild(funkin.macros.EventMacro.build())
|
||||||
class CancellableEvent implements IFlxDestroyable {
|
class CancellableEvent implements IFlxDestroyable {
|
||||||
@:dox(hide) public var cancelled:Bool = false;
|
@:dox(hide) public var cancelled:Bool = false;
|
||||||
@:dox(hide) private var __continueCalls:Bool = true;
|
@:dox(hide) private var __continueCalls:Bool = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Additional data if used in scripts
|
* Additional data if used in scripts
|
||||||
*/
|
*/
|
||||||
public var data:Dynamic = {};
|
public var data:Dynamic = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents default action from occurring.
|
* Prevents default action from occurring.
|
||||||
* @param c Whenever the scripts following this one should be called or not. (Defaults to `true`)
|
* @param c Whenever the scripts following this one should be called or not. (Defaults to `true`)
|
||||||
*/
|
*/
|
||||||
public function preventDefault(c:Bool = false) {
|
public function preventDefault(c:Bool = false) {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
__continueCalls = c;
|
__continueCalls = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
public function cancel(c:Bool = true) {preventDefault(c);}
|
public function cancel(c:Bool = true) {preventDefault(c);}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new cancellable event.
|
* Creates a new cancellable event.
|
||||||
* This allows scripts to call `cancel()` to cancel the event.
|
* This allows scripts to call `cancel()` to cancel the event.
|
||||||
*/
|
*/
|
||||||
public function new() {}
|
public function new() {}
|
||||||
|
|
||||||
public function recycleBase() {
|
public function recycleBase() {
|
||||||
data = {};
|
data = {};
|
||||||
cancelled = false;
|
cancelled = false;
|
||||||
__continueCalls = true;
|
__continueCalls = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string representation of the event, in this format:
|
* Returns a string representation of the event, in this format:
|
||||||
* `[CancellableEvent]`
|
* `[CancellableEvent]`
|
||||||
* `[CancellableEvent (Cancelled)]`
|
* `[CancellableEvent (Cancelled)]`
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public function toString():String {
|
public function toString():String {
|
||||||
var fields = Reflect.fields(this);
|
var fields = Reflect.fields(this);
|
||||||
var claName = Type.getClassName(Type.getClass(this)).split(".");
|
var claName = Type.getClassName(Type.getClass(this)).split(".");
|
||||||
var rep = '[${claName[claName.length-1]}${cancelled ? " (Cancelled)" : ""}]';
|
var rep = '[${claName[claName.length-1]}${cancelled ? " (Cancelled)" : ""}]';
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy() {
|
public function destroy() {
|
||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,42 +4,42 @@ import flixel.tweens.FlxTween;
|
|||||||
import flixel.system.FlxSound;
|
import flixel.system.FlxSound;
|
||||||
|
|
||||||
class CountdownEvent extends CancellableEvent {
|
class CountdownEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* At which count the countdown is. Normally goes 0-1-2-3-4 unless `PlayState.instance.introLength` is changed.
|
* At which count the countdown is. Normally goes 0-1-2-3-4 unless `PlayState.instance.introLength` is changed.
|
||||||
*/
|
*/
|
||||||
public var swagCounter:Int;
|
public var swagCounter:Int;
|
||||||
/**
|
/**
|
||||||
* Volume at which the intro countdown sound will play.
|
* Volume at which the intro countdown sound will play.
|
||||||
*/
|
*/
|
||||||
public var volume:Float;
|
public var volume:Float;
|
||||||
/**
|
/**
|
||||||
* Path of the intro sound that'll be played.
|
* Path of the intro sound that'll be played.
|
||||||
*/
|
*/
|
||||||
public var soundPath:String;
|
public var soundPath:String;
|
||||||
/**
|
/**
|
||||||
* Path to the sprite path that'll be shown.
|
* Path to the sprite path that'll be shown.
|
||||||
*/
|
*/
|
||||||
public var spritePath:String;
|
public var spritePath:String;
|
||||||
/**
|
/**
|
||||||
* Scale of the sprite.
|
* Scale of the sprite.
|
||||||
*/
|
*/
|
||||||
public var scale:Float;
|
public var scale:Float;
|
||||||
/**
|
/**
|
||||||
* Whenever antialiasing is enabled or not.
|
* Whenever antialiasing is enabled or not.
|
||||||
*/
|
*/
|
||||||
public var antialiasing:Bool;
|
public var antialiasing:Bool;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created sprite, only available in `onPostCountdown`
|
* Created sprite, only available in `onPostCountdown`
|
||||||
*/
|
*/
|
||||||
public var sprite:FlxSprite;
|
public var sprite:FlxSprite;
|
||||||
/**
|
/**
|
||||||
* Created tween for the sprite, only available in `onPostCountdown`
|
* Created tween for the sprite, only available in `onPostCountdown`
|
||||||
*/
|
*/
|
||||||
public var spriteTween:FlxTween;
|
public var spriteTween:FlxTween;
|
||||||
/**
|
/**
|
||||||
* Created sound, only available in `onPostCountdown`
|
* Created sound, only available in `onPostCountdown`
|
||||||
*/
|
*/
|
||||||
public var sound:FlxSound;
|
public var sound:FlxSound;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
package funkin.scripting.events;
|
package funkin.scripting.events;
|
||||||
|
|
||||||
class DanceEvent extends CancellableEvent {
|
class DanceEvent extends CancellableEvent {
|
||||||
public var danced:Bool;
|
public var danced:Bool;
|
||||||
}
|
}
|
||||||
@@ -3,32 +3,32 @@ package funkin.scripting.events;
|
|||||||
import funkin.scripting.events.PlayAnimEvent.PlayAnimContext;
|
import funkin.scripting.events.PlayAnimEvent.PlayAnimContext;
|
||||||
|
|
||||||
class DirectionAnimEvent extends CancellableEvent {
|
class DirectionAnimEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
Default animation that will be played
|
Default animation that will be played
|
||||||
**/
|
**/
|
||||||
public var animName:String;
|
public var animName:String;
|
||||||
/**
|
/**
|
||||||
In which direction the animation will be played
|
In which direction the animation will be played
|
||||||
**/
|
**/
|
||||||
public var direction:Int;
|
public var direction:Int;
|
||||||
/**
|
/**
|
||||||
The suffix of the animation (ex: "-alt") - Defaults to ""
|
The suffix of the animation (ex: "-alt") - Defaults to ""
|
||||||
**/
|
**/
|
||||||
public var suffix:String;
|
public var suffix:String;
|
||||||
/**
|
/**
|
||||||
Context of the animation. Is either equal to `SING` or `MISS`.
|
Context of the animation. Is either equal to `SING` or `MISS`.
|
||||||
**/
|
**/
|
||||||
public var context:PlayAnimContext;
|
public var context:PlayAnimContext;
|
||||||
/**
|
/**
|
||||||
Whenever the animation will play reversed or not.
|
Whenever the animation will play reversed or not.
|
||||||
**/
|
**/
|
||||||
public var reversed:Bool;
|
public var reversed:Bool;
|
||||||
/**
|
/**
|
||||||
At what frame the animation will start playing
|
At what frame the animation will start playing
|
||||||
**/
|
**/
|
||||||
public var frame:Int;
|
public var frame:Int;
|
||||||
/**
|
/**
|
||||||
Whenever the animation will play reversed or not.
|
Whenever the animation will play reversed or not.
|
||||||
**/
|
**/
|
||||||
public var force:Bool = true;
|
public var force:Bool = true;
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,8 @@ import discord_rpc.DiscordRpc.DiscordPresenceOptions;
|
|||||||
#end
|
#end
|
||||||
|
|
||||||
class DiscordPresenceUpdateEvent extends CancellableEvent {
|
class DiscordPresenceUpdateEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Object containing all of the data for the presence. Can be altered.
|
* Object containing all of the data for the presence. Can be altered.
|
||||||
*/
|
*/
|
||||||
public var presenceData:#if DISCORD_RPC DiscordPresenceOptions #else Dynamic #end;
|
public var presenceData:#if DISCORD_RPC DiscordPresenceOptions #else Dynamic #end;
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
package funkin.scripting.events;
|
package funkin.scripting.events;
|
||||||
|
|
||||||
class FreeplaySongSelectEvent extends CancellableEvent {
|
class FreeplaySongSelectEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Song name that is about to be played
|
* Song name that is about to be played
|
||||||
*/
|
*/
|
||||||
public var song:String;
|
public var song:String;
|
||||||
/**
|
/**
|
||||||
* Difficulty name
|
* Difficulty name
|
||||||
*/
|
*/
|
||||||
public var difficulty:String;
|
public var difficulty:String;
|
||||||
/**
|
/**
|
||||||
* Whenever opponent mode is enabled or not.
|
* Whenever opponent mode is enabled or not.
|
||||||
*/
|
*/
|
||||||
public var opponentMode:Bool;
|
public var opponentMode:Bool;
|
||||||
/**
|
/**
|
||||||
* Whenever coop mode is enabled.
|
* Whenever coop mode is enabled.
|
||||||
*/
|
*/
|
||||||
public var coopMode:Bool;
|
public var coopMode:Bool;
|
||||||
}
|
}
|
||||||
@@ -3,31 +3,31 @@ package funkin.scripting.events;
|
|||||||
import funkin.game.StrumLine;
|
import funkin.game.StrumLine;
|
||||||
|
|
||||||
class InputSystemEvent extends CancellableEvent {
|
class InputSystemEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Array containing whenever a specific control is pressed or not.
|
* Array containing whenever a specific control is pressed or not.
|
||||||
* For example, `pressed[0]` will return whenever the left strum was pressed.
|
* For example, `pressed[0]` will return whenever the left strum was pressed.
|
||||||
*/
|
*/
|
||||||
public var pressed:Array<Bool>;
|
public var pressed:Array<Bool>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array containing whenever a specific control was pressed (not hold) this frame or not.
|
* Array containing whenever a specific control was pressed (not hold) this frame or not.
|
||||||
* For example, `justPressed[0]` will return whenever the left strum was just pressed.
|
* For example, `justPressed[0]` will return whenever the left strum was just pressed.
|
||||||
*/
|
*/
|
||||||
public var justPressed:Array<Bool>;
|
public var justPressed:Array<Bool>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array containing whenever a specific control was released this frame or not.
|
* Array containing whenever a specific control was released this frame or not.
|
||||||
* For example, `justReleased[0]` will return whenever the left strum was just released.
|
* For example, `justReleased[0]` will return whenever the left strum was just released.
|
||||||
*/
|
*/
|
||||||
public var justReleased:Array<Bool>;
|
public var justReleased:Array<Bool>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strumline which input is being processed.
|
* Strumline which input is being processed.
|
||||||
*/
|
*/
|
||||||
public var strumLine:StrumLine;
|
public var strumLine:StrumLine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the Strumline.
|
* ID of the Strumline.
|
||||||
*/
|
*/
|
||||||
public var strumLineID:Int;
|
public var strumLineID:Int;
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
package funkin.scripting.events;
|
package funkin.scripting.events;
|
||||||
|
|
||||||
class MenuChangeEvent extends CancellableEvent {
|
class MenuChangeEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Value before the change
|
* Value before the change
|
||||||
*/
|
*/
|
||||||
public var oldValue:Int;
|
public var oldValue:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value after the change
|
* Value after the change
|
||||||
*/
|
*/
|
||||||
public var value:Int;
|
public var value:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Amount of change
|
* Amount of change
|
||||||
*/
|
*/
|
||||||
public var change:Int;
|
public var change:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever the menu SFX should be played.
|
* Whenever the menu SFX should be played.
|
||||||
*/
|
*/
|
||||||
public var playMenuSFX:Bool = true;
|
public var playMenuSFX:Bool = true;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package funkin.scripting.events;
|
package funkin.scripting.events;
|
||||||
|
|
||||||
class NameEvent extends CancellableEvent {
|
class NameEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Name
|
* Name
|
||||||
*/
|
*/
|
||||||
public var name:String;
|
public var name:String;
|
||||||
}
|
}
|
||||||
@@ -3,48 +3,48 @@ package funkin.scripting.events;
|
|||||||
import funkin.game.Note;
|
import funkin.game.Note;
|
||||||
|
|
||||||
class NoteCreationEvent extends CancellableEvent {
|
class NoteCreationEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Note that is being created
|
* Note that is being created
|
||||||
*/
|
*/
|
||||||
public var note:Note;
|
public var note:Note;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the strum (from 0 to 3)
|
* ID of the strum (from 0 to 3)
|
||||||
*/
|
*/
|
||||||
public var strumID:Int;
|
public var strumID:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note Type (ex: "My Super Cool Note", or "Mine")
|
* Note Type (ex: "My Super Cool Note", or "Mine")
|
||||||
*/
|
*/
|
||||||
public var noteType:String;
|
public var noteType:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the note type.
|
* ID of the note type.
|
||||||
*/
|
*/
|
||||||
public var noteTypeID:Int;
|
public var noteTypeID:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the player.
|
* ID of the player.
|
||||||
*/
|
*/
|
||||||
public var strumLineID:Int;
|
public var strumLineID:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever the note will need to be hit by the player
|
* Whenever the note will need to be hit by the player
|
||||||
*/
|
*/
|
||||||
public var mustHit:Bool;
|
public var mustHit:Bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note sprite, if you only want to replace the sprite.
|
* Note sprite, if you only want to replace the sprite.
|
||||||
*/
|
*/
|
||||||
public var noteSprite:String;
|
public var noteSprite:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note scale, if you only want to replace the scale.
|
* Note scale, if you only want to replace the scale.
|
||||||
*/
|
*/
|
||||||
public var noteScale:Float;
|
public var noteScale:Float;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sing animation suffix. "-alt" for alt anim or "" for normal notes.
|
* Sing animation suffix. "-alt" for alt anim or "" for normal notes.
|
||||||
*/
|
*/
|
||||||
public var animSuffix:String;
|
public var animSuffix:String;
|
||||||
}
|
}
|
||||||
@@ -4,170 +4,170 @@ import funkin.game.Note;
|
|||||||
import funkin.game.Character;
|
import funkin.game.Character;
|
||||||
|
|
||||||
class NoteHitEvent extends CancellableEvent {
|
class NoteHitEvent extends CancellableEvent {
|
||||||
@:dox(hide) public var animCancelled:Bool = false;
|
@:dox(hide) public var animCancelled:Bool = false;
|
||||||
@:dox(hide) public var strumGlowCancelled:Bool = false;
|
@:dox(hide) public var strumGlowCancelled:Bool = false;
|
||||||
@:dox(hide) public var deleteNote:Bool = true;
|
@:dox(hide) public var deleteNote:Bool = true;
|
||||||
@:dox(hide) public var unmuteVocals:Bool = true;
|
@:dox(hide) public var unmuteVocals:Bool = true;
|
||||||
@:dox(hide) public var enableCamZooming:Bool = true;
|
@:dox(hide) public var enableCamZooming:Bool = true;
|
||||||
@:dox(hide) public var autoHitLastSustain:Bool = true;
|
@:dox(hide) public var autoHitLastSustain:Bool = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever a miss should be added.
|
* Whenever a miss should be added.
|
||||||
*/
|
*/
|
||||||
public var misses:Bool = true;
|
public var misses:Bool = true;
|
||||||
/**
|
/**
|
||||||
* Whenever a miss should be added.
|
* Whenever a miss should be added.
|
||||||
*/
|
*/
|
||||||
public var countAsCombo:Bool = true;
|
public var countAsCombo:Bool = true;
|
||||||
/**
|
/**
|
||||||
* Whenever ratings should be shown or not.
|
* Whenever ratings should be shown or not.
|
||||||
*/
|
*/
|
||||||
public var showRating:Null<Bool> = null;
|
public var showRating:Null<Bool> = null;
|
||||||
/**
|
/**
|
||||||
* Note that has been pressed
|
* Note that has been pressed
|
||||||
*/
|
*/
|
||||||
public var note:Note;
|
public var note:Note;
|
||||||
/**
|
/**
|
||||||
* Character that pressed the note.
|
* Character that pressed the note.
|
||||||
*/
|
*/
|
||||||
public var character(get, set):Character;
|
public var character(get, set):Character;
|
||||||
/**
|
/**
|
||||||
* Characters that pressed the note.
|
* Characters that pressed the note.
|
||||||
*/
|
*/
|
||||||
public var characters:Array<Character>;
|
public var characters:Array<Character>;
|
||||||
/**
|
/**
|
||||||
* Whenever the Character is a player
|
* Whenever the Character is a player
|
||||||
*/
|
*/
|
||||||
public var player:Bool;
|
public var player:Bool;
|
||||||
/**
|
/**
|
||||||
* Note Type name (null if default note)
|
* Note Type name (null if default note)
|
||||||
*/
|
*/
|
||||||
public var noteType:String;
|
public var noteType:String;
|
||||||
/**
|
/**
|
||||||
* Suffix of the animation. "-alt" for alt notes, "" for normal ones.
|
* Suffix of the animation. "-alt" for alt notes, "" for normal ones.
|
||||||
*/
|
*/
|
||||||
public var animSuffix:String;
|
public var animSuffix:String;
|
||||||
/**
|
/**
|
||||||
* Prefix of the rating sprite path. Defaults to "game/score/"
|
* Prefix of the rating sprite path. Defaults to "game/score/"
|
||||||
*/
|
*/
|
||||||
public var ratingPrefix:String;
|
public var ratingPrefix:String;
|
||||||
/**
|
/**
|
||||||
* Suffix of the rating sprite path.
|
* Suffix of the rating sprite path.
|
||||||
*/
|
*/
|
||||||
public var ratingSuffix:String;
|
public var ratingSuffix:String;
|
||||||
/**
|
/**
|
||||||
* Direction of the press (0 = Left, 1 = Down, 2 = Up, 3 = Right)
|
* Direction of the press (0 = Left, 1 = Down, 2 = Up, 3 = Right)
|
||||||
*/
|
*/
|
||||||
public var direction:Int;
|
public var direction:Int;
|
||||||
/**
|
/**
|
||||||
* Score gained after note press.
|
* Score gained after note press.
|
||||||
*/
|
*/
|
||||||
public var score:Int;
|
public var score:Int;
|
||||||
/**
|
/**
|
||||||
* Accuracy gained from pressing this note. From 0 to 1. null means no accuracy is gained.
|
* Accuracy gained from pressing this note. From 0 to 1. null means no accuracy is gained.
|
||||||
*/
|
*/
|
||||||
public var accuracy:Null<Float>;
|
public var accuracy:Null<Float>;
|
||||||
/**
|
/**
|
||||||
* The amount of health that'll be gained from pressing that note. If called from `onPlayerMiss`, the value will be negative.
|
* The amount of health that'll be gained from pressing that note. If called from `onPlayerMiss`, the value will be negative.
|
||||||
*/
|
*/
|
||||||
public var healthGain:Float;
|
public var healthGain:Float;
|
||||||
/**
|
/**
|
||||||
* Rating name. Defaults to "sick", "good", "bad" and "shit". Customisable.
|
* Rating name. Defaults to "sick", "good", "bad" and "shit". Customisable.
|
||||||
*/
|
*/
|
||||||
public var rating:String = "sick";
|
public var rating:String = "sick";
|
||||||
/**
|
/**
|
||||||
* Whenever a splash should be shown when the note is hit.
|
* Whenever a splash should be shown when the note is hit.
|
||||||
*/
|
*/
|
||||||
public var showSplash:Bool = false;
|
public var showSplash:Bool = false;
|
||||||
/**
|
/**
|
||||||
* Scale of combo numbers.
|
* Scale of combo numbers.
|
||||||
*/
|
*/
|
||||||
public var numScale:Float = 0.5;
|
public var numScale:Float = 0.5;
|
||||||
/**
|
/**
|
||||||
* Whenever antialiasing should be enabled on combo number.
|
* Whenever antialiasing should be enabled on combo number.
|
||||||
*/
|
*/
|
||||||
public var numAntialiasing:Bool = true;
|
public var numAntialiasing:Bool = true;
|
||||||
/**
|
/**
|
||||||
* Scale of ratings.
|
* Scale of ratings.
|
||||||
*/
|
*/
|
||||||
public var ratingScale:Float = 0.7;
|
public var ratingScale:Float = 0.7;
|
||||||
/**
|
/**
|
||||||
* Whenever antialiasing should be enabled on ratings.
|
* Whenever antialiasing should be enabled on ratings.
|
||||||
*/
|
*/
|
||||||
public var ratingAntialiasing:Bool = true;
|
public var ratingAntialiasing:Bool = true;
|
||||||
/**
|
/**
|
||||||
* Whenever the animation should be forced to play.
|
* Whenever the animation should be forced to play.
|
||||||
*/
|
*/
|
||||||
public var forceAnim:Bool = true;
|
public var forceAnim:Bool = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the default sing animation from being played.
|
* Prevents the default sing animation from being played.
|
||||||
*/
|
*/
|
||||||
public function preventAnim() {
|
public function preventAnim() {
|
||||||
animCancelled = true;
|
animCancelled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
public function cancelAnim() {preventAnim();}
|
public function cancelAnim() {preventAnim();}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the note from being deleted.
|
* Prevents the note from being deleted.
|
||||||
*/
|
*/
|
||||||
public function preventDeletion() {
|
public function preventDeletion() {
|
||||||
deleteNote = false;
|
deleteNote = false;
|
||||||
}
|
}
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
public function cancelDeletion() {preventDeletion();}
|
public function cancelDeletion() {preventDeletion();}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the vocals volume from being set to 1 after pressing the note.
|
* Prevents the vocals volume from being set to 1 after pressing the note.
|
||||||
*/
|
*/
|
||||||
public function preventVocalsUnmute() {
|
public function preventVocalsUnmute() {
|
||||||
unmuteVocals = false;
|
unmuteVocals = false;
|
||||||
}
|
}
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
public function cancelVocalsUnmute() {preventVocalsUnmute();}
|
public function cancelVocalsUnmute() {preventVocalsUnmute();}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the vocals volume from being muted in case its a parameter of `onPlayerMiss`
|
* Prevents the vocals volume from being muted in case its a parameter of `onPlayerMiss`
|
||||||
*/
|
*/
|
||||||
public function preventVocalsMute() {
|
public function preventVocalsMute() {
|
||||||
unmuteVocals = true;
|
unmuteVocals = true;
|
||||||
}
|
}
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
public function cancelVocalsMute() {preventVocalsMute();}
|
public function cancelVocalsMute() {preventVocalsMute();}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the camera zoom every 4 beats from enabling.
|
* Prevents the camera zoom every 4 beats from enabling.
|
||||||
*/
|
*/
|
||||||
public function preventCamZooming() {
|
public function preventCamZooming() {
|
||||||
enableCamZooming = false;
|
enableCamZooming = false;
|
||||||
}
|
}
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
public function cancelCamZooming() {preventCamZooming();}
|
public function cancelCamZooming() {preventCamZooming();}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the sustain tail (the last one) from being automatically hit when the sustain before it is hit.
|
* Prevents the sustain tail (the last one) from being automatically hit when the sustain before it is hit.
|
||||||
*/
|
*/
|
||||||
public function preventLastSustainHit() {
|
public function preventLastSustainHit() {
|
||||||
autoHitLastSustain = false;
|
autoHitLastSustain = false;
|
||||||
}
|
}
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
public function cancelLastSustainHit() {preventLastSustainHit();}
|
public function cancelLastSustainHit() {preventLastSustainHit();}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the strum from glowing after this note has been pressed.
|
* Prevents the strum from glowing after this note has been pressed.
|
||||||
*/
|
*/
|
||||||
public function preventStrumGlow() {
|
public function preventStrumGlow() {
|
||||||
strumGlowCancelled = true;
|
strumGlowCancelled = true;
|
||||||
}
|
}
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
public function cancelStrumGlow() {preventStrumGlow();}
|
public function cancelStrumGlow() {preventStrumGlow();}
|
||||||
|
|
||||||
private inline function get_character()
|
private inline function get_character()
|
||||||
return characters[0];
|
return characters[0];
|
||||||
private function set_character(char:Character) {
|
private function set_character(char:Character) {
|
||||||
characters = [char];
|
characters = [char];
|
||||||
return char;
|
return char;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,45 +4,45 @@ import funkin.game.Note;
|
|||||||
import funkin.game.Strum;
|
import funkin.game.Strum;
|
||||||
|
|
||||||
class NoteUpdateEvent extends CancellableEvent {
|
class NoteUpdateEvent extends CancellableEvent {
|
||||||
@:dox(hide) public var __updateHitWindow = true;
|
@:dox(hide) public var __updateHitWindow = true;
|
||||||
@:dox(hide) public var __autoCPUHit = true;
|
@:dox(hide) public var __autoCPUHit = true;
|
||||||
@:dox(hide) public var __reposNote = true;
|
@:dox(hide) public var __reposNote = true;
|
||||||
/**
|
/**
|
||||||
* Note that is being updated
|
* Note that is being updated
|
||||||
*/
|
*/
|
||||||
public var note:Note;
|
public var note:Note;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time elapsed since last frame
|
* Time elapsed since last frame
|
||||||
*/
|
*/
|
||||||
public var elapsed:Null<Float>;
|
public var elapsed:Null<Float>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note's strum (can be changed)
|
* Note's strum (can be changed)
|
||||||
*/
|
*/
|
||||||
public var strum:Strum;
|
public var strum:Strum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the hit window update.
|
* Cancels the hit window update.
|
||||||
*/
|
*/
|
||||||
public function cancelWindowUpdate() {
|
public function cancelWindowUpdate() {
|
||||||
__updateHitWindow = false;
|
__updateHitWindow = false;
|
||||||
}
|
}
|
||||||
@:dox(hide) public function preventWindowUpdate() { cancelWindowUpdate(); }
|
@:dox(hide) public function preventWindowUpdate() { cancelWindowUpdate(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the automatic CPU hit.
|
* Cancels the automatic CPU hit.
|
||||||
*/
|
*/
|
||||||
public function cancelAutoCPUHit() {
|
public function cancelAutoCPUHit() {
|
||||||
__autoCPUHit = false;
|
__autoCPUHit = false;
|
||||||
}
|
}
|
||||||
@:dox(hide) public function preventAutoCPUHit() { cancelAutoCPUHit(); }
|
@:dox(hide) public function preventAutoCPUHit() { cancelAutoCPUHit(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the note position update (note will freeze).
|
* Cancels the note position update (note will freeze).
|
||||||
*/
|
*/
|
||||||
public function cancelPositionUpdate() {
|
public function cancelPositionUpdate() {
|
||||||
__reposNote = false;
|
__reposNote = false;
|
||||||
}
|
}
|
||||||
@:dox(hide) public function preventPositionUpdate() { cancelPositionUpdate(); }
|
@:dox(hide) public function preventPositionUpdate() { cancelPositionUpdate(); }
|
||||||
}
|
}
|
||||||
@@ -4,13 +4,13 @@ package funkin.scripting.events;
|
|||||||
* CANCEL this event to prevent default behaviour!
|
* CANCEL this event to prevent default behaviour!
|
||||||
*/
|
*/
|
||||||
class PauseCreationEvent extends CancellableEvent {
|
class PauseCreationEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Music that is going to be played
|
* Music that is going to be played
|
||||||
*/
|
*/
|
||||||
public var music:String;
|
public var music:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All option names
|
* All option names
|
||||||
*/
|
*/
|
||||||
public var options:Array<String>;
|
public var options:Array<String>;
|
||||||
}
|
}
|
||||||
@@ -1,64 +1,64 @@
|
|||||||
package funkin.scripting.events;
|
package funkin.scripting.events;
|
||||||
|
|
||||||
class PlayAnimEvent extends CancellableEvent {
|
class PlayAnimEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
Name of the animation that's going to be played.
|
Name of the animation that's going to be played.
|
||||||
**/
|
**/
|
||||||
public var animName:String;
|
public var animName:String;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Whenever the animation will be forced or not.
|
Whenever the animation will be forced or not.
|
||||||
**/
|
**/
|
||||||
public var force:Bool;
|
public var force:Bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Whenever the animation will play in reverse or not
|
Whenever the animation will play in reverse or not
|
||||||
**/
|
**/
|
||||||
public var reverse:Bool;
|
public var reverse:Bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The frame at which the animation will start playing
|
The frame at which the animation will start playing
|
||||||
**/
|
**/
|
||||||
public var startingFrame:Int = 0;
|
public var startingFrame:Int = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Context of the animation
|
Context of the animation
|
||||||
**/
|
**/
|
||||||
public var context:PlayAnimContext;
|
public var context:PlayAnimContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Contains all contexts possible for `PlayAnimEvent`.
|
Contains all contexts possible for `PlayAnimEvent`.
|
||||||
**/
|
**/
|
||||||
@:enum
|
@:enum
|
||||||
abstract PlayAnimContext(String) {
|
abstract PlayAnimContext(String) {
|
||||||
/**
|
/**
|
||||||
No context was given for the animation.
|
No context was given for the animation.
|
||||||
The character won't dance until the animation is finished
|
The character won't dance until the animation is finished
|
||||||
**/
|
**/
|
||||||
var NONE = null;
|
var NONE = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Whenever a note is hit and a sing animation will be played.
|
Whenever a note is hit and a sing animation will be played.
|
||||||
The character will only dance after their holdTime is reached.
|
The character will only dance after their holdTime is reached.
|
||||||
**/
|
**/
|
||||||
var SING = "SING";
|
var SING = "SING";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Whenever a dance animation is played.
|
Whenever a dance animation is played.
|
||||||
The character's dancing wont be blocked.
|
The character's dancing wont be blocked.
|
||||||
**/
|
**/
|
||||||
var DANCE = "DANCE";
|
var DANCE = "DANCE";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Whenever a note is missed and a miss animation will be played.
|
Whenever a note is missed and a miss animation will be played.
|
||||||
Only for scripting, since it has the same effects as SING.
|
Only for scripting, since it has the same effects as SING.
|
||||||
**/
|
**/
|
||||||
var MISS = "MISS";
|
var MISS = "MISS";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Locks the character's animation.
|
Locks the character's animation.
|
||||||
Prevents the character from dancing, even if the animation ended.
|
Prevents the character from dancing, even if the animation ended.
|
||||||
**/
|
**/
|
||||||
var LOCK = "LOCK";
|
var LOCK = "LOCK";
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package funkin.scripting.events;
|
package funkin.scripting.events;
|
||||||
|
|
||||||
class PointEvent extends CancellableEvent {
|
class PointEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
X position
|
X position
|
||||||
**/
|
**/
|
||||||
public var x:Float;
|
public var x:Float;
|
||||||
/**
|
/**
|
||||||
Y position
|
Y position
|
||||||
**/
|
**/
|
||||||
public var y:Float;
|
public var y:Float;
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package funkin.scripting.events;
|
package funkin.scripting.events;
|
||||||
|
|
||||||
class RatingUpdateEvent extends CancellableEvent {
|
class RatingUpdateEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
New combo
|
New combo
|
||||||
**/
|
**/
|
||||||
public var rating:ComboRating;
|
public var rating:ComboRating;
|
||||||
/**
|
/**
|
||||||
Old combo (may be null)
|
Old combo (may be null)
|
||||||
**/
|
**/
|
||||||
public var oldRating:ComboRating;
|
public var oldRating:ComboRating;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
package funkin.scripting.events;
|
package funkin.scripting.events;
|
||||||
|
|
||||||
class ResizeEvent extends CancellableEvent {
|
class ResizeEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* New width
|
* New width
|
||||||
*/
|
*/
|
||||||
public var width:Int;
|
public var width:Int;
|
||||||
/**
|
/**
|
||||||
* New height
|
* New height
|
||||||
*/
|
*/
|
||||||
public var height:Int;
|
public var height:Int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Old width (may be null)
|
* Old width (may be null)
|
||||||
*/
|
*/
|
||||||
public var oldWidth:Null<Int>;
|
public var oldWidth:Null<Int>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Old height (may be null)
|
* Old height (may be null)
|
||||||
*/
|
*/
|
||||||
public var oldHeight:Null<Int>;
|
public var oldHeight:Null<Int>;
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,8 @@ package funkin.scripting.events;
|
|||||||
import funkin.game.Note;
|
import funkin.game.Note;
|
||||||
|
|
||||||
class SimpleNoteEvent extends CancellableEvent {
|
class SimpleNoteEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
Note that is affected.
|
Note that is affected.
|
||||||
**/
|
**/
|
||||||
public var note:Note;
|
public var note:Note;
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user