Skip to content

Commit

Permalink
starting to get custom zip for player chars implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
KoloInDaCrib committed Nov 23, 2024
1 parent 170d1ab commit 43c1779
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 22 deletions.
74 changes: 56 additions & 18 deletions source/funkin/ui/debug/char/animate/CharSelectAtlasSprite.hx
Original file line number Diff line number Diff line change
Expand Up @@ -48,32 +48,46 @@ class CharSelectAtlasSprite extends FlxAnimate

super(x, y, assetPath, settings);

if (assetPath == null && zipBytes != null)
{
var animData:String = "";
var spritemapArray:Array<String> = [];
var imageMap:Map<String, BitmapData> = [];
if (assetPath == null && zipBytes != null) loadFromZip(zipBytes);

var zipFiles = funkin.util.FileUtil.readZIPFromBytes(zipBytes);
if (zipFiles.length == 0) return;
if (assetPath != null || zipBytes != null) initSymbols();
}

for (file in zipFiles)
{
if (file.fileName.indexOf("/") != -1) file.fileName = haxe.io.Path.withoutDirectory(file.fileName);
public function loadFromZip(zip:haxe.io.Bytes)
{
var animData:String = "";
var spritemapArray:Array<String> = [];
var imageMap:Map<String, BitmapData> = [];

if (file.fileName.indexOf("Animation.json") != -1) animData = CharCreatorUtil.normalizeJSONText(file.data.toString());
var zipFiles = funkin.util.FileUtil.readZIPFromBytes(zip);
if (zipFiles.length == 0) return;

if (file.fileName.startsWith("spritemap")
&& file.fileName.endsWith(".json")) spritemapArray.push(CharCreatorUtil.normalizeJSONText(file.data.toString()));
if (file.fileName.startsWith("spritemap")
&& file.fileName.endsWith(".png")) imageMap.set(file.fileName, BitmapData.fromBytes(file.data));
}
for (file in zipFiles)
{
if (file.fileName.indexOf("/") != -1) file.fileName = haxe.io.Path.withoutDirectory(file.fileName);

if (animData == "" || spritemapArray.length == 0 || imageMap.keys().array().length == 0) return;
if (file.fileName.indexOf("Animation.json") != -1) animData = CharCreatorUtil.normalizeJSONText(file.data.toString());

this.loadSeparateAtlas(animData, CharSelectAnimateFrames.fromTextureAtlas(spritemapArray, imageMap));
if (file.fileName.startsWith("spritemap")
&& file.fileName.endsWith(".json")) spritemapArray.push(CharCreatorUtil.normalizeJSONText(file.data.toString()));
if (file.fileName.startsWith("spritemap")
&& file.fileName.endsWith(".png")) imageMap.set(file.fileName, BitmapData.fromBytes(file.data));
}

if (animData == "" || spritemapArray.length == 0 || imageMap.keys().array().length == 0) return;

this.loadSeparateAtlas(animData, CharSelectAnimateFrames.fromTextureAtlas(spritemapArray, imageMap));

initSymbols();
}

var symbolsInitialized:Bool = false;

