Merge pull request #440 from theDetourist/replayoverhaul

Replay now uses Botplay to simulate previous sessions
This commit is contained in:
Kade M 2021-05-12 21:49:18 -07:00 committed by GitHub
commit fae01e17c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 3745 additions and 3741 deletions

View File

@ -1,239 +1,246 @@
package; package;
import openfl.Lib; import openfl.Lib;
#if windows #if windows
import llua.Lua; import llua.Lua;
#end #end
import Controls.Control; import Controls.Control;
import flixel.FlxG; import flixel.FlxG;
import flixel.FlxSprite; import flixel.FlxSprite;
import flixel.FlxSubState; import flixel.FlxSubState;
import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.FlxTransitionableState;
import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.input.keyboard.FlxKey; import flixel.input.keyboard.FlxKey;
import flixel.system.FlxSound; import flixel.system.FlxSound;
import flixel.text.FlxText; import flixel.text.FlxText;
import flixel.tweens.FlxEase; import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween; import flixel.tweens.FlxTween;
import flixel.util.FlxColor; import flixel.util.FlxColor;
class PauseSubState extends MusicBeatSubstate class PauseSubState extends MusicBeatSubstate
{ {
var grpMenuShit:FlxTypedGroup<Alphabet>; var grpMenuShit:FlxTypedGroup<Alphabet>;
var menuItems:Array<String> = ['Resume', 'Restart Song', 'Exit to menu']; var menuItems:Array<String> = ['Resume', 'Restart Song', 'Exit to menu'];
var curSelected:Int = 0; var curSelected:Int = 0;
var pauseMusic:FlxSound; var pauseMusic:FlxSound;
var perSongOffset:FlxText; var perSongOffset:FlxText;
var offsetChanged:Bool = false; var offsetChanged:Bool = false;
public function new(x:Float, y:Float) public function new(x:Float, y:Float)
{ {
super(); super();
pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true); pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true);
pauseMusic.volume = 0; pauseMusic.volume = 0;
pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2)));
FlxG.sound.list.add(pauseMusic); FlxG.sound.list.add(pauseMusic);
var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
bg.alpha = 0; bg.alpha = 0;
bg.scrollFactor.set(); bg.scrollFactor.set();
add(bg); add(bg);
var levelInfo:FlxText = new FlxText(20, 15, 0, "", 32); var levelInfo:FlxText = new FlxText(20, 15, 0, "", 32);
levelInfo.text += PlayState.SONG.song; levelInfo.text += PlayState.SONG.song;
levelInfo.scrollFactor.set(); levelInfo.scrollFactor.set();
levelInfo.setFormat(Paths.font("vcr.ttf"), 32); levelInfo.setFormat(Paths.font("vcr.ttf"), 32);
levelInfo.updateHitbox(); levelInfo.updateHitbox();
add(levelInfo); add(levelInfo);
var levelDifficulty:FlxText = new FlxText(20, 15 + 32, 0, "", 32); var levelDifficulty:FlxText = new FlxText(20, 15 + 32, 0, "", 32);
levelDifficulty.text += CoolUtil.difficultyString(); levelDifficulty.text += CoolUtil.difficultyString();
levelDifficulty.scrollFactor.set(); levelDifficulty.scrollFactor.set();
levelDifficulty.setFormat(Paths.font('vcr.ttf'), 32); levelDifficulty.setFormat(Paths.font('vcr.ttf'), 32);
levelDifficulty.updateHitbox(); levelDifficulty.updateHitbox();
add(levelDifficulty); add(levelDifficulty);
levelDifficulty.alpha = 0; levelDifficulty.alpha = 0;
levelInfo.alpha = 0; levelInfo.alpha = 0;
levelInfo.x = FlxG.width - (levelInfo.width + 20); levelInfo.x = FlxG.width - (levelInfo.width + 20);
levelDifficulty.x = FlxG.width - (levelDifficulty.width + 20); levelDifficulty.x = FlxG.width - (levelDifficulty.width + 20);
FlxTween.tween(bg, {alpha: 0.6}, 0.4, {ease: FlxEase.quartInOut}); FlxTween.tween(bg, {alpha: 0.6}, 0.4, {ease: FlxEase.quartInOut});
FlxTween.tween(levelInfo, {alpha: 1, y: 20}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.3}); FlxTween.tween(levelInfo, {alpha: 1, y: 20}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.3});
FlxTween.tween(levelDifficulty, {alpha: 1, y: levelDifficulty.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.5}); FlxTween.tween(levelDifficulty, {alpha: 1, y: levelDifficulty.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.5});
grpMenuShit = new FlxTypedGroup<Alphabet>(); grpMenuShit = new FlxTypedGroup<Alphabet>();
add(grpMenuShit); add(grpMenuShit);
perSongOffset = new FlxText(5, FlxG.height - 18, 0, "Additive Offset (Left, Right): " + PlayState.songOffset + " - Description - " + 'Adds value to global offset, per song.', 12); perSongOffset = new FlxText(5, FlxG.height - 18, 0, "Additive Offset (Left, Right): " + PlayState.songOffset + " - Description - " + 'Adds value to global offset, per song.', 12);
perSongOffset.scrollFactor.set(); perSongOffset.scrollFactor.set();
perSongOffset.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); perSongOffset.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
#if cpp #if cpp
add(perSongOffset); add(perSongOffset);
#end #end
for (i in 0...menuItems.length) for (i in 0...menuItems.length)
{ {
var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false); var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false);
songText.isMenuItem = true; songText.isMenuItem = true;
songText.targetY = i; songText.targetY = i;
grpMenuShit.add(songText); grpMenuShit.add(songText);
} }
changeSelection(); changeSelection();
cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]];
} }
override function update(elapsed:Float) override function update(elapsed:Float)
{ {
if (pauseMusic.volume < 0.5) if (pauseMusic.volume < 0.5)
pauseMusic.volume += 0.01 * elapsed; pauseMusic.volume += 0.01 * elapsed;
super.update(elapsed); super.update(elapsed);
var upP = controls.UP_P; var upP = controls.UP_P;
var downP = controls.DOWN_P; var downP = controls.DOWN_P;
var leftP = controls.LEFT_P; var leftP = controls.LEFT_P;
var rightP = controls.RIGHT_P; var rightP = controls.RIGHT_P;
var accepted = controls.ACCEPT; var accepted = controls.ACCEPT;
var oldOffset:Float = 0; var oldOffset:Float = 0;
var songPath = 'assets/data/' + PlayState.SONG.song.toLowerCase() + '/'; var songPath = 'assets/data/' + PlayState.SONG.song.toLowerCase() + '/';
if (upP) if (upP)
{ {
changeSelection(-1); changeSelection(-1);
}else if (downP) }else if (downP)
{ {
changeSelection(1); changeSelection(1);
} }
#if cpp #if cpp
else if (leftP) else if (leftP)
{ {
oldOffset = PlayState.songOffset; oldOffset = PlayState.songOffset;
PlayState.songOffset -= 1; PlayState.songOffset -= 1;
sys.FileSystem.rename(songPath + oldOffset + '.offset', songPath + PlayState.songOffset + '.offset'); sys.FileSystem.rename(songPath + oldOffset + '.offset', songPath + PlayState.songOffset + '.offset');
perSongOffset.text = "Additive Offset (Left, Right): " + PlayState.songOffset + " - Description - " + 'Adds value to global offset, per song.'; perSongOffset.text = "Additive Offset (Left, Right): " + PlayState.songOffset + " - Description - " + 'Adds value to global offset, per song.';
// Prevent loop from happening every single time the offset changes // Prevent loop from happening every single time the offset changes
if(!offsetChanged) if(!offsetChanged)
{ {
grpMenuShit.clear(); grpMenuShit.clear();
menuItems = ['Restart Song', 'Exit to menu']; menuItems = ['Restart Song', 'Exit to menu'];
for (i in 0...menuItems.length) for (i in 0...menuItems.length)
{ {
var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false); var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false);
songText.isMenuItem = true; songText.isMenuItem = true;
songText.targetY = i; songText.targetY = i;
grpMenuShit.add(songText); grpMenuShit.add(songText);
} }
changeSelection(); changeSelection();
cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]];
offsetChanged = true; offsetChanged = true;
} }
}else if (rightP) }else if (rightP)
{ {
oldOffset = PlayState.songOffset; oldOffset = PlayState.songOffset;
PlayState.songOffset += 1; PlayState.songOffset += 1;
sys.FileSystem.rename(songPath + oldOffset + '.offset', songPath + PlayState.songOffset + '.offset'); sys.FileSystem.rename(songPath + oldOffset + '.offset', songPath + PlayState.songOffset + '.offset');
perSongOffset.text = "Additive Offset (Left, Right): " + PlayState.songOffset + " - Description - " + 'Adds value to global offset, per song.'; perSongOffset.text = "Additive Offset (Left, Right): " + PlayState.songOffset + " - Description - " + 'Adds value to global offset, per song.';
if(!offsetChanged) if(!offsetChanged)
{ {
grpMenuShit.clear(); grpMenuShit.clear();
menuItems = ['Restart Song', 'Exit to menu']; menuItems = ['Restart Song', 'Exit to menu'];
for (i in 0...menuItems.length) for (i in 0...menuItems.length)
{ {
var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false); var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false);
songText.isMenuItem = true; songText.isMenuItem = true;
songText.targetY = i; songText.targetY = i;
grpMenuShit.add(songText); grpMenuShit.add(songText);
} }
changeSelection(); changeSelection();
cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]];
offsetChanged = true; offsetChanged = true;
} }
} }
#end #end
if (accepted) if (accepted)
{ {
var daSelected:String = menuItems[curSelected]; var daSelected:String = menuItems[curSelected];
switch (daSelected) switch (daSelected)
{ {
case "Resume": case "Resume":
close(); close();
case "Restart Song": case "Restart Song":
FlxG.resetState(); FlxG.resetState();
case "Exit to menu": case "Exit to menu":
PlayState.loadRep = false; if(PlayState.loadRep)
#if windows {
if (PlayState.luaModchart != null) FlxG.save.data.botplay = false;
{ FlxG.save.data.scrollSpeed = 1;
PlayState.luaModchart.die(); FlxG.save.data.downscroll = false;
PlayState.luaModchart = null; }
} PlayState.loadRep = false;
#end #if windows
if (FlxG.save.data.fpsCap > 290) if (PlayState.luaModchart != null)
(cast (Lib.current.getChildAt(0), Main)).setFPSCap(290); {
FlxG.switchState(new MainMenuState()); PlayState.luaModchart.die();
} PlayState.luaModchart = null;
} }
#end
if (FlxG.keys.justPressed.J) if (FlxG.save.data.fpsCap > 290)
{ (cast (Lib.current.getChildAt(0), Main)).setFPSCap(290);
// for reference later!
// PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null); FlxG.switchState(new MainMenuState());
} }
} }
override function destroy() if (FlxG.keys.justPressed.J)
{ {
pauseMusic.destroy(); // for reference later!
// PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null);
super.destroy(); }
} }
function changeSelection(change:Int = 0):Void override function destroy()
{ {
curSelected += change; pauseMusic.destroy();
if (curSelected < 0) super.destroy();
curSelected = menuItems.length - 1; }
if (curSelected >= menuItems.length)
curSelected = 0; function changeSelection(change:Int = 0):Void
{
var bullShit:Int = 0; curSelected += change;
for (item in grpMenuShit.members) if (curSelected < 0)
{ curSelected = menuItems.length - 1;
item.targetY = bullShit - curSelected; if (curSelected >= menuItems.length)
bullShit++; curSelected = 0;
item.alpha = 0.6; var bullShit:Int = 0;
// item.setGraphicSize(Std.int(item.width * 0.8));
for (item in grpMenuShit.members)
if (item.targetY == 0) {
{ item.targetY = bullShit - curSelected;
item.alpha = 1; bullShit++;
// item.setGraphicSize(Std.int(item.width));
} item.alpha = 0.6;
} // item.setGraphicSize(Std.int(item.width * 0.8));
}
} if (item.targetY == 0)
{
item.alpha = 1;
// item.setGraphicSize(Std.int(item.width));
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,101 +1,91 @@
#if sys #if sys
import sys.io.File; import sys.io.File;
#end #end
import Controls.Control; import Controls.Control;
import flixel.FlxG; import flixel.FlxG;
import openfl.events.IOErrorEvent; import openfl.events.IOErrorEvent;
import openfl.events.Event; import openfl.events.Event;
import openfl.net.FileReference; import openfl.net.FileReference;
import lime.utils.Assets; import lime.utils.Assets;
import haxe.Json; import haxe.Json;
import flixel.input.keyboard.FlxKey; import flixel.input.keyboard.FlxKey;
import openfl.utils.Dictionary; import openfl.utils.Dictionary;
typedef KeyPress = typedef ReplayJSON =
{ {
public var time:Float; public var replayGameVer:String;
public var key:String; public var timestamp:Date;
} public var songName:String;
public var songDiff:Int;
typedef KeyRelease = public var songNotes:Array<Float>;
{ public var noteSpeed:Float;
public var time:Float; public var isDownscroll:Bool;
public var key:String; }
}
class Replay
typedef ReplayJSON = {
{ public static var version:String = "1.0"; // replay file version
public var replayGameVer:String;
public var timestamp:Date; public var path:String = "";
public var songName:String; public var replay:ReplayJSON;
public var songDiff:Int; public function new(path:String)
public var keyPresses:Array<KeyPress>; {
public var keyReleases:Array<KeyRelease>; this.path = path;
} replay = {
songName: "Tutorial",
class Replay songDiff: 1,
{ noteSpeed: 1.5,
public static var version:String = "1.0"; // replay file version isDownscroll: false,
songNotes: [],
public var path:String = ""; replayGameVer: version,
public var replay:ReplayJSON; timestamp: Date.now()
public function new(path:String) };
{ }
this.path = path;
replay = { public static function LoadReplay(path:String):Replay
songName: "Tutorial", {
songDiff: 1, var rep:Replay = new Replay(path);
keyPresses: [],
keyReleases: [], rep.LoadFromJSON();
replayGameVer: version,
timestamp: Date.now() trace('basic replay data:\nSong Name: ' + rep.replay.songName + '\nSong Diff: ' + rep.replay.songDiff + '\nNotes Length: ' + rep.replay.songNotes.length);
};
} return rep;
}
public static function LoadReplay(path:String):Replay
{ public function SaveReplay(notearray:Array<Float>)
var rep:Replay = new Replay(path); {
var json = {
rep.LoadFromJSON(); "songName": PlayState.SONG.song.toLowerCase(),
"songDiff": PlayState.storyDifficulty,
trace('basic replay data:\nSong Name: ' + rep.replay.songName + '\nSong Diff: ' + rep.replay.songDiff + '\nKeys Length: ' + rep.replay.keyPresses.length); "noteSpeed": (FlxG.save.data.scrollSpeed > 1 ? FlxG.save.data.scrollSpeed : PlayState.SONG.speed),
"isDownscroll": FlxG.save.data.downscroll,
return rep; "songNotes": notearray,
} "timestamp": Date.now(),
"replayGameVer": version
public function SaveReplay() };
{
var json = { var data:String = Json.stringify(json);
"songName": PlayState.SONG.song.toLowerCase(),
"songDiff": PlayState.storyDifficulty, #if sys
"keyPresses": replay.keyPresses, File.saveContent("assets/replays/replay-" + PlayState.SONG.song + "-time" + Date.now().getTime() + ".kadeReplay", data);
"keyReleases": replay.keyReleases, #end
"timestamp": Date.now(), }
"replayGameVer": version
}; public function LoadFromJSON()
{
var data:String = Json.stringify(json); #if sys
trace('loading ' + Sys.getCwd() + 'assets/replays/' + path + ' replay...');
#if sys try
File.saveContent("assets/replays/replay-" + PlayState.SONG.song + "-time" + Date.now().getTime() + ".kadeReplay", data); {
#end var repl:ReplayJSON = cast Json.parse(File.getContent(Sys.getCwd() + "assets/replays/" + path));
} replay = repl;
}
catch(e)
public function LoadFromJSON() {
{ trace('failed!\n' + e.message);
#if sys }
trace('loading ' + Sys.getCwd() + 'assets/replays/' + path + ' replay...'); #end
try }
{
var repl:ReplayJSON = cast Json.parse(File.getContent(Sys.getCwd() + "assets/replays/" + path)); }
replay = repl;
}
catch(e)
{
trace('failed!\n' + e.message);
}
#end
}
}