From b502208b90cb6ea378f38dbf80551b3cbb6b7677 Mon Sep 17 00:00:00 2001
From: Ryiuu <161896371+Ryiuu04@users.noreply.github.com>
Date: Tue, 6 Aug 2024 19:24:32 -0300
Subject: [PATCH] cool stuff + small fixes
if you can't compile, install hxvlc 1.2.0
---
Project.xml | 1 +
source/backend/CustomFadeTransition.hx | 30 +--
source/backend/Paths.hx | 124 ++++++---
source/flxanimate/FlxAnimate.hx | 67 +++++
source/flxanimate/frames/FlxAnimateFrames.hx | 180 ++++++++-----
source/luafiles/FlxAnimateFunctions.hx | 14 +-
source/luafiles/ModchartState.hx | 250 ++++++++++++++++++-
source/objects/PsychVideoSprite.hx | 3 +-
source/states/PlayState.hx | 148 ++++++++---
source/states/editors/ChartingState.hx | 108 +++++++-
source/substates/PauseSubState.hx | 1 +
11 files changed, 759 insertions(+), 167 deletions(-)
diff --git a/Project.xml b/Project.xml
index 577b43b..857b067 100644
--- a/Project.xml
+++ b/Project.xml
@@ -135,6 +135,7 @@
+
diff --git a/source/backend/CustomFadeTransition.hx b/source/backend/CustomFadeTransition.hx
index 03d64ec..ecd39d6 100644
--- a/source/backend/CustomFadeTransition.hx
+++ b/source/backend/CustomFadeTransition.hx
@@ -41,20 +41,11 @@ class CustomFadeTransition extends MusicBeatSubstate
transitionSprite = new FlxSprite(-2600);
transitionSprite.loadGraphic(Paths.image('transition thingy'));
- //transitionSprite.frames = Paths.getSparrowAtlas('circle thing', 'preload');
- //transitionSprite.animation.addByPrefix('transition', 'kevin_normal', 60, false);
transitionSprite.scrollFactor.set(0, 0);
add(transitionSprite);
if (isTransIn)
{
- //transitionSprite.animation.play('transition', true, true, 28);
- //transitionSprite.animation.callback = function(anim, framenumber, frameindex)
- //{
- //if (framenumber == 0)
- //close();
- //}
-
transitionSprite.x = -620;
FlxTween.tween(transitionSprite, { x: 1280 }, 0.4, {
@@ -66,15 +57,6 @@ class CustomFadeTransition extends MusicBeatSubstate
}
else
{
- // transitionSprite.animation.play('transition', true);
- // transitionSprite.animation.callback = function(anim, framenumber, frameindex)
- // {
- //if (finishCallback != null && framenumber == 28)
- //{
- //finishCallback();
- //}
- //}
-
transitionSprite.x = -2600;
FlxTween.tween(transitionSprite, { x: -620 }, 0.4, {
@@ -86,11 +68,13 @@ class CustomFadeTransition extends MusicBeatSubstate
}
- if (nextCamera != null)
- {
- transitionSprite.cameras = [nextCamera];
- }
- nextCamera = null;
+ //quick fix for the character editor/stage editor
+ var transitionCamera = new FlxCamera();
+ transitionCamera.bgColor.alpha = 0;
+ FlxG.cameras.add(transitionCamera, false);
+
+ transitionSprite.cameras = [transitionCamera];
+ //
}
override function update(elapsed:Float)
diff --git a/source/backend/Paths.hx b/source/backend/Paths.hx
index dd94cc6..107fc5f 100644
--- a/source/backend/Paths.hx
+++ b/source/backend/Paths.hx
@@ -250,38 +250,35 @@ class Paths
return FileSystem.absolutePath('assets/songs/${songLowercase}/'+pre+'Inst'+suf+'.$SOUND_EXT');
}
- inline static public function voices2(song:String, ?library:String)
+ inline static public function voices2(song:String, postfix:String = null, ?library:String/*this library shit is even used?*/)
{
var songLowercase = StringTools.replace(song, " ", "-").toLowerCase();
- switch (songLowercase) {
- case 'dad-battle': songLowercase = 'dadbattle';
- case 'philly-nice': songLowercase = 'philly';
- }
var pre:String = "";
var suf:String = "";
if (Main.noCopyright && (Assets.exists('songs:assets/songs/${songLowercase}/'+'Voices'+'Alt'+'.$SOUND_EXT') || FileSystem.exists(Paths.modsSounds('songs', '${songLowercase}/'+pre+'VoicesAlt'))))
suf = 'Alt';
- if (PlayState.isNeonight)
- suf = 'NN';
- if (PlayState.isVitor)
- suf = 'V';
- if (PlayState.isBETADCIU && CoolUtil.difficulties[0] == "Guest" && (Assets.exists('songs:assets/songs/${songLowercase}/'+'Voices'+'Guest'+'.$SOUND_EXT') || FileSystem.exists(Paths.modsSounds('songs', '${songLowercase}/'+pre+'VoicesGuest'))))
- suf = 'Guest';
- if (PlayState.isBETADCIU && (Assets.exists('songs:assets/songs/${songLowercase}/'+'Voices'+'BETADCIU'+'.$SOUND_EXT') || FileSystem.exists(Paths.modsSounds('songs', '${songLowercase}/'+pre+'VoicesBETADCIU'))))
- suf = 'BETADCIU';
-
- if (FileSystem.exists(Paths.modsSounds('songs', '${songLowercase}/'+pre+'Voices'+suf)))
- {
- returnSound('songs', '${songLowercase}/'+pre+'Voices'+suf);
- return Paths.modsSounds('songs', '${songLowercase}/'+pre+'Voices'+suf);
- }
-
- return FileSystem.absolutePath('assets/songs/${songLowercase}/'+pre+'Voices'+suf+'.$SOUND_EXT');
- }
-
- inline static public function voices(song:String)
+ if (PlayState.isNeonight)
+ suf = 'NN';
+ if (PlayState.isVitor)
+ suf = 'V';
+ if (PlayState.isBETADCIU && CoolUtil.difficulties[0] == "Guest" && (Assets.exists('songs:assets/songs/${songLowercase}/'+'Voices'+'Guest'+'.$SOUND_EXT') || FileSystem.exists(Paths.modsSounds('songs', '${songLowercase}/'+pre+'VoicesGuest'))))
+ suf = 'Guest';
+ if (PlayState.isBETADCIU && (Assets.exists('songs:assets/songs/${songLowercase}/'+'Voices'+'BETADCIU'+'.$SOUND_EXT') || FileSystem.exists(Paths.modsSounds('songs', '${songLowercase}/'+pre+'VoicesBETADCIU'))))
+ suf = 'BETADCIU';
+ if (postfix != null) suf += '-' + postfix;
+
+ if (FileSystem.exists(Paths.modsSounds('songs', '${songLowercase}/'+pre+'Voices'+suf)))
+ {
+ returnSound('songs', '${songLowercase}/'+pre+'Voices'+suf);
+ return Paths.modsSounds('songs', '${songLowercase}/'+pre+'Voices'+suf);
+ }
+
+ return FileSystem.absolutePath('assets/songs/${songLowercase}/'+pre+'Voices'+suf+'.$SOUND_EXT');
+ }
+
+ inline static public function voices(song:String, ?postfix:String = null)
{
var songLowercase = StringTools.replace(song, " ", "-").toLowerCase();
switch (songLowercase) {
@@ -299,11 +296,10 @@ class Paths
suf = 'V';
if (PlayState.isBETADCIU && CoolUtil.difficulties[0] == "Guest")
suf = 'Guest';
- if (PlayState.isBETADCIU && (songLowercase == 'kaboom' || songLowercase == 'triple-trouble'))
+ if (PlayState.isBETADCIU)
suf = 'BETADCIU';
- if (Main.isMegalo && songLowercase == 'hill-of-the-void')
- suf = 'Megalo';
-
+ if (postfix != null) suf += '-' + postfix;
+
return 'songs:assets/songs/${songLowercase}/'+pre+'Voices'+suf+'.$SOUND_EXT';
}
@@ -953,4 +949,76 @@ class Paths
return list;
}
#end
+
+ #if flxanimate
+ public static function loadAnimateAtlas(spr:FlxAnimate, folderOrImg:Dynamic, spriteJson:Dynamic = null, animationJson:Dynamic = null)
+ {
+ var changedAnimJson = false;
+ var changedAtlasJson = false;
+ var changedImage = false;
+
+ if(spriteJson != null)
+ {
+ changedAtlasJson = true;
+ spriteJson = File.getContent(spriteJson);
+ }
+
+ if(animationJson != null)
+ {
+ changedAnimJson = true;
+ animationJson = File.getContent(animationJson);
+ }
+
+ // is folder or image path
+ if(Std.isOfType(folderOrImg, String))
+ {
+ var originalPath:String = folderOrImg;
+ for (i in 0...10)
+ {
+ var st:String = '$i';
+ if(i == 0) st = '';
+
+ if(!changedAtlasJson)
+ {
+ spriteJson = getTextFromFile('images/$originalPath/spritemap$st.json');
+ if(spriteJson != null)
+ {
+ trace('found Sprite Json');
+ changedImage = true;
+ changedAtlasJson = true;
+ folderOrImg = returnGraphic('$originalPath/spritemap$st');
+ break;
+ }
+ }
+ else if(fileExists('images/$originalPath/spritemap$st.png', IMAGE))
+ {
+ trace('found Sprite PNG');
+ changedImage = true;
+ folderOrImg = returnGraphic('$originalPath/spritemap$st');
+ break;
+ }
+ }
+
+ if(!changedImage)
+ {
+ trace('Changing folderOrImg to FlxGraphic');
+ changedImage = true;
+ folderOrImg = returnGraphic(originalPath);
+ }
+
+ if(!changedAnimJson)
+ {
+ trace('found Animation Json');
+ changedAnimJson = true;
+ animationJson = getTextFromFile('images/$originalPath/Animation.json');
+ }
+ }
+
+ trace(folderOrImg);
+ //trace(spriteJson);
+ //trace(animationJson);
+
+ spr.loadAtlasEx(folderOrImg, spriteJson, animationJson);
+ }
+ #end
}
\ No newline at end of file
diff --git a/source/flxanimate/FlxAnimate.hx b/source/flxanimate/FlxAnimate.hx
index 98ceeb4..ec09633 100644
--- a/source/flxanimate/FlxAnimate.hx
+++ b/source/flxanimate/FlxAnimate.hx
@@ -22,6 +22,7 @@ import flixel.math.FlxMatrix;
import openfl.geom.ColorTransform;
import flixel.math.FlxMath;
import flixel.FlxBasic;
+import flixel.system.FlxAssets.FlxGraphicAsset;
typedef Settings = {
?ButtonSettings:Map,
@@ -91,6 +92,72 @@ class FlxAnimate extends FlxSprite
anim._loadAtlas(atlasSetting(Path));
frames = FlxAnimateFrames.fromTextureAtlas(Path);
}
+
+ public function loadAtlasEx(img:FlxGraphicAsset, pathOrStr:String = null, myJson:Dynamic = null)
+ {
+ var animJson:AnimAtlas = null;
+ if(myJson is String)
+ {
+ var trimmed:String = pathOrStr.trim();
+ trimmed = trimmed.substr(trimmed.length - 5).toLowerCase();
+
+ if(trimmed == '.json') myJson = sys.io.File.getContent(myJson); //is a path
+ animJson = cast haxe.Json.parse(_removeBOM(myJson));
+ }
+ else animJson = cast myJson;
+
+ var isXml:Null = null;
+ var myData:Dynamic = pathOrStr;
+
+ var trimmed:String = pathOrStr.trim();
+ trimmed = trimmed.substr(trimmed.length - 5).toLowerCase();
+
+ if(trimmed == '.json') //Path is json
+ {
+ myData = sys.io.File.getContent(pathOrStr);
+ isXml = false;
+ }
+ else if (trimmed.substr(1) == '.xml') //Path is xml
+ {
+ myData = sys.io.File.getContent(pathOrStr);
+ isXml = true;
+ }
+ myData = _removeBOM(myData);
+
+ // Automatic if everything else fails
+ switch(isXml)
+ {
+ case true:
+ myData = Xml.parse(myData);
+ case false:
+ myData = haxe.Json.parse(myData);
+ case null:
+ try
+ {
+ myData = haxe.Json.parse(myData);
+ isXml = false;
+ //trace('JSON parsed successfully!');
+ }
+ catch(e)
+ {
+ myData = Xml.parse(myData);
+ isXml = true;
+ //trace('XML parsed successfully!');
+ }
+ }
+
+ anim._loadAtlas(animJson);
+ if(!isXml) frames = FlxAnimateFrames.fromAnimateAtlas(cast myData, img);
+ else frames = FlxAnimateFrames.fromSparrow(cast myData, img);
+ origin = anim.curInstance.symbol.transformationPoint;
+ }
+
+ function _removeBOM(str:String) //Removes BOM byte order indicator
+ {
+ if (str.charCodeAt(0) == 0xFEFF) str = str.substr(1); //myData = myData.substr(2);
+ return str;
+ }
+
/**
* the function `draw()` renders the symbol that `anim` has currently plus a pivot that you can toggle on or off.
*/
diff --git a/source/flxanimate/frames/FlxAnimateFrames.hx b/source/flxanimate/frames/FlxAnimateFrames.hx
index 2b255f1..a91278f 100644
--- a/source/flxanimate/frames/FlxAnimateFrames.hx
+++ b/source/flxanimate/frames/FlxAnimateFrames.hx
@@ -42,10 +42,10 @@ class FlxAnimateFrames extends FlxAtlasFrames
* @param Path Where the Sprites are, normally you use it once when calling FlxAnimate already
* @return new sliced limbs for you to use ;)
*/
- public static function fromTextureAtlas(Path:String):FlxAtlasFrames
+ public static function fromTextureAtlas(Path:String):FlxAtlasFrames
{
var frames:FlxAnimateFrames = new FlxAnimateFrames();
-
+
if (zip != null || haxe.io.Path.extension(Path) == "zip")
{
#if html5
@@ -54,9 +54,9 @@ class FlxAnimateFrames extends FlxAtlasFrames
#end
var imagemap:Map = new Map();
var jsonMap:Map = new Map();
- var thing = (zip != null) ? zip : Zip.unzip(Zip.readZip(Assets.exists(Path) ? Assets.getBytes(Path) : File.getBytes(Path)));
- for (list in thing)
- {
+ var thing = (zip != null) ? zip : Zip.unzip(Zip.readZip(#if sys sys.io.File.getBytes(Path) #else Assets.getBytes(Path) #end));
+ for (list in thing)
+ {
if (haxe.io.Path.extension(list.fileName) == "json")
{
jsonMap.set(list.fileName,haxe.Json.parse(StringTools.replace(list.data.toString(), String.fromCharCode(0xFEFF), "")));
@@ -66,7 +66,7 @@ class FlxAnimateFrames extends FlxAtlasFrames
var name = list.fileName.split("/");
imagemap.set(name[name.length - 1], list.data);
}
- }
+ }
// Assuming the json has the same stuff as the image stuff
for (curJson in jsonMap)
{
@@ -75,7 +75,7 @@ class FlxAnimateFrames extends FlxAtlasFrames
{
for (sprites in curJson.ATLAS.SPRITES)
{
- frames.pushFrame(textureAtlasHelper(curImage, sprites.SPRITE, curJson.meta));
+ frames.pushFrame(textureAtlasHelper(FlxG.bitmap.add(curImage), sprites.SPRITE, curJson.meta));
}
}
else
@@ -85,63 +85,84 @@ class FlxAnimateFrames extends FlxAtlasFrames
}
else
{
- if (Assets.exists('$Path/spritemap.json') || FileSystem.exists('$Path/spritemap.json'))
+ #if sys
+ var texts = sys.FileSystem.readDirectory(Path).filter((text) -> text.startsWith('spritemap') && text.toLowerCase().endsWith('.json'));
+ for(i in 0...texts.length) texts[i] = '$Path/' + texts[i];
+ #else
+ var texts = Assets.list(TEXT).filter((text) -> StringTools.startsWith(text, '$Path/spritemap'));
+ #end
+ if (texts.length > 1)
{
- var isAssets = Assets.exists('$Path/spritemap.json');
- var curJson:AnimateAtlas = haxe.Json.parse(StringTools.replace((isAssets ? Assets.getText('$Path/spritemap.json') : File.getContent('$Path/spritemap.json')), String.fromCharCode(0xFEFF), ""));
- var curSpritemap = isAssets ? Assets.getBitmapData('$Path/${curJson.meta.image}') : BitmapData.fromFile('$Path/${curJson.meta.image}');
- if (curSpritemap != null)
+ texts.sort(function (a, b)
{
- var graphic = FlxG.bitmap.add(curSpritemap);
- var spritemapFrames = FlxAtlasFrames.findFrame(graphic);
- if (spritemapFrames == null)
- {
- spritemapFrames = new FlxAnimateFrames();
- for (curSprite in curJson.ATLAS.SPRITES)
- {
- spritemapFrames.pushFrame(textureAtlasHelper(graphic.bitmap,curSprite.SPRITE, curJson.meta));
- }
- }
- graphic.addFrameCollection(spritemapFrames);
- frames.concatFrames(spritemapFrames);
- }
- else
- FlxG.log.error('the image called "${curJson.meta.image}" does not exist in Path $Path, maybe you changed the image Path somewhere else?');
- }
- var i = 1;
+ var an = Std.parseInt(haxe.io.Path.withoutDirectory(a).charAt(9));
+ var bn = Std.parseInt(haxe.io.Path.withoutDirectory(b).charAt(9));
+ if (Math.isNaN(an) || Math.isNaN(bn))
+ return 0;
- while (Assets.exists('$Path/spritemap$i.json') || FileSystem.exists('$Path/spritemap$i.json'))
+ return an - bn;
+ });
+ }
+ var spritemaps:Array<{image:BitmapData, json:AnimateAtlas}> = [];
+ for (text in texts)
+ {
+ #if sys
+ var txt = sys.io.File.getContent(text);
+ #else
+ var txt = Assets.getText(text);
+ #end
+ if (txt.charCodeAt(0) == 0xFEFF)
+ txt = txt.substring(1);
+ var json:AnimateAtlas = haxe.Json.parse(txt);
+
+ #if sys
+ spritemaps.push({image: BitmapData.fromFile('$Path/${json.meta.image}'), json: json});
+ #else
+ spritemaps.push({image: Assets.getBitmapData('$Path/${json.meta.image}'), json: json});
+ #end
+ }
+
+ for (spritemap in spritemaps)
{
- var isAssets = Assets.exists('$Path/spritemap$i.json');
- var curJson:AnimateAtlas = haxe.Json.parse(StringTools.replace((isAssets ? Assets.getText('$Path/spritemap$i.json') : File.getContent('$Path/spritemap$i.json')), String.fromCharCode(0xFEFF), ""));
- trace("JSON FOR PATH " + Path + " IS: \n" + curJson);
- var curSpritemap = (isAssets ? Assets.getBitmapData('$Path/${curJson.meta.image}') : BitmapData.fromFile('$Path/${curJson.meta.image}'));
- if (curSpritemap != null)
+ if (spritemap.image == null)
+ {
+ FlxG.log.error('the image called "${spritemap.json.meta.image}" does not exist in Path $Path, maybe you changed the image Path somewhere else?');
+ continue;
+ }
+
+ var graphic = FlxG.bitmap.add(spritemap.image);
+ var spritemapFrames = FlxAtlasFrames.findFrame(graphic);
+ if (spritemapFrames == null)
{
- var graphic = FlxG.bitmap.add(curSpritemap);
- var spritemapFrames = FlxAtlasFrames.findFrame(graphic);
- if (spritemapFrames == null)
+ spritemapFrames = new FlxAnimateFrames();
+ for (curSprite in spritemap.json.ATLAS.SPRITES)
{
- spritemapFrames = new FlxAnimateFrames();
- for (curSprite in curJson.ATLAS.SPRITES)
- {
- spritemapFrames.pushFrame(textureAtlasHelper(graphic.bitmap,curSprite.SPRITE, curJson.meta));
- }
+ spritemapFrames.pushFrame(textureAtlasHelper(graphic, curSprite.SPRITE, spritemap.json.meta));
}
- graphic.addFrameCollection(spritemapFrames);
- frames.concatFrames(spritemapFrames);
}
- else
- FlxG.log.error('the image called "${curJson.meta.image}" does not exist in Path $Path, maybe you changed the image Path somewhere else?');
- i++;
+ graphic.addFrameCollection(spritemapFrames);
+ frames.animateConcat(spritemapFrames);
+ }
+
+ if (frames.frames == [])
+ {
+ FlxG.log.error("the Frames parsing couldn't parse any of the frames, it's completely empty! \n Maybe you misspelled the Path?");
+ return null;
}
}
- if (frames.frames == [])
+ return frames;
+ }
+
+ public function animateConcat(frames:FlxFramesCollection)
+ {
+ if (parents.indexOf(frames.parent) == -1)
+ parents.push(frames.parent);
+ for (frame in frames.frames)
{
- FlxG.log.error("the Frames parsing couldn't parse any of the frames, it's completely empty! \n Maybe you misspelled the Path?");
- return null;
+ this.frames.push(frame);
+ framesHash.set(frame.name, frame);
}
- return frames;
+ return this;
}
public function concatFrames(frames:FlxFramesCollection)
@@ -154,6 +175,37 @@ class FlxAnimateFrames extends FlxAtlasFrames
framesHash.set(frame.name, frame);
}
}
+
+ /**
+ *
+ * @param Data the Json/XML file content/string
+ * @param Image the image which the file is referencing **WARNING:** if you set the path as a json, it's obligatory to set the image!
+ * @return A new instance of `FlxAtlasFrames`
+ */
+ public static function fromAnimateAtlas(Data:AnimateAtlas, Image:FlxGraphicAsset):FlxAnimateFrames
+ {
+ var frames:FlxAnimateFrames = new FlxAnimateFrames();
+ var graphic = FlxG.bitmap.add(Image);
+ var spritemapFrames = FlxAtlasFrames.findFrame(graphic);
+ if (spritemapFrames == null)
+ {
+ spritemapFrames = new FlxAnimateFrames();
+ for (curSprite in Data.ATLAS.SPRITES)
+ {
+ spritemapFrames.pushFrame(textureAtlasHelper(graphic, curSprite.SPRITE, Data.meta));
+ }
+ }
+ graphic.addFrameCollection(spritemapFrames);
+ frames.animateConcat(spritemapFrames);
+
+ if (frames.frames == [])
+ {
+ trace("the Frames parsing couldn't parse any of the frames, it's completely empty! \n Maybe you misspelled the Path?");
+ return null;
+ }
+ return frames;
+ }
+
/**
* Sparrow spritesheet format parser with support of both of the versions and making the image completely optional to you.
* @param Path The direction of the Xml you want to parse.
@@ -479,24 +531,24 @@ class FlxAnimateFrames extends FlxAtlasFrames
Frames.addAtlasFrame(frameRect, sourceSize, offset, name, angle);
}
- static function textureAtlasHelper(SpriteMap:BitmapData, limb:AnimateSpriteData, curMeta:Meta)
+ static function textureAtlasHelper(SpriteMap:FlxGraphic, limb:AnimateSpriteData, curMeta:Meta)
{
+
var width = (limb.rotated) ? limb.h : limb.w;
var height = (limb.rotated) ? limb.w : limb.h;
- var sprite = new BitmapData(width, height, true, 0);
- var matrix = new FlxMatrix(1,0,0,1,-limb.x,-limb.y);
- if (limb.rotated)
- {
- matrix.rotateByNegative90();
- matrix.translate(0, height);
- }
- sprite.draw(SpriteMap, matrix);
-
+
@:privateAccess
- var curFrame = new FlxFrame(FlxG.bitmap.add(sprite));
+ var curFrame = new FlxFrame(SpriteMap);
+
curFrame.name = limb.name;
curFrame.sourceSize.set(width, height);
- curFrame.frame = new FlxRect(0,0, width, height);
+ curFrame.frame = new FlxRect(limb.x, limb.y, limb.w, limb.h);
+
+ if (limb.rotated)
+ {
+ curFrame.angle = ANGLE_NEG_90;
+ }
+
return curFrame;
}
diff --git a/source/luafiles/FlxAnimateFunctions.hx b/source/luafiles/FlxAnimateFunctions.hx
index 7c7a5b3..63164ba 100644
--- a/source/luafiles/FlxAnimateFunctions.hx
+++ b/source/luafiles/FlxAnimateFunctions.hx
@@ -5,12 +5,12 @@ import openfl.utils.Assets;
#if (LUA_ALLOWED && flxanimate)
class FlxAnimateFunctions
{
- public static function implement(funk:FunkinLua)
+ public static function implement(funk:ModchartState)
{
var lua:State = funk.lua;
- Lua_helper.add_callback(lua, "makeFlxAnimateSprite", function(tag:String, ?x:Float = 0, ?y:Float = 0, ?loadFolder:String = null) {
+ Lua_helper.add_callback(lua, "makeFlxAnimateSprite", function(tag:String, ?loadFolder:String = null, ?x:Float = 0, ?y:Float = 0) {
tag = tag.replace('.', '');
- var lastSprite = PlayState.instance.variables.get(tag);
+ var lastSprite = PlayState.instance.modchartSprites.get(tag);
if(lastSprite != null)
{
lastSprite.kill();
@@ -20,18 +20,18 @@ class FlxAnimateFunctions
var mySprite:ModchartAnimateSprite = new ModchartAnimateSprite(x, y);
if(loadFolder != null) Paths.loadAnimateAtlas(mySprite, loadFolder);
- PlayState.instance.variables.set(tag, mySprite);
+ PlayState.instance.modchartSprites.set(tag, mySprite);
mySprite.active = true;
});
Lua_helper.add_callback(lua, "loadAnimateAtlas", function(tag:String, folderOrImg:Dynamic, ?spriteJson:Dynamic = null, ?animationJson:Dynamic = null) {
- var spr:FlxAnimate = PlayState.instance.variables.get(tag);
+ var spr:FlxAnimate = PlayState.instance.modchartSprites.get(tag);
if(spr != null) Paths.loadAnimateAtlas(spr, folderOrImg, spriteJson, animationJson);
});
Lua_helper.add_callback(lua, "addAnimationBySymbol", function(tag:String, name:String, symbol:String, ?framerate:Float = 24, ?loop:Bool = false, ?matX:Float = 0, ?matY:Float = 0)
{
- var obj:Dynamic = PlayState.instance.variables.get(tag);
+ var obj:Dynamic = PlayState.instance.modchartSprites.get(tag);
if(cast (obj, FlxAnimate) == null) return false;
obj.anim.addBySymbol(name, symbol, framerate, loop, matX, matY);
@@ -45,7 +45,7 @@ class FlxAnimateFunctions
Lua_helper.add_callback(lua, "addAnimationBySymbolIndices", function(tag:String, name:String, symbol:String, ?indices:Any = null, ?framerate:Float = 24, ?loop:Bool = false, ?matX:Float = 0, ?matY:Float = 0)
{
- var obj:Dynamic = PlayState.instance.variables.get(tag);
+ var obj:Dynamic = PlayState.instance.modchartSprites.get(tag);
if(cast (obj, FlxAnimate) == null) return false;
if(indices == null)
diff --git a/source/luafiles/ModchartState.hx b/source/luafiles/ModchartState.hx
index bb1812f..d4c4c40 100644
--- a/source/luafiles/ModchartState.hx
+++ b/source/luafiles/ModchartState.hx
@@ -14,6 +14,7 @@ import openfl.display.BitmapData;
import lime.app.Application;
import flixel.FlxBasic;
import flixel.FlxObject;
+import flixel.addons.transition.FlxTransitionableState;
import flixel.math.FlxPoint;
import flixel.effects.FlxFlicker;
import flixel.addons.effects.FlxTrail;
@@ -55,6 +56,15 @@ import openfl.display.ShaderParameterType;
import objects.*;
import states.editors.ModpackMaker;
+//bruh.
+import states.StoryMenuState;
+import states.GuestBETADCIUState;
+import states.BETADCIUState;
+import states.BonusSongsState;
+import states.NeonightState;
+import states.VitorState;
+import states.FreeplayState;
+
import backend.Song;
import backend.Highscore;
@@ -69,6 +79,8 @@ import luafiles.ModchartText;
import luafiles.ModchartText.*;
import luafiles.CustomSubstate;
+import substates.PauseSubState;
+
using StringTools;
class ModchartState
@@ -696,6 +708,7 @@ class ModchartState
if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy)
Paths.clearStoredMemory2(bfPath);
+ PlayState.instance.setOnScripts('boyfriendName', PlayState.instance.boyfriend.curCharacter);
PlayState.instance.startCharacterLua(PlayState.instance.boyfriend.curCharacter);
}
@@ -774,6 +787,7 @@ class ModchartState
if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy && daCurChar != PlayState.instance.dad.curCharacter)
Paths.clearStoredMemory2(dadPath);
+ PlayState.instance.setOnScripts('dadName', PlayState.instance.dad.curCharacter);
PlayState.instance.startCharacterLua(PlayState.instance.dad.curCharacter);
}
@@ -810,6 +824,7 @@ class ModchartState
if (FlxG.save.data.uncacheCharacterSwitch && !dontDestroy)
Paths.clearStoredMemory2(gfPath);
+ PlayState.instance.setOnScripts('gfName', PlayState.instance.gf.curCharacter);
PlayState.instance.startCharacterLua(PlayState.instance.gf.curCharacter);
}
@@ -965,6 +980,8 @@ class ModchartState
set('seenCutscene', PlayState.seenCutscene);
set('scriptName', scriptName);
+ set('shadersEnabled', ClientPrefs.data.shaders);
+
if (PlayState.SONG != null)
{
set("bpm", PlayState.SONG.bpm);
@@ -1398,7 +1415,7 @@ class ModchartState
if(luaInstance.scriptName == cervix)
{
if(traceMsg)
- luaTrace('The script "' + cervix + '" is already running!');
+ luaTrace('The lua script "' + cervix + '" is already running!');
return;
}
@@ -1409,6 +1426,42 @@ class ModchartState
}
luaTrace("addLuaScript: Script doesn't exist!", false, false, FlxColor.RED);
});
+
+ Lua_helper.add_callback(lua, "addHScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false, ?traceMsg:Bool = true) { //I wonder if this will cause a crash -- future me here. okay it didn't.
+ var cervix = luaFile + ".hx";
+ var scriptFound = false;
+ if(FileSystem.exists(FileSystem.absolutePath("assets/shared/"+cervix))) {
+ cervix = FileSystem.absolutePath("assets/shared/"+cervix);
+ scriptFound = true;
+ }
+ else if (FileSystem.exists(Paths.modFolders(cervix)))
+ {
+ cervix = Paths.modFolders(cervix);
+ scriptFound = true;
+ }
+ else {
+ cervix = Paths.getPreloadPath(cervix);
+ if(FileSystem.exists(cervix)) {
+ scriptFound = true;
+ }
+ }
+
+ if(scriptFound)
+ {
+ if(!ignoreAlreadyRunning)
+ for (script in PlayState.instance.hscriptArray)
+ if(script.origin == cervix)
+ {
+ if(traceMsg) luaTrace('The hscript script "' + cervix + '" is already running!');
+ return;
+ }
+
+ PlayState.instance.initHScript(cervix);
+ return;
+ }
+ luaTrace("addHScript: Script doesn't exist!", false, false, FlxColor.RED);
+ });
+
Lua_helper.add_callback(lua, "removeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf.
var cervix = luaFile + ".lua";
var doPush = false;
@@ -1458,6 +1511,42 @@ class ModchartState
}
luaTrace("removeLuaScript: Script doesn't exist!", false, false, FlxColor.RED);
});
+
+ Lua_helper.add_callback(lua, "removeHScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf.
+ var cervix = luaFile + ".hx";
+ var scriptFound = false;
+ if(FileSystem.exists(FileSystem.absolutePath("assets/shared/"+cervix))) {
+ cervix = FileSystem.absolutePath("assets/shared/"+cervix);
+ scriptFound = true;
+ }
+ else if (FileSystem.exists(Paths.modFolders(cervix)))
+ {
+ cervix = Paths.modFolders(cervix);
+ scriptFound = true;
+ }
+ else {
+ cervix = Paths.getPreloadPath(cervix);
+ if(FileSystem.exists(cervix)) {
+ scriptFound = true;
+ }
+ }
+
+ if(scriptFound)
+ {
+ if(!ignoreAlreadyRunning)
+ {
+ for (script in PlayState.instance.hscriptArray)
+ if(script.origin == cervix)
+ {
+ //trace('Closing script ' + (script.origin != null ? script.origin : luaFile));
+ script.destroy();
+ return;
+ }
+ }
+ return;
+ }
+ luaTrace("removeHScript: Script doesn't exist!", false, false, FlxColor.RED);
+ });
//because the regular close function isn't working for me
Lua_helper.add_callback(lua, "closeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false) { //would be dope asf.
@@ -1846,6 +1935,18 @@ class ModchartState
PlayState.instance.healthBar.createFilledBar(left_color, right_color);
PlayState.instance.healthBar.updateBar();
});
+
+ Lua_helper.add_callback(lua, "setTimeBarColors", function(left:String, right:String) {
+ var left_color:Null = null;
+ var right_color:Null = null;
+ if (left != null && left != '')
+ left_color = CoolUtil.colorFromString(left);
+ if (right != null && right != '')
+ right_color = CoolUtil.colorFromString(right);
+
+ PlayState.instance.timeBar.createFilledBar(left_color, right_color);
+ PlayState.instance.timeBar.updateBar();
+ });
Lua_helper.add_callback(lua,"getDominantColor", function(sprite:String){
var shit:Dynamic = LuaUtils.getObjectDirectly(sprite);
@@ -1994,6 +2095,24 @@ class ModchartState
}
}
});
+
+ Lua_helper.add_callback(lua, "getSoundPitch", function(tag:String) {
+ if(tag != null && tag.length > 0 && PlayState.instance.modchartSounds.exists(tag)) {
+ return PlayState.instance.modchartSounds.get(tag).pitch;
+ }
+ return 0;
+ });
+ Lua_helper.add_callback(lua, "setSoundPitch", function(tag:String, value:Float, doPause:Bool = false) {
+ if(tag != null && tag.length > 0 && PlayState.instance.modchartSounds.exists(tag)) {
+ var theSound:FlxSound = PlayState.instance.modchartSounds.get(tag);
+ if(theSound != null) {
+ var wasResumed:Bool = theSound.playing;
+ if (doPause) theSound.pause();
+ theSound.pitch = value;
+ if (doPause && wasResumed) theSound.play();
+ }
+ }
+ });
Lua_helper.add_callback(lua, "close", function(printMessage:Bool = false) {
closed = true;
@@ -2204,6 +2323,15 @@ class ModchartState
c.setRGB(r, g, b);
LuaUtils.cameraFromString(camera).fade(c, d, f);
});
+
+ Lua_helper.add_callback(lua, "cameraSetTarget", function(target:String) {
+ var isDad:Bool = false;
+ if(target == 'dad') {
+ isDad = true;
+ }
+ PlayState.instance.moveCamera(isDad);
+ return isDad;
+ });
Lua_helper.add_callback(lua, "cameraShake", function(camera:String, intensity:Float, duration:Float) {
if (PlayState.instance != null){duration = duration / PlayState.instance.playbackRate;}
@@ -2515,6 +2643,26 @@ class ModchartState
default: shit.screenCenter(XY);
}
});
+
+ Lua_helper.add_callback(lua, "objectsOverlap", function(obj1:String, obj2:String) {
+ var namesArray:Array = [obj1, obj2];
+ var objectsArray:Array = [];
+ for (i in 0...namesArray.length)
+ {
+ var real = PlayState.instance.getLuaObject(namesArray[i]);
+ if(real!=null) {
+ objectsArray.push(real);
+ } else {
+ objectsArray.push(Reflect.getProperty(LuaUtils.getTargetInstance(), namesArray[i]));
+ }
+ }
+
+ if(!objectsArray.contains(null) && FlxG.overlap(objectsArray[0], objectsArray[1]))
+ {
+ return true;
+ }
+ return false;
+ });
Lua_helper.add_callback(lua,"playActorAnimation", function(obj:String,anim:String,force:Bool = false,reverse:Bool = false, ?frame:Int = 0) {
var char:Character = LuaUtils.getObjectDirectly(obj);
@@ -2831,11 +2979,108 @@ class ModchartState
return true;
#end
});
-
+
+ Lua_helper.add_callback(lua, "makeVideoSprite", function(tag:String, videoFile:String, ?x:Float, ?y:Float, ?camera:String, ?shouldLoop:Bool, ?muted:Bool) {
+ // I hate you FlxVideoSprite....
+ #if VIDEOS_ALLOWED
+ tag = tag.replace('.', '');
+ LuaUtils.resetSpriteTag(tag);
+ var leVSprite:PsychVideoSprite = null;
+ if(FileSystem.exists(Paths.video(videoFile)) && videoFile != null && videoFile.length > 0) {
+
+ leVSprite = new PsychVideoSprite();
+ leVSprite.addCallback('onFormat',()->{
+ leVSprite.setPosition(x,y);
+ leVSprite.cameras = [LuaUtils.cameraFromString(camera)];
+ });
+ leVSprite.addCallback('onEnd',()->{
+ if (Stage.instance.swagBacks.exists(tag)) {
+ Stage.instance.swagBacks.get(tag).destroy();
+ Stage.instance.swagBacks.remove(tag);
+ }
+
+ if (PlayState.instance.modchartSprites.exists(tag)) {
+ PlayState.instance.modchartSprites.get(tag).destroy();
+ PlayState.instance.modchartSprites.remove(tag);
+ }
+
+ PlayState.instance.callOnLuas('onVideoFinished', [tag]);
+ });
+ var options:Array = [];
+ if (shouldLoop) options.push(PsychVideoSprite.looping);
+ if (muted) options.push(PsychVideoSprite.muted);
+
+ leVSprite.load(Paths.video(videoFile), options);
+ leVSprite.antialiasing = true;
+ leVSprite.play();
+
+ if (isStageLua && !preloading){
+ Stage.instance.swagBacks.set(tag, leVSprite);
+ }
+ else{
+ PlayState.instance.modchartSprites.set(tag, leVSprite);
+ }
+
+ } else {
+ luaTrace('makeVideoSprite: The video file "' + videoFile + '" cannot be found!', FlxColor.RED);
+ return;
+ }
+ leVSprite.active = true;
+ #else
+ luaTrace('Nuh Uh!!... - Platform not supported!');
+ #end
+ });
+
Lua_helper.add_callback(lua, "endSong", function(hmm:String) {
PlayState.instance.KillNotes();
PlayState.instance.endSong();
});
+
+ Lua_helper.add_callback(lua, "restartSong", function(?skipTransition:Bool = false,?cutscene:Bool = false,?preloadAgain:Bool = false) {
+ PlayState.instance.persistentUpdate = false;
+ FlxG.camera.followLerp = 0;
+ if(skipTransition == true) PauseSubState.restartSong(false,cutscene,preloadAgain);
+ else PauseSubState.restartSong(skipTransition,cutscene,preloadAgain);
+ return true;
+ });
+
+ Lua_helper.add_callback(lua, "exitSong", function(?skipTransition:Bool = false) {
+ if(skipTransition)
+ {
+ FlxTransitionableState.skipNextTransIn = true;
+ FlxTransitionableState.skipNextTransOut = true;
+ }
+
+ if(PlayState.isStoryMode) MusicBeatState.switchState(new StoryMenuState());
+
+ if (PlayState.isBETADCIU){
+ if (CoolUtil.difficulties[0] == "Guest")
+ MusicBeatState.switchState(new states.GuestBETADCIUState());
+ else
+ MusicBeatState.switchState(new states.BETADCIUState());
+ }else{
+ if (PlayState.isBonus)
+ MusicBeatState.switchState(new states.BonusSongsState());
+ else if (PlayState.isNeonight)
+ MusicBeatState.switchState(new states.NeonightState());
+ else if (PlayState.isVitor)
+ MusicBeatState.switchState(new states.VitorState());
+ else
+ MusicBeatState.switchState(new states.FreeplayState());
+ }
+
+ #if DISCORD_ALLOWED DiscordClient.resetClientID(); #end
+
+ PlayState.changedDifficulty = false;
+ PlayState.chartingMode = false;
+ PlayState.instance.transitioning = true;
+ FlxG.camera.followLerp = 0;
+
+ FlxTransitionableState.skipNextTransIn = false;//visual bug fix
+ FlxTransitionableState.skipNextTransOut = false;//visual bug fix
+
+ return true;
+ });
//idk if I wanna add events. alright I added the ones that are usable without that much tinkering.
Lua_helper.add_callback(lua, "triggerEvent", function(name:String, arg1:Dynamic, arg2:Dynamic, ?arg3:Dynamic = "") {
@@ -3588,6 +3833,7 @@ class ModchartState
#if desktop DiscordClient.addLuaCallbacks(lua); #end
#if hscript HScript.implement(this); #end
+ #if flxanimate FlxAnimateFunctions.implement(this); #end
ReflectionFunctions.implement(this);
TweenFunctions.implement(this);
TextFunctions.implement(this);
diff --git a/source/objects/PsychVideoSprite.hx b/source/objects/PsychVideoSprite.hx
index ec65723..1371b08 100644
--- a/source/objects/PsychVideoSprite.hx
+++ b/source/objects/PsychVideoSprite.hx
@@ -1,10 +1,11 @@
package objects;
+import hxvlc.flixel.FlxVideoSprite as VideoSprite;
//Borrowed from Sonic Legacy for Free 4 Pirates
//i wanted a few things -data
//also srs moment fuck hxcodec its given me so many headaches. you was good in the past but we moved on bud!
-class PsychVideoSprite extends FlxVideoSprite
+class PsychVideoSprite extends VideoSprite
{
public static var heldVideos:Array = [];
diff --git a/source/states/PlayState.hx b/source/states/PlayState.hx
index 64575ce..61d0d18 100644
--- a/source/states/PlayState.hx
+++ b/source/states/PlayState.hx
@@ -129,6 +129,7 @@ using StringTools;
#elseif (hxCodec >= "2.6.1") import hxcodec.VideoHandler as VideoHandler;
#elseif (hxCodec == "2.6.0") import VideoHandler;
#else import vlc.MP4Handler as VideoHandler; #end
+import objects.PsychVideoSprite;
#end
class PlayState extends MusicBeatState
@@ -203,6 +204,7 @@ class PlayState extends MusicBeatState
#end
public var vocals:FlxSound;
+ public var opponentVocals:FlxSound;
public var inst:FlxSound;
public var dad:Character;
@@ -1110,8 +1112,8 @@ class PlayState extends MusicBeatState
playerSingAnimations = singAnimations;
- setOnLuas("mustHitSection", PlayState.SONG.notes[curSection].mustHitSection); //just so we can check the first section
- setOnLuas('gfSection', SONG.notes[curSection].gfSection); //forgot to check this one too.
+ setOnScripts("mustHitSection", PlayState.SONG.notes[curSection].mustHitSection); //just so we can check the first section
+ setOnScripts('gfSection', SONG.notes[curSection].gfSection); //forgot to check this one too.
callOnScripts('start', []);
callOnScripts('onCreate', []); //psych
@@ -1296,6 +1298,7 @@ class PlayState extends MusicBeatState
paused = true;
vocals.stop();
+ opponentVocals.stop();
FlxG.sound.music.stop();
var daX = boyfriend.getScreenPosition().x;
@@ -1367,14 +1370,14 @@ class PlayState extends MusicBeatState
if (SONG.notes[curSection].changeBPM)
{
Conductor.changeBPM(SONG.notes[curSection].bpm);
- setOnLuas('curBpm', Conductor.bpm);
- setOnLuas('crochet', Conductor.crochet);
- setOnLuas('stepCrochet', Conductor.stepCrochet);
+ setOnScripts('curBpm', Conductor.bpm);
+ setOnScripts('crochet', Conductor.crochet);
+ setOnScripts('stepCrochet', Conductor.stepCrochet);
}
- setOnLuas("mustHitSection", SONG.notes[curSection].mustHitSection);
+ setOnScripts("mustHitSection", SONG.notes[curSection].mustHitSection);
//setOnLuas('altAnim', SONG.notes[curSection].altAnim);
- setOnLuas('gfSection', SONG.notes[curSection].gfSection);
+ setOnScripts('gfSection', SONG.notes[curSection].gfSection);
}
setOnScripts('curSection', curSection);
@@ -2440,6 +2443,7 @@ class PlayState extends MusicBeatState
FlxG.sound.music.pause();
vocals.pause();
+ opponentVocals.pause();
FlxG.sound.music.time = time;
FlxG.sound.music.play();
@@ -2449,9 +2453,13 @@ class PlayState extends MusicBeatState
if (Conductor.songPosition <= vocals.length)
{
vocals.time = time;
+ opponentVocals.time = time;
+
FlxG.sound.music.pitch = playbackRate;
+ opponentVocals.pitch = playbackRate;
}
vocals.play();
+ opponentVocals.play();
songTime = time;
}
@@ -2484,21 +2492,21 @@ class PlayState extends MusicBeatState
generateStaticArrows(1, boyfriend.noteSkin, !skipArrowStartTween, daStartAlpha);
for (i in 0...playerStrums.length) {
- setOnLuas('defaultPlayerStrumX' + i, playerStrums.members[i].x);
- setOnLuas('defaultPlayerStrumY' + i, playerStrums.members[i].y);
+ setOnScripts('defaultPlayerStrumX' + i, playerStrums.members[i].x);
+ setOnScripts('defaultPlayerStrumY' + i, playerStrums.members[i].y);
}
for (i in 0...opponentStrums.length) {
- setOnLuas('defaultOpponentStrumX' + i, opponentStrums.members[i].x);
- setOnLuas('defaultOpponentStrumY' + i, opponentStrums.members[i].y);
+ setOnScripts('defaultOpponentStrumX' + i, opponentStrums.members[i].x);
+ setOnScripts('defaultOpponentStrumY' + i, opponentStrums.members[i].y);
}
//kade engine
- for (i in 0...strumLineNotes.length){
+ for (i in 0...strumLineNotes.length){//I wonder if someone still uses this...
var member = PlayState.instance.strumLineNotes.members[i];
- setOnLuas("defaultStrum" + i + "X", Math.floor(member.x));
- setOnLuas("defaultStrum" + i + "Y", Math.floor(member.y));
- setOnLuas("defaultStrum" + i + "Angle", Math.floor(member.angle));
- setOnLuas("defaultStrum" + i + "Alpha", Math.floor(member.alpha));
+ setOnScripts("defaultStrum" + i + "X", Math.floor(member.x));
+ setOnScripts("defaultStrum" + i + "Y", Math.floor(member.y));
+ setOnScripts("defaultStrum" + i + "Angle", Math.floor(member.angle));
+ setOnScripts("defaultStrum" + i + "Alpha", Math.floor(member.alpha));
}
callOnScripts('onStartCountdown', null, true);
@@ -2744,6 +2752,7 @@ class PlayState extends MusicBeatState
FlxG.sound.music.pitch = playbackRate;
FlxG.sound.music.onComplete = songOutro;
vocals.play();
+ opponentVocals.play();
if (ClientPrefs.data.psychUI)
{
@@ -2769,6 +2778,7 @@ class PlayState extends MusicBeatState
//trace('Oopsie doopsie! Paused sound');
FlxG.sound.music.pause();
vocals.pause();
+ opponentVocals.pause();
}
// Song duration in a float, useful for the time left feature
@@ -2838,7 +2848,7 @@ class PlayState extends MusicBeatState
curSong = songData.song;
- if (SONG.needsVoices)
+ /*if (SONG.needsVoices) //If the new system glitches out for some reason I'll just re-enable this
{
if (!Assets.exists(Paths.voices(PlayState.SONG.song)))
{
@@ -2851,13 +2861,54 @@ class PlayState extends MusicBeatState
vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.voices(PlayState.SONG.song));
}
else
- vocals = new FlxSound();
+ vocals = new FlxSound();*/
+
+ vocals = new FlxSound();
+ opponentVocals = new FlxSound();
+ try
+ {
+ if (SONG.needsVoices)//WHY THERES SO MANY VOICES FUNCTIONS
+ {
+ var playerVocals = Paths.voices(songData.song, (boyfriend.vocalsFile == null || boyfriend.vocalsFile.length < 1) ? 'Player' : boyfriend.vocalsFile);
+ if (!Assets.exists(playerVocals)) playerVocals = null;
+
+ var playerVocals2 = Paths.voices2(songData.song, (boyfriend.vocalsFile == null || boyfriend.vocalsFile.length < 1) ? 'Player' : boyfriend.vocalsFile);
+ if (!FileSystem.exists(playerVocals2)) playerVocals2 = null;
+
+ if (!Assets.exists(playerVocals))
+ if (FileSystem.exists(playerVocals2)) vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.currentTrackedSounds.exists(playerVocals2) ? Paths.currentTrackedSounds.get(playerVocals2) : Sound.fromFile(playerVocals2));
+ else if (!FileSystem.exists(playerVocals2))
+ if (Assets.exists(playerVocals)) vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(playerVocals);
+
+ if(playerVocals == null && playerVocals2 == null){ //don't talk to me.
+ if (!Assets.exists(Paths.voices(PlayState.SONG.song))){
+ if (Paths.currentTrackedSounds.exists(Paths.voices2(PlayState.SONG.song)))
+ vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.currentTrackedSounds.get(Paths.voices2(PlayState.SONG.song)));
+ else
+ vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Sound.fromFile(Paths.voices2(PlayState.SONG.song)));
+ }else
+ vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.voices(PlayState.SONG.song));
+ }
+
+ var oppVocals = Paths.voices(songData.song, (dad.vocalsFile == null || dad.vocalsFile.length < 1) ? 'Opponent' : dad.vocalsFile);
+ var oppVocals2 = Paths.voices2(songData.song, (dad.vocalsFile == null || dad.vocalsFile.length < 1) ? 'Opponent' : dad.vocalsFile);
+
+ if (!Assets.exists(oppVocals))
+ if (FileSystem.exists(oppVocals2)) opponentVocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.currentTrackedSounds.exists(oppVocals2) ? Paths.currentTrackedSounds.get(oppVocals2) : Sound.fromFile(oppVocals2));
+ else
+ if (Assets.exists(oppVocals)) opponentVocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(oppVocals);
+ }
+ }
+ catch(e:Dynamic) {}
+
trace('loaded vocals');
- vocals.looped = false;
- vocals.pitch = playbackRate;
- FlxG.sound.list.add(vocals);
+ vocals.looped = false;
+ vocals.pitch = playbackRate;
+ opponentVocals.pitch = playbackRate;
+ FlxG.sound.list.add(vocals);
+ FlxG.sound.list.add(opponentVocals);
notes = new FlxTypedGroup();
add(notes);
@@ -3115,6 +3166,7 @@ class PlayState extends MusicBeatState
{
FlxG.sound.music.pause();
vocals.pause();
+ opponentVocals.pause();
}
#if desktop
@@ -3166,6 +3218,10 @@ class PlayState extends MusicBeatState
for (timer in modchartTimers) {
timer.active = true;
}
+
+ #if VIDEOS_ALLOWED
+ PsychVideoSprite.globalResume();
+ #end
callOnScripts('onResume');
}
@@ -3177,6 +3233,7 @@ class PlayState extends MusicBeatState
public function resyncVocals():Void
{
vocals.pause();
+ opponentVocals.pause();
FlxG.sound.music.play();
FlxG.sound.music.pitch = playbackRate;
@@ -3186,10 +3243,17 @@ class PlayState extends MusicBeatState
vocals.time = Conductor.songPosition;
vocals.pitch = playbackRate;
}
+
+ if (Conductor.songPosition <= opponentVocals.length)
+ {
+ opponentVocals.time = Conductor.songPosition;
+ opponentVocals.pitch = playbackRate;
+ }
vocals.play();
+ opponentVocals.play();
#if desktop
- DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAcc: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | songMisses: " + songMisses , iconRPC);
+ DiscordClient.changePresence(detailsText + " " + SONG.song + " (" + storyDifficultyText + ") " + Ratings.GenerateLetterRank(accuracy), "\nAccuracy: " + HelperFunctions.truncateFloat(accuracy, 2) + "% | Score: " + songScore + " | Misses: " + songMisses , iconRPC);
#end
}
@@ -3248,8 +3312,13 @@ class PlayState extends MusicBeatState
if(FlxG.sound.music != null) {
FlxG.sound.music.pause();
vocals.pause();
+ opponentVocals.pause();
}
+ #if VIDEOS_ALLOWED
+ PsychVideoSprite.globalPause();
+ #end
+
isPaused = true;
openSubState(new substates.PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
//}
@@ -3292,10 +3361,10 @@ class PlayState extends MusicBeatState
#if desktop
if (songStarted)
{
- setOnLuas('songPos',Conductor.songPosition);
- setOnLuas('hudZoom', camHUD.zoom);
- setOnLuas('cameraZoom',FlxG.camera.zoom);
- callOnLuas('update', [elapsed]);
+ setOnScripts('songPos',Conductor.songPosition);
+ setOnScripts('hudZoom', camHUD.zoom);
+ setOnScripts('cameraZoom',FlxG.camera.zoom);
+ callOnScripts('update', [elapsed]);
if (luaWiggles != [])
{
@@ -3750,6 +3819,8 @@ class PlayState extends MusicBeatState
FlxG.sound.music.volume = 0;
vocals.volume = 0;
vocals.pause();
+ opponentVocals.volume = 0;
+ opponentVocals.pause();
canPause = false;
updateTime = false;
endingSong = true;
@@ -4472,9 +4543,10 @@ class PlayState extends MusicBeatState
function updateAccuracy(?badHit:Bool = false)
{
- setOnLuas('score', songScore);
- setOnLuas('misses', songMisses);
- setOnLuas('hits', songHits);
+ setOnScripts('score', songScore);
+ setOnScripts('misses', songMisses);
+ setOnScripts('hits', songHits);
+ setOnScripts('combo', combo);
var ret:Dynamic = callOnScripts('onRecalculateRating', null, true);
@@ -4503,9 +4575,9 @@ class PlayState extends MusicBeatState
callOnScripts('onUpdateScore', [badHit]);
- setOnLuas('rating', ratingPercent);
- setOnLuas('ratingName', ratingName);
- setOnLuas('ratingFC', ratingFC);
+ setOnScripts('rating', ratingPercent);
+ setOnScripts('ratingName', ratingName);
+ setOnScripts('ratingFC', ratingFC);
}
function getKeyPresses(note:Note):Int
@@ -4626,6 +4698,7 @@ class PlayState extends MusicBeatState
time += 0.15;
}
+ if(opponentVocals.length <= 0) vocals.volume = 1;
StrumPlayAnim(true, Std.int(Math.abs(note.noteData)), time);
note.hitByOpponent = true;
@@ -4901,6 +4974,7 @@ class PlayState extends MusicBeatState
usedTimeTravel = true;
FlxG.sound.music.pause();
vocals.pause();
+ opponentVocals.pause();
Conductor.songPosition = skipExactly;
notes.forEachAlive(function(daNote:Note)
{
@@ -4922,6 +4996,8 @@ class PlayState extends MusicBeatState
FlxG.sound.music.play();
vocals.time = Conductor.songPosition;
vocals.play();
+ opponentVocals.time = Conductor.songPosition;
+ opponentVocals.play();
new FlxTimer().start(0.5, function(tmr:FlxTimer)
{
usedTimeTravel = false;
@@ -4935,6 +5011,7 @@ class PlayState extends MusicBeatState
usedTimeTravel = true;
FlxG.sound.music.pause();
vocals.pause();
+ opponentVocals.pause();
Conductor.songPosition += 10000 * multiplier;
notes.forEachAlive(function(daNote:Note)
{
@@ -4956,6 +5033,8 @@ class PlayState extends MusicBeatState
FlxG.sound.music.play();
vocals.time = Conductor.songPosition;
vocals.play();
+ opponentVocals.time = Conductor.songPosition;
+ opponentVocals.play();
new FlxTimer().start(0.5, function(tmr:FlxTimer)
{
usedTimeTravel = false;
@@ -5158,12 +5237,13 @@ class PlayState extends MusicBeatState
if(generatedMusic)
{
if(vocals != null) vocals.pitch = value;
+ if(opponentVocals != null) opponentVocals.pitch = value;
FlxG.sound.music.pitch = value;
}
playbackRate = value;
FlxG.animationTimeScale = value;
//Conductor.safeZoneOffset = (FlxG.save.data.safeFrames / 60) * 1000 * value;
- setOnLuas('playbackRate', playbackRate);
+ setOnScripts('playbackRate', playbackRate);
adjustCamFollow();
return value;
@@ -5308,7 +5388,7 @@ class PlayState extends MusicBeatState
notes.sort(FlxSort.byY, (FlxG.save.data.downscroll ? FlxSort.ASCENDING : FlxSort.DESCENDING));
}
- setOnLuas('curBeat',curBeat);
+ setOnScripts('curBeat',curBeat);
callOnScripts('beatHit', [curBeat]);
callOnScripts('onBeatHit', [curBeat]);
diff --git a/source/states/editors/ChartingState.hx b/source/states/editors/ChartingState.hx
index 5484cf5..2a1d503 100644
--- a/source/states/editors/ChartingState.hx
+++ b/source/states/editors/ChartingState.hx
@@ -143,6 +143,7 @@ class ChartingState extends MusicBeatState
var gridBlackLine:FlxSprite;
var gridBlackLine2:FlxSprite;
var vocals:FlxSound;
+ var opponentVocals:FlxSound = null;
var leftIcon:HealthIcon;
var rightIcon:HealthIcon;
@@ -374,6 +375,9 @@ class ChartingState extends MusicBeatState
add(nextRenderedSustains);
add(nextRenderedNotes);
+ add(nextRenderedSustains);
+ add(nextRenderedNotes);
+
//loadEvents(); // it doesn't load the events unless I do this
updateGrid();
@@ -538,6 +542,7 @@ class ChartingState extends MusicBeatState
vol = 0;
vocals.volume = vol;
+ if(opponentVocals != null) opponentVocals.volume = vol;
}
};
@@ -1287,7 +1292,7 @@ class ChartingState extends MusicBeatState
eventPushedMap = null;
#end
- descText = new FlxText(20, 230, 0, eventStuff[0][0]);
+ descText = new FlxText(20, 210, 0, eventStuff[0][0]);
var leEvents:Array = [];
for (i in 0...eventStuff.length) {
@@ -1429,13 +1434,41 @@ class ChartingState extends MusicBeatState
else
FlxG.sound.playMusic(Paths.inst(daSong), 0.6);
- // WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER
- if (FileSystem.exists(Paths.voices2(daSong)))
- vocals = new FlxSound().loadEmbedded(Sound.fromFile(Paths.voices2(daSong)));
- else
- vocals = new FlxSound().loadEmbedded(Paths.voices(daSong));
+ try
+ {
+ var playerVocals = Paths.voices(daSong, (characterData.vocalsP1 == null || characterData.vocalsP1.length < 1) ? 'Player' : characterData.vocalsP1);
+ if (!Assets.exists(playerVocals)) playerVocals = null;
+
+ var playerVocals2 = Paths.voices2(daSong, (characterData.vocalsP1 == null || characterData.vocalsP1.length < 1) ? 'Player' : characterData.vocalsP1);
+ if (!FileSystem.exists(playerVocals2)) playerVocals2 = null;
+
+ if (!Assets.exists(playerVocals))
+ if (FileSystem.exists(playerVocals2)) vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.currentTrackedSounds.exists(playerVocals2) ? Paths.currentTrackedSounds.get(playerVocals2) : Sound.fromFile(playerVocals2));
+ else if (!FileSystem.exists(playerVocals2))
+ if (Assets.exists(playerVocals)) vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(playerVocals);
+
+ if(playerVocals == null && playerVocals2 == null){ //don't talk to me.
+ if (!Assets.exists(Paths.voices(PlayState.SONG.song))){
+ if (Paths.currentTrackedSounds.exists(Paths.voices2(PlayState.SONG.song)))
+ vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.currentTrackedSounds.get(Paths.voices2(PlayState.SONG.song)));
+ else
+ vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Sound.fromFile(Paths.voices2(PlayState.SONG.song)));
+ }else
+ vocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.voices(PlayState.SONG.song));
+ }
+ var oppVocals = Paths.voices(daSong, (characterData.vocalsP2 == null || characterData.vocalsP2.length < 1) ? 'Opponent' : characterData.vocalsP2);
+ var oppVocals2 = Paths.voices2(daSong, (characterData.vocalsP2 == null || characterData.vocalsP2.length < 1) ? 'Opponent' : characterData.vocalsP2);
+
+ if (!Assets.exists(oppVocals))
+ if (FileSystem.exists(oppVocals2)) opponentVocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(Paths.currentTrackedSounds.exists(oppVocals2) ? Paths.currentTrackedSounds.get(oppVocals2) : Sound.fromFile(oppVocals2));
+ else
+ if (Assets.exists(oppVocals)) opponentVocals = FlxG.sound.list.recycle(FlxSound).loadEmbedded(oppVocals);
+ }
+ catch(e:Dynamic) {}
+
FlxG.sound.list.add(vocals);
+ FlxG.sound.list.add(opponentVocals);
pauseMusic();
@@ -1450,11 +1483,16 @@ class ChartingState extends MusicBeatState
vocals.pause();
vocals.time = 0;
}
+ if(opponentVocals != null) {
+ opponentVocals.pause();
+ opponentVocals.time = 0;
+ }
changeSection();
curSec = 0;
updateGrid();
updateSectionUI();
vocals.play();
+ if (opponentVocals != null)opponentVocals.play();
};
}
@@ -1515,6 +1553,7 @@ class ChartingState extends MusicBeatState
updateGrid();
case "song_vocalvol":
vocals.volume = Math.max(nums.value, 0.1);
+ if (opponentVocals != null)opponentVocals.volume = Math.max(nums.value, 0.1);
case "section_dtype":
_song.notes[curSec].dType = Std.int(nums.value);
updateGrid();
@@ -1671,6 +1710,8 @@ class ChartingState extends MusicBeatState
Conductor.songPosition = FlxG.sound.music.time;
else if (vocals != null)
Conductor.songPosition = vocals.time;
+ else if (opponentVocals != null)
+ Conductor.songPosition = opponentVocals.time;
else
Conductor.songPosition = FlxG.sound.music.time; // it went back again?
@@ -1747,6 +1788,7 @@ class ChartingState extends MusicBeatState
FlxG.sound.music.pitch = playbackSpeed;
vocals.pitch = playbackSpeed;
+ if (opponentVocals != null)opponentVocals.pitch = playbackSpeed;
FlxG.watch.addQuick('daBeat', curBeat);
@@ -1811,6 +1853,7 @@ class ChartingState extends MusicBeatState
PlayState.SONG = _song;
FlxG.sound.music.stop();
vocals.stop();
+ if (opponentVocals != null) opponentVocals.stop();
if (FlxG.keys.pressed.SHIFT){
PlayState.startOnTime = Conductor.songPosition;
@@ -1891,6 +1934,7 @@ class ChartingState extends MusicBeatState
else
{
vocals.play();
+ if (opponentVocals != null)opponentVocals.play();
FlxG.sound.music.play();
lilBf.animation.play("idle");
@@ -1911,6 +1955,7 @@ class ChartingState extends MusicBeatState
pauseMusic();
FlxG.sound.music.time -= (FlxG.mouse.wheel * Conductor.stepCrochet * 0.4);
vocals.time = FlxG.sound.music.time;
+ if (opponentVocals != null)opponentVocals.time = FlxG.sound.music.time;
}
if (!FlxG.keys.pressed.SHIFT)
@@ -1933,6 +1978,7 @@ class ChartingState extends MusicBeatState
FlxG.sound.music.time += daTime;
vocals.time = FlxG.sound.music.time;
+ if (opponentVocals != null)opponentVocals.time = FlxG.sound.music.time;
}
}
else
@@ -1951,6 +1997,7 @@ class ChartingState extends MusicBeatState
FlxG.sound.music.time += daTime;
vocals.time = FlxG.sound.music.time;
+ if (opponentVocals != null)opponentVocals.time = FlxG.sound.music.time;
}
}
}
@@ -2141,6 +2188,7 @@ class ChartingState extends MusicBeatState
}
vocals.time = FlxG.sound.music.time;
+ if (opponentVocals != null)opponentVocals.time = FlxG.sound.music.time;
updateCurStep();
updateGrid();
@@ -2166,6 +2214,7 @@ class ChartingState extends MusicBeatState
FlxG.sound.music.time = sectionStartTime();
vocals.time = FlxG.sound.music.time;
+ if (opponentVocals != null)opponentVocals.time = FlxG.sound.music.time;
updateCurStep();
}
@@ -2199,6 +2248,48 @@ class ChartingState extends MusicBeatState
updateHeads();
}
+ var characterData:Dynamic = {
+ vocalsP1: null,
+ vocalsP2: null
+ };
+
+ function updateJsonData():Void
+ {
+ for (i in 1...3)
+ {
+ var data:CharacterFile = loadCharacterFile(Reflect.field(_song, 'player$i'));
+ Reflect.setField(characterData, 'vocalsP$i', data.vocals_file != null ? data.vocals_file : '');
+ }
+ }
+
+ var characterFailed:Bool = false;
+ function loadCharacterFile(char:String):CharacterFile {
+ characterFailed = false;
+ var characterPath:String = 'characters/' + char + '.json';
+ #if MODS_ALLOWED
+ var path:String = Paths.modFolders(characterPath);
+ if (!FileSystem.exists(path)) {
+ path = Paths.getSharedPath(characterPath);
+ }
+
+ if (!FileSystem.exists(path))
+ #else
+ var path:String = Paths.getSharedPath(characterPath);
+ if (!OpenFlAssets.exists(path))
+ #end
+ {
+ path = Paths.getSharedPath('characters/' + Character.DEFAULT_CHARACTER + '.json'); //If a character couldn't be found, change him to BF just to prevent a crash
+ characterFailed = true;
+ }
+
+ #if MODS_ALLOWED
+ var rawJson = File.getContent(path);
+ #else
+ var rawJson = OpenFlAssets.getText(path);
+ #end
+ return cast Json.parse(rawJson);
+ }
+
function updateHeads():Void
{
var healthIconP1:String = loadHealthIconFromCharacter(_song.player1);
@@ -3328,8 +3419,6 @@ class ChartingState extends MusicBeatState
}
}
}
-
-
#else
noteStyleList = CoolUtil.coolTextFile(Paths.txt('noteStyleList'));
#end
@@ -3343,6 +3432,9 @@ class ChartingState extends MusicBeatState
if (vocals != null){
vocals.pause();
}
+ if (opponentVocals != null){
+ opponentVocals.pause();
+ }
lilBf.animation.play("idle");
lilOpp.animation.play("idle");
diff --git a/source/substates/PauseSubState.hx b/source/substates/PauseSubState.hx
index f174ab5..a9c11d8 100644
--- a/source/substates/PauseSubState.hx
+++ b/source/substates/PauseSubState.hx
@@ -300,6 +300,7 @@ class PauseSubState extends MusicBeatSubstate
else
{
if (!useTransition){
+ FlxTransitionableState.skipNextTransIn = true;
FlxTransitionableState.skipNextTransOut = true;
}