A LOT OF NEW STUFF + more vslice events WIP
JUST GOTTA MAKE THE TWEEN ON THE CAMERA MOVEMENT FRUNCTION PROPERLY AND WE'RE GOOD (and also make the charter not save not changed paramteres)
This commit is contained in:
@@ -10,17 +10,48 @@ import openfl.Assets;
|
||||
using StringTools;
|
||||
|
||||
class EventsData {
|
||||
public static var defaultEventsList:Array<String> = ["HScript Call", "Camera Movement", "Add Camera Zoom", "Camera Modulo Change", "Camera Flash", "BPM Change", "Scroll Speed Change", "Alt Animation Toggle", "Play Animation"];
|
||||
public static var defaultEventsList:Array<String> = ["HScript Call", "Camera Movement", "Add Camera Zoom", "Camera Zoom", "Camera Modulo Change", "Camera Flash", "BPM Change", "Scroll Speed Change", "Alt Animation Toggle", "Play Animation"];
|
||||
public static var defaultEventsParams:Map<String, Array<EventParamInfo>> = [
|
||||
"HScript Call" => [
|
||||
{name: "Function Name", type: TString, defValue: "myFunc"},
|
||||
{name: "Function Parameters (String split with commas)", type: TString, defValue: ""}
|
||||
],
|
||||
"Camera Movement" => [{name: "Camera Target", type: TStrumLine, defValue: 0}],
|
||||
"Camera Movement" => [
|
||||
{name: "Camera Target", type: TStrumLine, defValue: 0},
|
||||
{name: "Tween Movement?", type: TBool, defValue: true},
|
||||
{name: "Tween Time (Steps, IF NOT CLASSIC)", type: TFloat(0.25, 9999, 0.25, 2), defValue: 4},
|
||||
{
|
||||
name: "Tween Ease (ex: circ, quad, cube)",
|
||||
type: TDropDown(['CLASSIC', 'linear', 'back', 'bounce', 'circ', 'cube', 'elastic', 'expo', 'quad', 'quart', 'quint', 'sine', 'smoothStep', 'smootherStep']),
|
||||
defValue: "CLASSIC"
|
||||
},
|
||||
{
|
||||
name: "Tween Type (excluded if CLASSIC or linear, ex: InOut)",
|
||||
type: TDropDown(['In', 'Out', 'InOut']),
|
||||
defValue: "In"
|
||||
}
|
||||
],
|
||||
"Add Camera Zoom" => [
|
||||
{name: "Amount", type: TFloat(-10, 10, 0.01, 2), defValue: 0.05},
|
||||
{name: "Camera", type: TDropDown(['camGame', 'camHUD']), defValue: "camGame"}
|
||||
],
|
||||
"Camera Zoom" => [
|
||||
{name: "Tween Zoom?", type: TBool, defValue: true},
|
||||
{name: "New Zoom", type: TFloat(-10, 10, 0.01, 2), defValue: 1},
|
||||
{name: "Camera", type: TDropDown(['camGame', 'camHUD']), defValue: "camGame"},
|
||||
{name: "Tween Time (Steps)", type: TFloat(0.25, 9999, 0.25, 2), defValue: 4},
|
||||
{
|
||||
name: "Tween Ease (ex: circ, quad, cube)",
|
||||
type: TDropDown(['linear', 'back', 'bounce', 'circ', 'cube', 'elastic', 'expo', 'quad', 'quart', 'quint', 'sine', 'smoothStep', 'smootherStep']),
|
||||
defValue: "linear"
|
||||
},
|
||||
{
|
||||
name: "Tween Type (excluded if linear, ex: InOut)",
|
||||
type: TDropDown(['In', 'Out', 'InOut']),
|
||||
defValue: "In"
|
||||
},
|
||||
{name: "Multiplicative?", type: TBool, defValue: false}
|
||||
],
|
||||
"Camera Modulo Change" => [
|
||||
{name: "Modulo Interval (Beats)", type: TInt(1, 9999999, 1), defValue: 4},
|
||||
{name: "Bump Strength", type: TFloat(0.1, 10, 0.01, 2), defValue: 1}
|
||||
@@ -42,10 +73,11 @@ class EventsData {
|
||||
defValue: "linear"
|
||||
},
|
||||
{
|
||||
name: "Tween Type (ex: InOut)",
|
||||
name: "Tween Type (excluded if linear, ex: InOut)",
|
||||
type: TDropDown(['In', 'Out', 'InOut']),
|
||||
defValue: "In"
|
||||
}
|
||||
},
|
||||
{name: "Multiplicative?", type: TBool, defValue: false}
|
||||
],
|
||||
"Alt Animation Toggle" => [{name: "Enable On Sing Poses", type: TBool, defValue: true}, {name: "Enable On Idle", type: TBool, defValue: true}, {name: "Strumline", type: TStrumLine, defValue: 0}],
|
||||
"Play Animation" => [{name: "Character", type: TStrumLine, defValue: 0}, {name: "Animation", type: TString, defValue: "animation"}, {name: "Is forced?", type: TBool, defValue: true}],
|
||||
|
||||
@@ -45,8 +45,8 @@ class VSliceParser {
|
||||
for (note in data)
|
||||
{
|
||||
var daNoteType:Null<Int> = null;
|
||||
if (note.k != null) // TODO: check if kind is alt maybe - Nex
|
||||
daNoteType = Chart.addNoteType(result, note.k);
|
||||
if (note.k != null)
|
||||
daNoteType = Chart.addNoteType(result, note.k == "alt" ? "Alt Anim Note" : note.k); // they hardcoded "alt" for converting old charts BUT THEN WHY THE HELL WOULD YOU CALL "MOM" THE NOTE KIND IN WEEK5 GRAHHH - Nex
|
||||
|
||||
var daNoteData:Int = Std.int(note.d % 8);
|
||||
var isMustHit:Bool = Math.floor(daNoteData / 4) == 0;
|
||||
@@ -76,13 +76,42 @@ class VSliceParser {
|
||||
|
||||
for (event in events)
|
||||
{
|
||||
var values = event.v;
|
||||
switch (event.e)
|
||||
{
|
||||
case "FocusCamera":
|
||||
result.events.push({
|
||||
time: event.t,
|
||||
name: "Camera Movement",
|
||||
params: [event.v.char]
|
||||
params: [values.char == -1 ? 2 : values.char, values.ease != "INSTANT", values.duration == null ? 4 : values.duration, values.ease == null || values.ease == "INSTANT" ? "CLASSIC" : values.ease, ""]
|
||||
});
|
||||
case "PlayAnimation":
|
||||
result.events.push({
|
||||
time: event.t,
|
||||
name: "Play Animation",
|
||||
params: [switch(values.target) {
|
||||
case 'boyfriend' | 'bf' | 'player': 1;
|
||||
case 'dad' | 'opponent': 0;
|
||||
default /*case 'girlfriend' | 'gf'*/: 2; // usually the default should be the stage prop but we dont have that sooo - Nex
|
||||
}, values.anim, values.force == null ? false : values.force]
|
||||
});
|
||||
case "ScrollSpeed":
|
||||
result.events.push({
|
||||
time: event.t,
|
||||
name: "Scroll Speed Change", // we dont support the strumline value and also i will put the whole ease name into a single parameter since it works anyways - Nex
|
||||
params: [values.ease != "INSTANT", values.scroll == null ? 1 : values.scroll, values.duration == null ? 4 : values.duration, values.ease == null || values.ease == "INSTANT" ? "linear" : values.ease, "", values.absolute != true]
|
||||
});
|
||||
case "SetCameraBop":
|
||||
result.events.push({
|
||||
time: event.t,
|
||||
name: "Camera Modulo Change",
|
||||
params: [values.rate == null ? 4 : values.rate, values.intensity == null ? 1 : values.intensity]
|
||||
});
|
||||
case "ZoomCamera":
|
||||
result.events.push({
|
||||
time: event.t,
|
||||
name: "Camera Zoom", // we dont support the direct mode since welp, its kind of useless here - Nex
|
||||
params: [values.ease != "INSTANT", values.zoom == null ? 1 : values.zoom, "camGame", values.duration == null ? 4 : values.duration, values.ease == null || values.ease == "INSTANT" ? "linear" : values.ease, "", false]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ class Flags {
|
||||
public static var DEFAULT_CAM_ZOOM_STRENGTH:Int = 1;
|
||||
public static var DEFAULT_CAM_ZOOM:Float = 1.05; // what zoom level it defaults to
|
||||
public static var DEFAULT_HUD_ZOOM:Float = 1.0;
|
||||
public static var MAX_CAMERA_ZOOM:Float = 1.35;
|
||||
public static var MAX_CAMERA_ZOOM_MULT:Float = 1.35;
|
||||
|
||||
public static var DEFAULT_PAUSE_ITEMS:Array<String> = ['Resume', 'Restart Song', 'Change Controls', 'Change Options', 'Exit to menu', "Exit to charter"];
|
||||
public static var DEFAULT_CUTSCENE_PAUSE_ITEMS:Array<String> = ['Resume Cutscene', 'Skip Cutscene', 'Restart Cutscene', 'Exit to menu'];
|
||||
|
||||
@@ -819,8 +819,8 @@ class CoolUtil
|
||||
* @param mainEase Main ease
|
||||
* @param suffix Suffix (Ignored if `mainEase` is `linear`)
|
||||
*/
|
||||
@:noUsing public static inline function flxeaseFromString(mainEase:String, suffix:String)
|
||||
return Reflect.field(FlxEase, mainEase + (mainEase == "linear" ? "" : suffix));
|
||||
@:noUsing public static inline function flxeaseFromString(mainEase:String, ?suffix:String)
|
||||
return Reflect.field(FlxEase, mainEase + (mainEase == "linear" || suffix == null ? "" : suffix));
|
||||
|
||||
/**
|
||||
* Sorts an array alphabetically.
|
||||
|
||||
+119
-48
@@ -7,6 +7,7 @@ import flixel.math.FlxPoint;
|
||||
import flixel.sound.FlxSound;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.tweens.misc.VarTween;
|
||||
import flixel.ui.FlxBar;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.FlxSort;
|
||||
@@ -18,9 +19,9 @@ import funkin.backend.chart.EventsData;
|
||||
import funkin.backend.scripting.DummyScript;
|
||||
import funkin.backend.scripting.Script;
|
||||
import funkin.backend.scripting.ScriptPack;
|
||||
import funkin.backend.scripting.events.*;
|
||||
import funkin.backend.scripting.events.gameplay.*;
|
||||
import funkin.backend.scripting.events.note.*;
|
||||
import funkin.backend.scripting.events.*;
|
||||
import funkin.backend.system.Conductor;
|
||||
import funkin.backend.system.RotatingSpriteGroup;
|
||||
import funkin.editors.SaveWarning;
|
||||
@@ -138,8 +139,8 @@ class PlayState extends MusicBeatState
|
||||
*/
|
||||
public var downscroll(get, set):Bool;
|
||||
|
||||
@:dox(hide) private function set_downscroll(v:Bool) {return camHUD.downscroll = v;}
|
||||
@:dox(hide) private function get_downscroll():Bool {return camHUD.downscroll;}
|
||||
private inline function set_downscroll(v:Bool) return camHUD.downscroll = v;
|
||||
private inline function get_downscroll():Bool return camHUD.downscroll;
|
||||
|
||||
/**
|
||||
* Instrumental sound (Inst.ogg).
|
||||
@@ -225,23 +226,6 @@ class PlayState extends MusicBeatState
|
||||
*/
|
||||
public var doIconBop:Bool = true;
|
||||
|
||||
/**
|
||||
* Whenever cam zooming is enabled, enables on a note hit if not cancelled.
|
||||
*/
|
||||
public var camZooming:Bool = false;
|
||||
/**
|
||||
* Interval of cam zooming (beats).
|
||||
* For example: if set to 4, the camera will zoom every 4 beats.
|
||||
*/
|
||||
public var camZoomingInterval:Int = Flags.DEFAULT_CAM_ZOOM_INTERVAL;
|
||||
/**
|
||||
* How strong the cam zooms should be (defaults to 1)
|
||||
*/
|
||||
public var camZoomingStrength:Float = Flags.DEFAULT_CAM_ZOOM_STRENGTH;
|
||||
/**
|
||||
* Maximum amount of zoom for the camera.
|
||||
*/
|
||||
public var maxCamZoom:Float = Flags.MAX_CAMERA_ZOOM;
|
||||
/**
|
||||
* Current song name (lowercase)
|
||||
*/
|
||||
@@ -383,6 +367,30 @@ class PlayState extends MusicBeatState
|
||||
*/
|
||||
public var camHUDZoomLerp:Float = Flags.DEFAULT_HUD_ZOOM_LERP;
|
||||
|
||||
/**
|
||||
* Whenever cam zooming is enabled, enables on a note hit if not cancelled.
|
||||
*/
|
||||
public var camZooming:Bool = false;
|
||||
/**
|
||||
* Interval of cam zooming (beats).
|
||||
* For example: if set to 4, the camera will zoom every 4 beats.
|
||||
*/
|
||||
public var camZoomingInterval:Int = Flags.DEFAULT_CAM_ZOOM_INTERVAL;
|
||||
/**
|
||||
* How strong the cam zooms should be (defaults to 1)
|
||||
*/
|
||||
public var camZoomingStrength:Float = Flags.DEFAULT_CAM_ZOOM_STRENGTH;
|
||||
/**
|
||||
* Default multiplier for `maxCamZoom`.
|
||||
*/
|
||||
public var maxCamZoomMult:Float = Flags.MAX_CAMERA_ZOOM_MULT;
|
||||
/**
|
||||
* Maximum amount of zoom for the camera (based on `maxCamZoomMult` and the camera's zoom IF not set).
|
||||
*/
|
||||
public var maxCamZoom(get, default):Float = Math.NaN;
|
||||
|
||||
private inline function get_maxCamZoom() return Math.isNaN(maxCamZoom) ? maxCamZoomMult * defaultCamZoom : maxCamZoom;
|
||||
|
||||
/**
|
||||
* Zoom for the pixel assets.
|
||||
*/
|
||||
@@ -849,6 +857,7 @@ class PlayState extends MusicBeatState
|
||||
|
||||
/**
|
||||
* Function used to update Discord Presence.
|
||||
*
|
||||
* This function is dynamic, which means you can do `updateDiscordPresence = function() {}` in scripts.
|
||||
*/
|
||||
public dynamic function updateDiscordPresence()
|
||||
@@ -1029,10 +1038,16 @@ class PlayState extends MusicBeatState
|
||||
Note.__customNoteTypeExists = [];
|
||||
}
|
||||
|
||||
// keping this for backwards compat - Nex
|
||||
@:deprecated("resetSongInfos is deprecated, it's now handled in the loading song/weeks functions")
|
||||
// Backwards compat
|
||||
@:dox(hide) @:deprecated("resetSongInfos is deprecated, it's now handled in the loading song/weeks functions")
|
||||
public static function resetSongInfos() {}
|
||||
|
||||
@:dox(hide) @:deprecated("scrollSpeedTween is deprecated, use eventsTween['scrollSpeed'] instead")
|
||||
public var scrollSpeedTween(get, set):FlxTween;
|
||||
private inline function get_scrollSpeedTween() return eventsTween.get("scrollSpeed");
|
||||
private inline function set_scrollSpeedTween(val:FlxTween) {eventsTween.set("scrollSpeed", val); return val;}
|
||||
// End of backwards compat
|
||||
|
||||
@:dox(hide) private function generateSong(?songData:ChartData):Void
|
||||
{
|
||||
if (songData == null) songData = SONG;
|
||||
@@ -1342,28 +1357,8 @@ class PlayState extends MusicBeatState
|
||||
while(events.length > 0 && events.last().time <= Conductor.songPosition)
|
||||
executeEvent(events.pop());
|
||||
|
||||
if (generatedMusic && strumLines.members[curCameraTarget] != null)
|
||||
{
|
||||
var pos = FlxPoint.get();
|
||||
var r = 0;
|
||||
for(c in strumLines.members[curCameraTarget].characters) {
|
||||
if (c == null || !c.visible) continue;
|
||||
var cpos = c.getCameraPosition();
|
||||
pos.x += cpos.x;
|
||||
pos.y += cpos.y;
|
||||
r++;
|
||||
//cpos.put();
|
||||
}
|
||||
if (r > 0) {
|
||||
pos.x /= r;
|
||||
pos.y /= r;
|
||||
|
||||
var event = gameAndCharsEvent("onCameraMove", EventManager.get(CamMoveEvent).recycle(pos, strumLines.members[curCameraTarget], r));
|
||||
if (!event.cancelled)
|
||||
camFollow.setPosition(pos.x, pos.y);
|
||||
}
|
||||
pos.put();
|
||||
}
|
||||
if (generatedMusic)
|
||||
moveCamera();
|
||||
|
||||
if (camZooming)
|
||||
{
|
||||
@@ -1400,7 +1395,48 @@ class PlayState extends MusicBeatState
|
||||
scripts.event("postDraw", e);
|
||||
}
|
||||
|
||||
public var scrollSpeedTween:FlxTween = null;
|
||||
public function moveCamera() if (strumLines.members[curCameraTarget] != null) {
|
||||
var pos = FlxPoint.weak();
|
||||
var amount = calculateCamPos(strumLines.members[curCameraTarget].characters, pos);
|
||||
|
||||
var tween = eventsTween.get("cameraMovement");
|
||||
if (tween != null && !tween.finished && tween is VarTween) {
|
||||
var tween:VarTween = cast tween;
|
||||
@:privateAccess pos.set(tween._object.x, tween._object.y);
|
||||
}
|
||||
|
||||
if (amount > 0) {
|
||||
var event = gameAndCharsEvent("onCameraMove", EventManager.get(CamMoveEvent).recycle(pos, strumLines.members[curCameraTarget], amount));
|
||||
if (!event.cancelled)
|
||||
camFollow.setPosition(pos.x, pos.y);
|
||||
}
|
||||
pos.put();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used to calculate the camera position based on the characters.
|
||||
*
|
||||
* This function is dynamic, which means you can do `calculateCamPos = function(chars:Array<Character>, pos:FlxPoint) {}` in scripts.
|
||||
*/
|
||||
public dynamic function calculateCamPos(chars:Array<Character>, pos:FlxPoint):Int {
|
||||
var r:Int = 0;
|
||||
for (c in chars) {
|
||||
if (c == null || !c.visible) continue;
|
||||
var cpos = c.getCameraPosition();
|
||||
pos.x += cpos.x;
|
||||
pos.y += cpos.y;
|
||||
r++;
|
||||
}
|
||||
|
||||
if (r > 0) {
|
||||
pos.x /= r;
|
||||
pos.y /= r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public var eventsTween:Map<String, FlxTween> = [];
|
||||
|
||||
public function executeEvent(event:ChartEvent) @:privateAccess {
|
||||
if (event == null || event.params == null) return;
|
||||
@@ -1414,10 +1450,41 @@ class PlayState extends MusicBeatState
|
||||
case "HScript Call":
|
||||
scripts.call(event.params[0], event.params[1].split(','));
|
||||
case "Camera Movement":
|
||||
var tween = eventsTween.get("cameraMovement");
|
||||
if (tween != null) tween.cancel();
|
||||
|
||||
curCameraTarget = event.params[0];
|
||||
if (strumLines.members[curCameraTarget] != null) {
|
||||
if (event.params[1] == false) {
|
||||
moveCamera();
|
||||
FlxG.camera.snapToTarget();
|
||||
} else if (event.params[3] != "CLASSIC" && strumLines.members[curCameraTarget] != null) {
|
||||
var pos = FlxPoint.weak(), finalPos = FlxPoint.weak(); // pos will be handled in update() through the tween map - Nex
|
||||
if (calculateCamPos(strumLines.members[curCameraTarget].characters, finalPos) > 0)
|
||||
eventsTween.set("cameraMovement", FlxTween.tween(pos, {x: finalPos.x, y: finalPos.y}, (Conductor.stepCrochet / 1000) * event.params[2], {ease: CoolUtil.flxeaseFromString(event.params[3], event.params[4])}));
|
||||
}
|
||||
}
|
||||
case "Add Camera Zoom":
|
||||
var camera:FlxCamera = event.params[1] == "camHUD" ? camHUD : camGame;
|
||||
camera.zoom += event.params[0];
|
||||
case "Camera Zoom":
|
||||
var cam = event.params[2] == "camHUD" ? camHUD : camGame;
|
||||
var name = (event.params[2] == "camHUD" ? "camHUD" : "camGame") + ".zoom"; // avoiding having different values from these 2 - Nex
|
||||
var tween = eventsTween.get(name);
|
||||
if (tween != null) tween.cancel();
|
||||
|
||||
var finalZoom:Float = event.params[1];
|
||||
if (event.params[6] == true) finalZoom *= cam.zoom;
|
||||
|
||||
if (event.params[0] == false) {
|
||||
cam.zoom = finalZoom;
|
||||
if (cam == camHUD) defaultHudZoom = finalZoom;
|
||||
else defaultCamZoom = finalZoom;
|
||||
} else
|
||||
eventsTween.set(name, FlxTween.tween(cam, {zoom: finalZoom}, (Conductor.stepCrochet / 1000) * event.params[3], {ease: CoolUtil.flxeaseFromString(event.params[4], event.params[5]), onUpdate: function(_) {
|
||||
if (cam == camHUD) defaultHudZoom = cam.zoom;
|
||||
else defaultCamZoom = cam.zoom;
|
||||
}}));
|
||||
case "Camera Modulo Change":
|
||||
camZoomingInterval = event.params[0];
|
||||
camZoomingStrength = event.params[1];
|
||||
@@ -1430,12 +1497,16 @@ class PlayState extends MusicBeatState
|
||||
camera.flash(event.params[1], (Conductor.stepCrochet / 1000) * event.params[2], null, true);
|
||||
case "BPM Change": // automatically handled by conductor
|
||||
case "Scroll Speed Change":
|
||||
if (scrollSpeedTween != null) scrollSpeedTween.cancel();
|
||||
var tween = eventsTween.get("scrollSpeedTween");
|
||||
if (tween != null) tween.cancel();
|
||||
|
||||
var finalScroll:Float = event.params[1];
|
||||
if (event.params[5] == true) finalScroll *= scrollSpeed;
|
||||
|
||||
if (event.params[0] == false)
|
||||
scrollSpeed = event.params[1];
|
||||
scrollSpeed = finalScroll;
|
||||
else
|
||||
scrollSpeedTween = FlxTween.tween(this, {scrollSpeed: event.params[1]}, (Conductor.stepCrochet / 1000) * event.params[2], {ease: CoolUtil.flxeaseFromString(event.params[3], event.params[4])});
|
||||
eventsTween.set("scrollSpeedTween", FlxTween.tween(this, {scrollSpeed: finalScroll}, (Conductor.stepCrochet / 1000) * event.params[2], {ease: CoolUtil.flxeaseFromString(event.params[3], event.params[4])}));
|
||||
case "Alt Animation Toggle":
|
||||
var strLine = strumLines.members[event.params[2]];
|
||||
if (strLine != null) {
|
||||
|
||||
Reference in New Issue
Block a user