function initSymbols()
{
if (symbolsInitialized) return;

symbolsInitialized = true;
onAnimationComplete.add(cleanupAnimation);

// This defaults the sprite to play the first animation in the atlas,
Expand All @@ -90,6 +104,8 @@ class CharSelectAtlasSprite extends FlxAnimate
*/
public function listAnimations():Array<String>
{
if (!symbolsInitialized) return [];

var mainSymbol = this.anim.symbolDictionary[this.anim.stageInstance.symbol.name];
if (mainSymbol == null)
{
Expand All @@ -105,6 +121,7 @@ class CharSelectAtlasSprite extends FlxAnimate
*/
public function hasAnimation(id:String):Bool
{
if (!symbolsInitialized) return false;
return getLabelIndex(id) != -1 || anim.symbolDictionary.exists(id);
}

Expand All @@ -113,6 +130,7 @@ class CharSelectAtlasSprite extends FlxAnimate
*/
public function getCurrentAnimation():String
{
if (!symbolsInitialized) return "";
return this.currentAnimation;
}

Expand All @@ -135,6 +153,8 @@ class CharSelectAtlasSprite extends FlxAnimate
*/
public function playAnimation(id:String, restart:Bool = false, ignoreOther:Bool = false, loop:Bool = false, startFrame:Int = 0):Void
{
if (!symbolsInitialized) return;

// Skip if not allowed to play animations.
if ((!canPlayOtherAnims))
{
Expand Down Expand Up @@ -223,6 +243,7 @@ class CharSelectAtlasSprite extends FlxAnimate
*/
public function isAnimationFinished():Bool
{
if (!symbolsInitialized) return false;
return this.anim.finished;
}

Expand All @@ -232,6 +253,7 @@ class CharSelectAtlasSprite extends FlxAnimate
*/
public function isLoopComplete():Bool
{
if (!symbolsInitialized) return false;
if (this.anim == null) return false;
if (!this.anim.isPlaying) return false;

Expand All @@ -245,6 +267,7 @@ class CharSelectAtlasSprite extends FlxAnimate
*/
public function stopAnimation():Void
{
if (!symbolsInitialized) return;
if (this.currentAnimation == null) return;

this.anim.removeAllCallbacksFrom(getNextFrameLabel(this.currentAnimation));
Expand All @@ -254,17 +277,20 @@ class CharSelectAtlasSprite extends FlxAnimate

function addFrameCallback(label:String, callback:Void->Void):Void
{
if (!symbolsInitialized) return;
var frameLabel = this.anim.getFrameLabel(label);
frameLabel.add(callback);
}

function goToFrameLabel(label:String):Void
{
if (!symbolsInitialized) return;
this.anim.goToFrameLabel(label);
}

function getFrameLabelNames(?layer:haxe.extern.EitherType<Int, String> = null)
{
if (!symbolsInitialized) return [];
var labels = this.anim.getFrameLabels(layer);
var array = [];
for (label in labels)
Expand All @@ -277,28 +303,35 @@ class CharSelectAtlasSprite extends FlxAnimate

function getNextFrameLabel(label:String):String
{
if (!symbolsInitialized) return "";
return listAnimations()[(getLabelIndex(label) + 1) % listAnimations().length];
}

function getLabelIndex(label:String):Int
{
if (!symbolsInitialized) return -1;
return listAnimations().indexOf(label);
}

function goToFrameIndex(index:Int):Void
{
if (!symbolsInitialized) return;
this.anim.curFrame = index;
}

public function cleanupAnimation(_:String):Void
{
if (!symbolsInitialized) return;

canPlayOtherAnims = true;
// this.currentAnimation = null;
this.anim.pause();
}

function _onAnimationFrame(frame:Int):Void
{
if (!symbolsInitialized) return;

if (currentAnimation != null)
{
onAnimationFrame.dispatch(currentAnimation, frame);
Expand All @@ -323,6 +356,8 @@ class CharSelectAtlasSprite extends FlxAnimate

function _onAnimationComplete():Void
{
if (!symbolsInitialized) return;

if (currentAnimation != null)
{
onAnimationComplete.dispatch(currentAnimation);
Expand All @@ -337,6 +372,8 @@ class CharSelectAtlasSprite extends FlxAnimate

public function replaceFrameGraphic(index:Int, ?graphic:FlxGraphicAsset):Void
{
if (!symbolsInitialized) return;

if (graphic == null || !Assets.exists(graphic))
{
var prevFrame:Null<FlxFrame> = prevFrames.get(index);
Expand Down Expand Up @@ -375,6 +412,7 @@ class CharSelectAtlasSprite extends FlxAnimate

public function getPivotPosition():Null<FlxPoint>
{
if (!symbolsInitialized) return null;
return anim.curInstance.symbol.transformationPoint;
}

Expand Down
159 changes: 159 additions & 0 deletions source/funkin/ui/debug/char/components/wizard/AddPlayerFilesDialog.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package funkin.ui.debug.char.components.wizard;

import haxe.io.Path;
import haxe.ui.containers.HBox;
import haxe.ui.containers.dialogs.Dialogs.FileDialogExtensionInfo;
import haxe.ui.components.Button;
import haxe.ui.components.TextField;
import funkin.ui.debug.char.handlers.CharCreatorStartupWizard;
import funkin.util.FileUtil;
import flxanimate.data.AnimationData.AnimAtlas;
import flxanimate.data.SpriteMapData.AnimateAtlas;
import funkin.data.character.CharacterData.CharacterRenderType;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.FlxSprite;
import openfl.display.BitmapData;
import openfl.net.FileFilter;
import funkin.ui.debug.char.components.wizard.AddCharFilesDialog.UploadAssetsBox;

using StringTools;

// copy of AddCharFilesDialog lol
@:build(haxe.ui.macros.ComponentMacros.build("assets/exclude/data/ui/char-creator/wizard/add-assets.xml"))
class AddPlayerFilesDialog extends DefaultWizardDialog
{
override public function new()
{
super(UPLOAD_PLAYER_ASSETS);

addAssetsBox.addComponent(new UploadAssetsBox("Put the path to the Character Select .zip Data Here", FileUtil.FILE_EXTENSION_INFO_ZIP));
addAssetsBox.addComponent(new UploadAssetsBox("Put the path to the Freeplay DJ .zip Data Here", FileUtil.FILE_EXTENSION_INFO_ZIP));
}

override public function showDialog(modal:Bool = true):Void
{
super.showDialog(modal);

addAssetsBox.disabled = (!params.generatePlayerData || params.importedPlayerData != null);
}

override public function isNextStepAvailable():Bool
{
// we skippin if we aint even doin these
if (addAssetsBox.disabled) return true;

var uploadBoxes:Array<UploadAssetsBox> = [];
for (unsafeBox in addAssetsBox.childComponents)
{
if (!Std.isOfType(unsafeBox, UploadAssetsBox))
{
continue;
}
var box:UploadAssetsBox = cast unsafeBox;
if (box.daField.text == null || box.daField.text.length == 0)
{
continue;
}
uploadBoxes.push(box);
}

// check if the files even exist
for (thingy in uploadBoxes)
{
if (!FileUtil.doesFileExist(thingy.daField.text) && !openfl.Assets.exists(thingy.daField.text))
{
CharCreatorUtil.error("Add Files", "Path: " + thingy.daField.text + " doesn't exist. Is the spelling correct?");
return false;
}
}

// we do a little trollin
return typeCheck(uploadBoxes);
}

public function typeCheck(uploadBoxes:Array<UploadAssetsBox>):Bool
{
var allFiles = [params.charSelectFile, params.freeplayFile];

for (i in 0...uploadBoxes.length)
{
var zipPath = uploadBoxes[i].daField.text;

// checking if we even have the correct file types in the correct places
if (Path.extension(zipPath) != "zip")
{
CharCreatorUtil.error("Add Files", "The provided Path doesn't end with the supported format, (.zip).");
return false;
}

var zipBytes = CharCreatorUtil.gimmeTheBytes(zipPath);
if (zipBytes == null)
{
CharCreatorUtil.error("Add Files", "Error retrieving Bytes from the given Path.");
return false;
}

var zipFiles = FileUtil.readZIPFromBytes(zipBytes);
if (zipFiles.length == 0)
{
CharCreatorUtil.error("Add Files", "The provided .zip file has no content.");
return false;
}

var hasAnimData:Bool = false;
var hasSpritemapData:Bool = false;
var hasImageData:Bool = false;

for (entry in zipFiles)
{
if (entry.fileName.indexOf("/") != -1) entry.fileName = Path.withoutDirectory(entry.fileName);

if (entry.fileName.endsWith("Animation.json"))
{
var fileData = entry.data.toString();
var animData:AnimAtlas = haxe.Json.parse(CharCreatorUtil.normalizeJSONText(fileData));
if (animData == null)
{
CharCreatorUtil.error("Add Files", "Error parsing the Animation.json File.");
return false;
}

hasAnimData = true;
}

if (entry.fileName.startsWith("spritemap") && entry.fileName.endsWith(".json"))
{
var fileData = entry.data.toString();
var spritemapData:AnimateAtlas = haxe.Json.parse(CharCreatorUtil.normalizeJSONText(fileData));
if (spritemapData == null)
{
CharCreatorUtil.error("Add Files", "Error parsing the Spritemap.json File.");
return false;
}

hasSpritemapData = true;
}

if (entry.fileName.startsWith("spritemap") && entry.fileName.endsWith(".png"))
{
if (BitmapData.fromBytes(entry.data) == null)
{
CharCreatorUtil.error("Add Files", "Error parsing the Spritemap.png File.");
return false;
}
hasImageData = true;
}
}

if (hasAnimData && hasSpritemapData && hasImageData) allFiles[i] = {name: zipPath, bytes: zipBytes};

if (!(hasAnimData && hasSpritemapData && hasImageData))
{
CharCreatorUtil.error("Add Files", "Insufficient amount of Files in the .zip File.");
return false;
}
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class CharCreatorStartupWizard
dialogArray.push(new ImportDataDialog());
dialogArray.push(new RenderWizardDialog());
dialogArray.push(new AddCharFilesDialog());
dialogArray.push(new AddPlayerFilesDialog());
dialogArray.push(new ConfirmDialog());
}
}
Expand Down Expand Up @@ -86,6 +87,6 @@ enum abstract WizardStep(Int) from Int to Int
public var IMPORT_DATA = 1;
public var SELECT_CHAR_TYPE = 2;
public var UPLOAD_ASSETS = 3;
public var UPLOAD_PLAYER_ASSETS = -1; // not implemented yet!
public var CONFIRM = 4;
public var UPLOAD_PLAYER_ASSETS = 4;
public var CONFIRM = 5;
}
3 changes: 2 additions & 1 deletion source/funkin/ui/debug/char/pages/CharCreatorFreeplayPage.hx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ class CharCreatorFreeplayPage extends CharCreatorDefaultPage

var playuh = PlayerRegistry.instance.fetchEntry(data.importedPlayerData ?? "");

dj = new CharSelectAtlasSprite(640, 366, null, playuh?.getFreeplayDJData()?.getAtlasPath() != null ? playuh.getFreeplayDJData().getAtlasPath() : null);
dj = new CharSelectAtlasSprite(640, 366, data.freeplayFile?.bytes,
playuh?.getFreeplayDJData()?.getAtlasPath() != null ? playuh.getFreeplayDJData().getAtlasPath() : null);
add(dj);

generateUI();
Expand Down
Loading

0 comments on commit 43c1779

Please sign in to comment.