Continuous bpm change event, lots of other reworks and fixes
This commit is contained in:
@@ -843,6 +843,7 @@ class Charter extends UIState {
|
||||
if (s is CharterNote) cast(s, CharterNote).snappedToStrumline = true;
|
||||
if (s is UISprite) cast(s, UISprite).cursor = BUTTON;
|
||||
}
|
||||
checkSelectionForBPMUpdates();
|
||||
if (!(verticalChange == 0 && horizontalChange == 0)) {
|
||||
notesGroup.sortNotes(); eventsGroup.sortEvents();
|
||||
undos.addToUndo(CSelectionDrag(undoDrags));
|
||||
@@ -1031,11 +1032,7 @@ class Charter extends UIState {
|
||||
notesGroup.sortNotes();
|
||||
notesGroup.autoSort = true;
|
||||
|
||||
for (s in selection)
|
||||
if (s is CharterEvent) {
|
||||
Charter.instance.updateBPMEvents();
|
||||
break;
|
||||
}
|
||||
checkSelectionForBPMUpdates();
|
||||
|
||||
if (addToUndo)
|
||||
undos.addToUndo(CCreateSelection(selection));
|
||||
@@ -1059,11 +1056,7 @@ class Charter extends UIState {
|
||||
notesGroup.sortNotes();
|
||||
notesGroup.autoSort = true;
|
||||
|
||||
for (s in selection)
|
||||
if (s is CharterEvent) {
|
||||
Charter.instance.updateBPMEvents();
|
||||
break;
|
||||
}
|
||||
checkSelectionForBPMUpdates();
|
||||
|
||||
if (addToUndo)
|
||||
undos.addToUndo(CDeleteSelection(selection));
|
||||
@@ -1432,6 +1425,8 @@ class Charter extends UIState {
|
||||
selection = sObjects;
|
||||
_edit_copy(_); // to fix stupid bugs
|
||||
|
||||
checkSelectionForBPMUpdates();
|
||||
|
||||
undos.addToUndo(CCreateSelection(sObjects.copy()));
|
||||
}
|
||||
|
||||
@@ -1477,6 +1472,7 @@ class Charter extends UIState {
|
||||
if (s.selectable.draggable) s.selectable.handleDrag(s.change * -1);
|
||||
|
||||
selection = [for (s in selectionDrags) s.selectable];
|
||||
Charter.instance.updateBPMEvents();
|
||||
case CEditSustains(changes):
|
||||
for(n in changes)
|
||||
n.note.updatePos(n.note.step, n.note.id, n.before, n.note.type);
|
||||
@@ -1522,6 +1518,7 @@ class Charter extends UIState {
|
||||
for (s in selectionDrags)
|
||||
if (s.selectable.draggable) s.selectable.handleDrag(s.change);
|
||||
//this.selection = selection;
|
||||
Charter.instance.updateBPMEvents();
|
||||
case CEditSustains(changes):
|
||||
for(n in changes)
|
||||
n.note.updatePos(n.note.step, n.note.id, n.after, n.note.type);
|
||||
@@ -1836,14 +1833,30 @@ class Charter extends UIState {
|
||||
}
|
||||
|
||||
public function updateBPMEvents() {
|
||||
eventsGroup.sortEvents();
|
||||
Conductor.mapCharterBPMChanges(PlayState.SONG);
|
||||
buildEvents();
|
||||
|
||||
Conductor.changeBPM(PlayState.SONG.meta.bpm, cast PlayState.SONG.meta.beatsPerMeasure.getDefault(4), cast PlayState.SONG.meta.stepsPerBeat.getDefault(4));
|
||||
Conductor.mapBPMChanges(PlayState.SONG);
|
||||
|
||||
for(e in eventsGroup.members) {
|
||||
for(event in e.events) {
|
||||
if (event.name == "BPM Change" || event.name == "Time Signature Change" || event.name == "Continuous BPM Change") {
|
||||
e.refreshEventIcons();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refreshBPMSensitive();
|
||||
}
|
||||
|
||||
public inline function checkSelectionForBPMUpdates() {
|
||||
for (s in selection)
|
||||
if (s is CharterEvent) {
|
||||
Charter.instance.updateBPMEvents();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public inline function hitsoundsEnabled(id:Int)
|
||||
return strumLines.members[id] != null && strumLines.members[id].hitsounds;
|
||||
|
||||
|
||||
@@ -294,10 +294,10 @@ class CharterGridSeperatorBase extends FlxSprite {
|
||||
for (i => change in Conductor.bpmChangeMap) {
|
||||
if (change.stepTime >= minStep && change.stepTime <= maxStep) {
|
||||
//get step while ignoring the current change
|
||||
var index = CoolUtil.boundInt(i-1, 0, Conductor.bpmChangeMap.length - 1);
|
||||
var step = Conductor.getTimeWithBPMInSteps(change.songTime, index, Conductor.getTimeWithIndexInBPM(change.songTime, index));
|
||||
var index:Int = CoolUtil.boundInt(i-1, 0, Conductor.bpmChangeMap.length - 1);
|
||||
var step:Float = Conductor.getTimeWithBPMInSteps(change.songTime, index, Conductor.getTimeWithIndexInBPM(change.songTime, index));
|
||||
|
||||
if (Math.ceil(step) - step > 0) { //mid step change
|
||||
if (Math.ceil(step) - step > 0 && (step - Math.floor(step)) > FlxMath.EPSILON) { //mid step change
|
||||
timeSignatureChangeGaps.push(step);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package funkin.editors.charter;
|
||||
|
||||
import funkin.backend.shaders.CustomShader;
|
||||
import funkin.backend.system.Conductor;
|
||||
import flixel.group.FlxSpriteGroup;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.system.FlxAssets.FlxGraphicAsset;
|
||||
@@ -176,7 +178,7 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
||||
return healthIcon;
|
||||
}
|
||||
|
||||
public static function generateEventIcon(event:ChartEvent):FlxSprite {
|
||||
public static function generateEventIcon(event:ChartEvent, inMenu:Bool = true):FlxSprite {
|
||||
var script = getUIScript(event, "event-icon");
|
||||
if(script != null && !(script is DummyScript)) {
|
||||
if(script.get("generateIcon") != null) {
|
||||
@@ -201,8 +203,43 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
||||
num.active = false;
|
||||
num;
|
||||
});
|
||||
if (Conductor.invalidEvents.contains(event)) generateEventIconWarning(group);
|
||||
return group;
|
||||
}
|
||||
case "Continuous BPM Change":
|
||||
if(event.params != null && event.params[1] != null) {
|
||||
if (inMenu) {
|
||||
var group = new EventIconGroup();
|
||||
group.add(generateDefaultIcon("BPM Change Start"));
|
||||
if (Conductor.invalidEvents.contains(event)) generateEventIconWarning(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
var group = generateEventIconWithDuration(event.params[1], "BPM Change Start");
|
||||
group.members[0].y -= 2;
|
||||
generateEventIconNumbers(group, Std.int(event.params[0]), 15);
|
||||
if (Conductor.invalidEvents.contains(event)) generateEventIconWarning(group);
|
||||
return group;
|
||||
} else {
|
||||
return generateDefaultIcon("BPM Change Start");
|
||||
}
|
||||
case "BPM Change":
|
||||
if(event.params != null && event.params[0] != null) {
|
||||
if (inMenu) {
|
||||
var group = new EventIconGroup();
|
||||
group.add(generateDefaultIcon(event.name));
|
||||
if (Conductor.invalidEvents.contains(event)) generateEventIconWarning(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
var group = new EventIconGroup();
|
||||
group.add(generateDefaultIcon(event.name));
|
||||
group.members[0].y -= 2;
|
||||
generateEventIconNumbers(group, Std.int(event.params[0]), 15);
|
||||
if (Conductor.invalidEvents.contains(event)) generateEventIconWarning(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
case "Camera Movement":
|
||||
// camera movement, use health icon
|
||||
if(event.params != null) {
|
||||
@@ -213,6 +250,76 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
||||
return generateDefaultIcon(event.name);
|
||||
}
|
||||
|
||||
private static function generateEventIconNumbers(group:EventIconGroup, number:Int, y:Float) {
|
||||
var numString = Std.string(number);
|
||||
var offset = (16 - (numString.length*5))/2;
|
||||
for (num in 0...numString.length) {
|
||||
group.add({
|
||||
var num = new EventNumber(offset + num*5, y, Std.parseInt(numString.charAt(num)), EventNumber.ALIGN_CENTER);
|
||||
num.active = false;
|
||||
num;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static function generateEventIconWithDuration(duration:Float, startIcon:String, endIcon:String = "") {
|
||||
var group = new EventIconGroup();
|
||||
group.add(generateDefaultIcon(startIcon));
|
||||
|
||||
var xOffset = 4;
|
||||
var yGap = 24;
|
||||
var endGap = 7;
|
||||
if (endIcon == "") endGap = -2;
|
||||
|
||||
if (duration >= 0.65) { //min time for showing arrow
|
||||
var tail = new FlxSprite(xOffset, yGap);
|
||||
var arrow = new FlxSprite(xOffset, (duration * 40) + endGap);
|
||||
var arrowSegment = new FlxSprite(xOffset, yGap);
|
||||
tail.frames = arrow.frames = arrowSegment.frames = Paths.getSparrowAtlas("editors/charter/event-icons/components/arrow-down");
|
||||
|
||||
group.add({
|
||||
tail.animation.addByPrefix("tail", "tail");
|
||||
tail.animation.play("tail");
|
||||
tail;
|
||||
});
|
||||
|
||||
group.add({
|
||||
arrowSegment.animation.addByPrefix("segment", "segment");
|
||||
arrowSegment.animation.play("segment");
|
||||
arrowSegment.scale.y = (duration * 40) - (tail.height + endGap + yGap);
|
||||
arrowSegment.updateHitbox();
|
||||
arrowSegment.y += tail.height;
|
||||
arrowSegment;
|
||||
});
|
||||
|
||||
group.add({
|
||||
arrow.animation.addByPrefix("arrow", "arrow");
|
||||
arrow.animation.play("arrow");
|
||||
arrow;
|
||||
});
|
||||
}
|
||||
|
||||
if (endIcon != "") {
|
||||
group.add({
|
||||
var icon = generateDefaultIcon(endIcon);
|
||||
icon.y = duration * 40;
|
||||
icon;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
private static function generateEventIconWarning(group:EventIconGroup) {
|
||||
for (spr in group) {
|
||||
spr.colorTransform.redMultiplier = spr.colorTransform.greenMultiplier = spr.colorTransform.blueMultiplier = 0.5;
|
||||
spr.colorTransform.redOffset = 100;
|
||||
}
|
||||
group.add(getEventComponent("warning", 16, -8));
|
||||
group.copyColorTransformToChildren = false;
|
||||
}
|
||||
|
||||
public override function onHovered() {
|
||||
super.onHovered();
|
||||
/*
|
||||
@@ -238,26 +345,22 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
||||
}
|
||||
|
||||
for(event in events) {
|
||||
var spr = generateEventIcon(event);
|
||||
var spr = generateEventIcon(event, false);
|
||||
icons.push(spr);
|
||||
members.push(spr);
|
||||
}
|
||||
|
||||
draggable = true;
|
||||
for (event in events)
|
||||
if (event.name == "BPM Change" || event.name == "Time Signature Change") {
|
||||
draggable = false;
|
||||
break;
|
||||
}
|
||||
|
||||
x = (snappedToGrid && eventsBackdrop != null ? eventsBackdrop.x : 0) - (bWidth = 37 + (icons.length * 22));
|
||||
}
|
||||
}
|
||||
|
||||
class EventIconGroup extends FlxSpriteGroup {
|
||||
public var forceWidth:Float = 32;
|
||||
public var forceHeight:Float = 32;
|
||||
public var forceWidth:Float = 16;
|
||||
public var forceHeight:Float = 16;
|
||||
public var dontTransformChildren:Bool = true;
|
||||
public var copyColorTransformToChildren:Bool = true;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
@@ -298,6 +401,12 @@ class EventIconGroup extends FlxSpriteGroup {
|
||||
override function get_height() {
|
||||
return forceHeight;
|
||||
}
|
||||
|
||||
override public function draw() {
|
||||
@:privateAccess
|
||||
if (copyColorTransformToChildren && colorTransform != null) for (child in members) child.colorTransform.__copyFrom(colorTransform);
|
||||
super.draw();
|
||||
}
|
||||
}
|
||||
|
||||
class EventNumber extends FlxSprite {
|
||||
@@ -312,10 +421,15 @@ class EventNumber extends FlxSprite {
|
||||
super(x, y);
|
||||
this.digits = [];
|
||||
this.align = align;
|
||||
while (number > 0) {
|
||||
this.digits.insert(0, number % 10);
|
||||
number = Std.int(number / 10);
|
||||
if (number == 0) {
|
||||
this.digits.insert(0, 0);
|
||||
} else {
|
||||
while (number > 0) {
|
||||
this.digits.insert(0, number % 10);
|
||||
number = Std.int(number / 10);
|
||||
}
|
||||
}
|
||||
|
||||
loadGraphic(Paths.image('editors/charter/event-icons/components/eventNums'), true, 6, 7);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class CharterEventScreen extends UISubstateWindow {
|
||||
});
|
||||
eventsList.add(new EventButton(events[events.length-1], CharterEvent.generateEventIcon(events[events.length-1]), events.length-1, this, eventsList));
|
||||
changeTab(events.length-1);
|
||||
}));
|
||||
}, chartEvent.step));
|
||||
for (k=>i in events)
|
||||
eventsList.add(new EventButton(i, CharterEvent.generateEventIcon(i), k, this, eventsList));
|
||||
add(eventsList);
|
||||
@@ -83,12 +83,12 @@ class CharterEventScreen extends UISubstateWindow {
|
||||
else {
|
||||
chartEvent.events = [for (i in eventsList.buttons.members) i.event];
|
||||
chartEvent.refreshEventIcons();
|
||||
Charter.instance.updateBPMEvents();
|
||||
|
||||
Charter.undos.addToUndo(CEditEvent(chartEvent, oldEvents, [for (event in events) Reflect.copy(event)]));
|
||||
}
|
||||
}
|
||||
|
||||
Charter.instance.updateBPMEvents();
|
||||
close();
|
||||
});
|
||||
saveButton.x -= saveButton.bWidth;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package funkin.editors.charter;
|
||||
|
||||
import funkin.backend.system.Conductor;
|
||||
import funkin.backend.chart.EventsData;
|
||||
|
||||
class CharterEventTypeSelection extends UISubstateWindow {
|
||||
var callback:String->Void;
|
||||
var eventStepTime:Float;
|
||||
|
||||
var buttons:Array<UIButton> = [];
|
||||
|
||||
@@ -13,9 +15,10 @@ class CharterEventTypeSelection extends UISubstateWindow {
|
||||
var upIndicator:UIText;
|
||||
var downIndicator:UIText;
|
||||
|
||||
public function new(callback:String->Void) {
|
||||
public function new(callback:String->Void, eventStepTime:Float) {
|
||||
super();
|
||||
this.callback = callback;
|
||||
this.eventStepTime = eventStepTime;
|
||||
}
|
||||
|
||||
public override function create() {
|
||||
@@ -32,6 +35,15 @@ class CharterEventTypeSelection extends UISubstateWindow {
|
||||
buttonsBG.frames = Paths.getFrames('editors/ui/inputbox');
|
||||
add(buttonsBG);
|
||||
|
||||
var disableConductorEvents:Bool = false;
|
||||
var disableOnlyContinuousChanges:Bool = false;
|
||||
for (change in Conductor.bpmChangeMap) {
|
||||
if (change.continuous && eventStepTime >= change.stepTime && eventStepTime < change.endStepTime) {
|
||||
disableOnlyContinuousChanges = eventStepTime == change.stepTime; //allow time sig and instant bpm changes on the same event
|
||||
disableConductorEvents = !disableOnlyContinuousChanges;
|
||||
}
|
||||
}
|
||||
|
||||
for(k=>eventName in EventsData.eventsList) {
|
||||
var button = new UIButton(0, (32 * k), eventName, function() {
|
||||
close();
|
||||
@@ -52,6 +64,11 @@ class CharterEventTypeSelection extends UISubstateWindow {
|
||||
icon.x = button.x + 8;
|
||||
icon.y = button.y + Math.abs(button.bHeight - icon.height) / 2;
|
||||
add(icon);
|
||||
|
||||
if (disableConductorEvents && (eventName == "Time Signature Change" || eventName == "Continuous BPM Change" || eventName == "BPM Change") || (disableOnlyContinuousChanges && eventName == "Continuous BPM Change")) {
|
||||
button.selectable = button.shouldPress = false;
|
||||
button.autoAlpha = true;
|
||||
}
|
||||
}
|
||||
|
||||
windowSpr.bHeight = 61 + (32 * (17));
|
||||
@@ -79,7 +96,7 @@ class CharterEventTypeSelection extends UISubstateWindow {
|
||||
sinner += elapsed;
|
||||
|
||||
for (button in buttons)
|
||||
button.selectable = buttonsBG.hovered;
|
||||
if (button.shouldPress) button.selectable = buttonsBG.hovered;
|
||||
|
||||
buttonCameras.zoom = subCam.zoom;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user