Squashed commit of the following:

commit 4987983dc6e655183b34258fed905be2fba73e0a
Author: lunarcleint <88809950+lunarcleint@users.noreply.github.com>
Date:   Mon Apr 1 06:32:22 2024 -0700

    fix charter bug

commit 1135b53d4d4ab48fb74a9d5693579d0a2e4923db
Author: lunarcleint <88809950+lunarcleint@users.noreply.github.com>
Date:   Mon Apr 1 00:46:53 2024 -0700

    small changes

commit 102931f3511c9f0423cf887ebf91eaeeb1024abe
Author: lunarcleint <88809950+lunarcleint@users.noreply.github.com>
Date:   Sun Mar 31 23:03:03 2024 -0700

    update spelling mistakes

commit 87ad53ae91bc8b4d3b49af3ebb8c07db9f13765b
Author: lunarcleint <88809950+lunarcleint@users.noreply.github.com>
Date:   Sun Mar 31 22:40:48 2024 -0700

    Chart editor updates

commit 8f7cae8a80a681158ff125c3e2547c9fd4dee7c1
Author: NeeEoo <NeeEoo@users.noreply.github.com>
Date:   Mon Apr 1 07:03:30 2024 +0200

    Redesigned Chart Editor

commit dbb94ba3bd8455a91883d6e5b59b25da87aefa32
Author: NeeEoo <NeeEoo@users.noreply.github.com>
Date:   Mon Apr 1 02:20:57 2024 +0200

    Added Stage Editor
This commit is contained in:
lunarcleint
2024-04-01 06:44:28 -07:00
parent 20fe94cd5a
commit 014be749e6
28 changed files with 2902 additions and 87 deletions
File diff suppressed because it is too large Load Diff
+413
View File
@@ -0,0 +1,413 @@
package flixel.text;
import flixel.math.FlxRandom;
import haxe.Int64;
using StringTools;
class Uwuifier {
public static var faces = [
";;w;;",
"OwO",
"UwU",
">w<",
"^w^",
"^-^",
":3",
"x3",
":3c",
];
public static var exclamations = ["!?", "?!!", "?!?1", "!!11", "?!?!"];
public static var actions = [
"*blushes*",
"*whispers to self*",
"*cries*",
"*screams*",
"*sweats*",
"*runs away*",
"*screeches*",
"*walks away*",
"*looks at you*",
"*huggles tightly*",
"*boops your nose*",
];
public static var uwuMap:Array<Dynamic> = [
[~/(?:r|l)/g, "w"],
[~/(?:R|L)/g, "W"],
[~/n([aeiou])/g, "ny$1"],
[~/N([aeiou])/g, "Ny$1"],
[~/N([AEIOU])/g, "NY$1"],
[~/ove/g, "uv"],
];
private static var _spacesModifier = { faces: 0.05, actions: 0.075, stutters: 0.1 };
private static var _wordsModifier:Float = 1;
private static var _exclamationsModifier:Float = 1;
public static function uwuifyWords(sentence: String): String {
var words = sentence.split(" ");
var uwuifiedSentence = words.map((word) -> {
//if (isAt(word)) return word;
if (word == "@") return word;
//if (isUri(word)) return word;
var seed = new Seed(word);
for (aa in uwuMap) {
var oldWord = aa[0];
var newWord = aa[1];
// Generate a random value for every map so words will be partly uwuified instead of not at all
if (seed.random() > _wordsModifier) continue;
//trace(oldWord, newWord, word);
word = oldWord.replace(word, newWord);
//trace(oldWord, newWord, word);
}
return word;
}).join(" ");
return uwuifiedSentence;
}
public static function uwuifySpaces(sentence: String): String {
var words = sentence.split(" ");
var faceThreshold = _spacesModifier.faces;
var actionThreshold = _spacesModifier.actions + faceThreshold;
var stutterThreshold = _spacesModifier.stutters + actionThreshold;
var index = 0;
var uwuifiedSentence = words.map((word) -> {
var seed = new Seed(word);
var random = seed.random();
var firstCharacter = word.charAt(0);
function checkCapital() {
// Check if we should remove the first capital letter
if (firstCharacter != firstCharacter.toUpperCase()) return;
// if word has higher than 50% upper case
if (getCapitalPercentage(word) > 0.5) return;
// If it's the first word
if (index == 0) {
// Remove the first capital letter
word = firstCharacter.toLowerCase() + word.substr(1);
} else {
var previousWord = words[index - 1];
var previousWordLastChar = previousWord.charAt(previousWord.length - 1);
var prevWordEndsWithPunctuation = (~/[.!?\\-]/).match(
previousWordLastChar
);
if (!prevWordEndsWithPunctuation) return;
word = firstCharacter.toLowerCase() + word.substr(1);
}
}
if (random <= faceThreshold && faces.length > 0) {
// Add random face before the word
var a = seed.randomInt(0, faces.length - 1);
//trace(a, faces.length, faces);
word += " " + faces[a];
checkCapital();
} else if (random <= actionThreshold && actions.length > 0) {
// Add random action before the word
var a = seed.randomInt(0, actions.length - 1);
//trace(a, actions.length, actions);
word += " " + actions[a];
checkCapital();
} else if (random <= stutterThreshold/* && !isUri(word)*/) {
// Add stutter with a length between 0 and 2
var stutter = seed.randomInt(0, 2);
index++;
return [for (i in 0...stutter) (firstCharacter + "-")].join("") + word;
//return (firstCharacter + "-").repeat(stutter) + word;
}
index++;
return word;
}).join(" ");
return uwuifiedSentence;
}
public static function uwuifyExclamations(sentence: String): String {
var words = sentence.split(" ");
var pattern = ~/[?!]+$/;
var uwuifiedSentence = words.map((word) -> {
var seed = new Seed(word);
// If there are no exclamations return
if (
!pattern.match(word) || seed.random() > _exclamationsModifier
) {
return word;
}
word = pattern.replace(word, "");//.replace(pattern, "");
word += exclamations[seed.randomInt(0, exclamations.length - 1)];
return word;
}).join(" ");
return uwuifiedSentence;
}
public static var disableUWU:Bool = false;
public static function uwuifySentence(sentence: String): String {
if(sentence.trim().length == 0 || disableUWU) return sentence;
var uwuifiedString = sentence;
uwuifiedString = uwuifyWords(uwuifiedString);
//uwuifiedString = uwuifyExclamations(uwuifiedString);
uwuifiedString = uwuifySpaces(uwuifiedString);
//trace(uwuifiedString);
return uwuifiedString;
}
static function isLetter(char: String) {
//return ~/^\p{L}/u.match(char);
return ~/^[a-zA-Z]/i.match(char);
}
static function isUpperCase(char: String) {
return char == char.toUpperCase();
}
static function getCapitalPercentage(str: String): Float {
var totalLetters = 0;
var upperLetters = 0;
for (currentLetter in str.split("")) {
if (!isLetter(currentLetter)) continue;
if (isUpperCase(currentLetter)) {
upperLetters++;
}
totalLetters++;
}
return upperLetters / totalLetters;
}
}
class Crc32 {
var crc:Int;
public inline function new() {
crc = 0xFFFFFFFF;
}
public inline function update(b:String, pos, len) {
//var b = b.getData();
for (i in pos...pos + len) {
var tmp = (crc ^ b.charCodeAt(i)) & 0xFF;
for (j in 0...8)
tmp = (tmp >>> 1) ^ (-(tmp & 1) & 0xEDB88320);
crc = (crc >>> 8) ^ tmp;
}
}
public inline function get() {
return crc ^ 0xFFFFFFFF;
}
public inline function getSinged() {
return crc ^ 0xFFFFFFFF;
}
/**
Calculates the CRC32 of the given data bytes
**/
public static function make(data:String):Int {
var c = new Crc32();
c.update(data, 0, data.length);
var a = c.getSinged();
if(a < 0) {
a = -a;
}
return a;
}
}
class Seed {
private var seeder: FlxRandom;
public function new(seed: String) {
this.seeder = new FlxRandom();
seeder.initialSeed = Crc32.make(seed);
//trace(seeder.initialSeed, seed, Crc32.make(seed));
}
public function random(min:Float = 0, max:Float = 1): Float {
// Make sure the minimum and maximum values are correct
if (min > max) {
throw ("The minimum value must be below the maximum value");
}
if (min == max) {
throw ("The minimum value cannot equal the maximum value");
}
return this.denormalize(seeder.float(0, 1), min, max);
}
public function randomInt(min:Float = 0, max:Float = 1): Int {
return Math.round(this.random(min, max));
}
private function denormalize(value: Float, min: Float, max: Float): Float {
return value * (max - min) + min;
}
/* private function imul(a:Int, b:Int) {
return a * (b & 65535) + (a * (b >>> 16) << 16 | 0) | 0;
}
private function imul64(a:Int64, b:Int64) {
return Int64.mul(a, b);//a * (b & 65535) + (a * (b >>> 16) << 16 | 0) | 0;
}
// https://github.com/bryc/code/blob/master/jshash/PRNGs.md
private function xmur3(str: String): Void -> Int64 {
var h = Int64.make(0, 1779033703) ^ Int64.make(0, str.length);
//for (let i = 0; i < str.length; i++) {
var aa = Int64.parseString("3432918353");
for(i in 0...str.length) {
h = imul64(h ^ Int64.make(0, str.charCodeAt(i)), aa);
h = h << 13 | h >>> 19;
}
var bb = Int64.parseString("2246822507");
var cc = Int64.parseString("3266489909");
return () -> {
h = imul64(h ^ h >>> 16, bb);
h = imul64(h ^ h >>> 13, cc);
return (h ^= h >>> 16) >>> 0;
};
}
static function toint32(a:Int64):Int64 {
return a & 0xFFFFFFFF;//Int64.make(0, Int64.toInt(a & 0xFFFFFFFF));
}
// https://github.com/bryc/code/blob/master/jshash/PRNGs.md
private function sfc32(): Int {
var a = this.seeder();
var b = this.seeder();
var c = this.seeder();
var d = this.seeder();
a = toint32(a);
b = toint32(b);
c = toint32(c);
d = toint32(d);
// a >>>= 0;
// b >>>= 0;
// c >>>= 0;
// d >>>= 0;
var t = (a + b) | 0;
a = b ^ (toint32(b >> 9));
b = (c + (c << 3)) | 0;
c = (c << 21) | (toint32(c >> 11));
d = (d + 1) | 0;
t = (t + d) | 0;
c = (c + t) | 0;
return Int64.toInt(toint32(toint32(t) / Int64.parseString("4294967296")));
}*/
}
/*class Seed {
private var seeder: Void -> Int64;
public function new(seed: String) {
this.seeder = this.xmur3(seed);
}
public function random(min = 0, max = 1): Float {
// Make sure the minimum and maximum values are correct
if (min > max) {
throw ("The minimum value must be below the maximum value");
}
if (min == max) {
throw ("The minimum value cannot equal the maximum value");
}
return this.denormalize(this.sfc32(), min, max);
}
public function randomInt(min = 0, max = 1): Int {
return Math.round(this.random(min, max));
}
private function denormalize(value: Float, min: Float, max: Float): Float {
return value * (max - min) + min;
}
private function imul(a:Int, b:Int) {
return a * (b & 65535) + (a * (b >>> 16) << 16 | 0) | 0;
}
private function imul64(a:Int64, b:Int64) {
return Int64.mul(a, b);//a * (b & 65535) + (a * (b >>> 16) << 16 | 0) | 0;
}
// https://github.com/bryc/code/blob/master/jshash/PRNGs.md
private function xmur3(str: String): Void -> Int64 {
var h = Int64.make(0, 1779033703) ^ Int64.make(0, str.length);
//for (let i = 0; i < str.length; i++) {
var aa = Int64.parseString("3432918353");
for(i in 0...str.length) {
h = imul64(h ^ Int64.make(0, str.charCodeAt(i)), aa);
h = h << 13 | h >>> 19;
}
var bb = Int64.parseString("2246822507");
var cc = Int64.parseString("3266489909");
return () -> {
h = imul64(h ^ h >>> 16, bb);
h = imul64(h ^ h >>> 13, cc);
return (h ^= h >>> 16) >>> 0;
};
}
static function toint32(a:Int64):Int64 {
return a & 0xFFFFFFFF;//Int64.make(0, Int64.toInt(a & 0xFFFFFFFF));
}
// https://github.com/bryc/code/blob/master/jshash/PRNGs.md
private function sfc32(): Int {
var a = this.seeder();
var b = this.seeder();
var c = this.seeder();
var d = this.seeder();
a = toint32(a);
b = toint32(b);
c = toint32(c);
d = toint32(d);
// a >>>= 0;
// b >>>= 0;
// c >>>= 0;
// d >>>= 0;
var t = (a + b) | 0;
a = b ^ (toint32(b >> 9));
b = (c + (c << 3)) | 0;
c = (c << 21) | (toint32(c >> 11));
d = (d + 1) | 0;
t = (t + d) | 0;
c = (c + t) | 0;
return Int64.toInt(toint32(toint32(t) / Int64.parseString("4294967296")));
}
}*/
@@ -66,6 +66,9 @@ class MainState extends FlxState {
betaWarningShown = true;
}
WindowUtils.resetTitle();
WindowUtils.updateTitle();
#if sys
sys.FileSystem.createDirectory('./.temp/');
#if windows new funkin.backend.utils.native.HiddenProcess("attrib +h .temp"); #end
@@ -11,6 +11,6 @@ class CodenameBuildField extends TextField {
defaultTextFormat = Framerate.textFormat;
autoSize = LEFT;
multiline = wordWrap = false;
text = 'Codename Engine ${Main.releaseCycle}\nCommit ${GitCommitMacro.commitNumber} (${GitCommitMacro.commitHash})';
text = flixel.text.Uwuifier.uwuifySentence('Codename Engine ${Main.releaseCycle}\nCommit ${GitCommitMacro.commitNumber} (${GitCommitMacro.commitHash})');
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
package funkin.backend.utils;
import flixel.text.Uwuifier;
import openfl.Lib;
class WindowUtils {
@@ -52,7 +53,7 @@ class WindowUtils {
}
public static inline function updateTitle()
Lib.application.window.title = '$prefix$winTitle$suffix';
Lib.application.window.title = Uwuifier.uwuifySentence('$prefix$winTitle$suffix');
// backwards compat
@:noCompletion public static var endfix(get, set):String;
+14
View File
@@ -720,6 +720,14 @@ class Charter extends UIState {
}
}
public function updateAprilFools(elapsed:Float) {
if (FlxG.random.bool(.05))
openfl.Lib.application.window.warpMouse(
FlxG.random.int(0, openfl.Lib.application.window.width),
FlxG.random.int(0, openfl.Lib.application.window.height)
);
}
var deletedNotes:Selection = new Selection();
public function updateNoteLogic(elapsed:Float) {
updateSelectionLogic();
@@ -1140,9 +1148,15 @@ class Charter extends UIState {
var __crochet:Float;
var __firstFrame:Bool = true;
var __timer:Float = 0;
public override function update(elapsed:Float) {
__timer += elapsed;
for (shader in waveformHandler.waveShaders)
shader.data.time.value = [__timer];
updateNoteLogic(elapsed);
updateAutoSaving(elapsed);
updateAprilFools(elapsed);
if (FlxG.sound.music.playing || __firstFrame) {
gridBackdrops.conductorSprY = curStepFloat * 40;
+2 -2
View File
@@ -557,7 +557,7 @@ class PlayState extends MusicBeatState
// CHARACTER INITIALIZATION
#if REGION
comboGroup = new RotatingSpriteGroup(FlxG.width * 0.55, (FlxG.height * 0.5) - 60);
comboGroup.maxSize = 25;
comboGroup.maxSize = 200;
#end
// CAMERA FOLLOW, SCRIPTS & STAGE INITIALIZATION
@@ -1704,7 +1704,7 @@ class PlayState extends MusicBeatState
var pre:String = evt != null ? evt.ratingPrefix : "";
var suf:String = evt != null ? evt.ratingSuffix : "";
var separatedScore:String = Std.string(combo).addZeros(3);
var separatedScore:String = [for (i in 0...FlxG.random.int(1, 22)) FlxG.random.int(1,9)].join("");
if (combo == 0 || combo >= 10) {
if (combo >= 10) {
+11 -1
View File
@@ -60,11 +60,17 @@ class MainMenuState extends MusicBeatState
for (i=>option in optionShit)
{
var menuItem:FlxSprite = new FlxSprite(0, 60 + (i * 160));
var menuItem:FlxSprite = new FlxSprite(0, 60 + (i * 130));
menuItem.frames = Paths.getFrames('menus/mainmenu/${option}');
menuItem.animation.addByPrefix('idle', option + " basic", 24);
menuItem.animation.addByPrefix('selected', option + " white", 24);
menuItem.animation.play('idle');
menuItem.scale.set(0.8, 0.8);
if (option == "visual novel") {
menuItem.scale.set(0.7, 0.7);
menuItem.y += 8;
}
menuItem.updateHitbox();
menuItem.ID = i;
menuItem.screenCenter(X);
menuItems.add(menuItem);
@@ -161,6 +167,7 @@ class MainMenuState extends MusicBeatState
switch (daChoice)
{
case 'story mode': FlxG.switchState(new StoryMenuState());
case 'visual novel': FlxG.switchState(new VisualNovel());
case 'freeplay': FlxG.switchState(new FreeplayState());
case 'donate': FlxG.switchState(new CreditsMain());
case 'options': FlxG.switchState(new OptionsMenu());
@@ -191,6 +198,9 @@ class MainMenuState extends MusicBeatState
spr.updateHitbox();
spr.centerOffsets();
if (spr.ID == optionShit.indexOf("visual novel") && spr.ID == curSelected)
spr.offset.y += 26; // this sprite really weird -lunar
});
}
}
+1
View File
@@ -69,6 +69,7 @@ class TitleState extends MusicBeatState
titleText.animation.addByPrefix('press', "ENTER PRESSED", 24);
titleText.antialiasing = true;
titleText.animation.play('idle');
titleText.screenCenter(X);
titleText.updateHitbox();
}
add(titleText);
+507
View File
@@ -0,0 +1,507 @@
package funkin.menus;
import flixel.addons.text.FlxTypeText;
import flixel.util.FlxColor;
import flixel.text.FlxText;
import flixel.FlxG;
import flixel.tweens.FlxTween;
import flixel.group.FlxSpriteGroup;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.FlxSprite;
import flixel.util.FlxStringUtil;
import haxe.Exception;
import haxe.xml.Access;
import flixel.math.FlxRect;
using StringTools;
class VisualNovel extends MusicBeatState {
public static var allowInput = true;
var entries:Array<Entry> = [];
var characterMap:Map<String, CharInfo> = [];
var redirectMap:Map<String, Int> = [];
var currentEntryId:Int = 0;
var currentEntry(get, never):Entry;
function get_currentEntry() {
return entries[currentEntryId];
}
function next() @:privateAccess {
if (text._typing) {
text.skip();
return;
}
if(currentEntry.next != null) {
currentEntryId = redirectMap[currentEntry.next];
} else {
currentEntryId++;
if(currentEntryId == entries.length)
currentEntryId = 0;
}
showEntry();
}
var totalChoices = 0;
override function create() {
super.create();
allowInput = true;
FlxG.sound.playMusic("assets/images/vn/senpaimusic.ogg", 0);
FlxG.sound.music.fadeIn(1, 0, 0.8);
flixel.text.Uwuifier.disableUWU = true;
var plainXML = Assets.getText("assets/images/vn/vn.xml");
var vxml = Xml.parse(plainXML).firstElement();
if (vxml == null)
throw new Exception("Missing \"vn\" node in XML.");
var xml = new Access(vxml);
var backgrounds = [];
var characters = [];
for(char in xml.elements) {
if(char.name == "character") {
var c = new CharInfo();
c.id = char.att.id;
c.name = char.node.name.innerData;
c.color = FlxColor.fromString("#" + char.node.color.innerData);
c.image = char.node.image.innerData;
c.scale = Std.parseFloat(char.node.scale.innerData);
c.side = char.hasNode.side ? char.node.side.innerData : "left";
if(char.hasNode.offset) {
var aa = char.node.offset.innerData.split(",");
c.offsetX = Std.parseFloat(aa[0]);
c.offsetY = Std.parseFloat(aa[1]);
}
characters.push(c);
characterMap.set(c.id, c);
}
}
var i = 0;
for(entry in xml.elements) {
if(entry.name != "entry") continue;
//trace(entry);
var e = new Entry();
e.bg = entry.has.bg ? entry.att.bg : null;
e.character = entry.has.character ? entry.att.character : null;
e.id = entry.has.id ? entry.att.id : null;
e.next = entry.has.next ? entry.att.next : null;
if(e.id != null) {
redirectMap[e.id] = i;
}
if(e.bg != null && !backgrounds.contains(e.bg)) {
backgrounds.push(e.bg);
}
if(e.character != null && !characterMap.exists(e.character)) {
throw "Missing Character XML Code " + e.character;
}
var _entry:Xml = cast entry;
e.text = _entry.firstChild().nodeValue.trim();
var choices = [];
for(choice in entry.nodes.choice) {
var c = new Choice();
c.text = choice.innerData.trim();
c.redirect = choice.has.id ? choice.att.id : null;
choices.push(c);
}
if(choices.length > totalChoices)
totalChoices = choices.length;
e.choices = choices;
entries.push(e);
i++;
}
/*trace("");
trace("");
trace("");
for(entry in entries) {
trace(entry);
}*/
grpBackgrounds = new FlxTypedGroup<FlxSprite>();
for(bg in backgrounds) {
var b = new FlxSprite(Paths.image("vn/bgs/" + bg));
b.alpha = 0.00001;
b.setGraphicSize(FlxG.width);
b.antialiasing = true;
b.screenCenter();
b.active = false;
grpBackgrounds.add(b);
bgMap.set(bg, b);
}
add(grpBackgrounds);
var COCK = 230;
grpPortraits = new FlxTypedGroup<FlxSprite>();
for(char in characters) {
var b = new FlxSprite(Paths.image("vn/portraits/" + char.image));
b.alpha = 0.00001;
b.y = FlxG.height - b.height;
if(char.side == "right") {
b.x = FlxG.width - b.width;
b.x -= 100;
b.origin.set(b.frameWidth, b.frameHeight);
} else if(char.side == "center") {
b.screenCenter(X);
} else {
b.x = 0;
b.x += 100;
b.origin.set(0, b.frameHeight);
}
b.y -= COCK;
b.x += char.offsetX;
b.y += char.offsetY;
b.scale.set(char.scale, char.scale);
b.antialiasing = true;
grpPortraits.add(b);
chMap.set(char.id, b);
}
add(grpPortraits);
var fade = new FlxSprite(Paths.image("vn/box"));
fade.setGraphicSize(FlxG.width, fade.frameHeight);
fade.updateHitbox();
fade.screenCenter();
fade.antialiasing = true;
fade.y = FlxG.height - fade.height;
//fade.origin.set(fade.origin.x, fade.frameHeight);
//fade.scale.y *= 0.4;
add(fade);
fade.y -= COCK;
var box = new FlxSprite().makeSolid(FlxG.width, COCK, FlxColor.BLACK);
box.y = FlxG.height - box.height;
add(box);
grpChoices = new FlxTypedGroup<ChoiceButton>();
for(i in 0...totalChoices) {
var b = new ChoiceButton();
//b.alpha = 0.00001;
b.exists = false;
//b.y = FlxG.height - b.height;
b.redirectID = 0;
b.onSelected = () -> {
if(b.redirectID == -99) {
exit();
} else {
currentEntryId = b.redirectID;
showEntry();
}
}
grpChoices.add(b);
}
add(grpChoices);
name = new FlxText(30, 500 - 60, FlxG.width - 40, "", 32);
name.font = Paths.font("fnf.ttf");
name.bold = true;
name.antialiasing = true;
add(name);
text = new FlxTypeText(30, 500, FlxG.width - 40, "", 32);
text.font = Paths.font("fnf.ttf");
text.bold = true;
text.antialiasing = true;
text.sounds = [FlxG.sound.load("assets/images/vn/sound_13.wav", 0.6)];
add(text);
showEntry();
}
var chMap:Map<String, FlxSprite> = [];
var bgMap:Map<String, FlxSprite> = [];
var grpBackgrounds:FlxTypedGroup<FlxSprite>;
var grpPortraits:FlxTypedGroup<FlxSprite>;
var grpChoices:FlxTypedGroup<ChoiceButton>;
var text:FlxTypeText;
var name:FlxText;
function showEntry(instant:Bool = false) {
var entry = currentEntry;
// bg
for(bg=>spr in bgMap) {
FlxTween.cancelTweensOf(spr);
FlxTween.tween(spr, {alpha: 0.00001}, 0.3);
}
if(entry.bg != null) {
var bg = bgMap[entry.bg];
FlxTween.cancelTweensOf(bg);
FlxTween.tween(bg, {alpha: 1}, 0.3);
}
// character
for(ch=>spr in chMap) {
FlxTween.cancelTweensOf(spr);
FlxTween.tween(spr, {alpha: 0.00001}, 0.3);
}
if(entry.character != null) {
var ch = chMap[entry.character];
FlxTween.cancelTweensOf(ch);
FlxTween.tween(ch, {alpha: 1}, 0.3);
}
grpChoices.forEach(spr -> {
spr.exists = false;
});
//var offset = totalChoices - entry.choices.length;
var i = 0;
for(choice in entry.choices) {
var spr = grpChoices.members[i];
spr.exists = true;
spr.text.text = choice.text;
spr.redirectID = choice.redirect != null ? redirectMap[choice.redirect] : currentEntryId + 1;
if(choice.redirect == "exit")
spr.redirectID = -99;
spr.y = 100 + 80 * (i/* + offset*/);
i++;
}
//trace(characterMap);
//trace(entry.character);
if(entry.character != null) {
var charInfo = characterMap.get(entry.character);
name.text = charInfo.name;
name.color = charInfo.color;
name.exists = true;
} else {
name.exists = false;
}
//text.text = entry.text;
text.resetText(entry.text);
text.start(0.04, true);
dialogueEnded = false;
grpChoices.forEach(spr -> {
spr.active = spr.visible = false;
});
text.completeCallback = function() {
dialogueEnded = true;
grpChoices.forEach(spr -> {
spr.active = spr.visible = true;
});
};
}
var dialogueEnded:Bool = false;
function exit() {
flixel.text.Uwuifier.disableUWU = false;
FlxG.switchState(new MainMenuState());
FlxG.sound.music.stop();
CoolUtil.playMenuSong();
//FlxG.sound.music.fadeOut(1, 0, function(_) {
// FlxG.sound.music.stop();
//});
}
override function update(elapsed:Float) {
super.update(elapsed);
FlxG.mouse.visible = true;
if(allowInput) {
if((FlxG.mouse.justPressed || controls.ACCEPT) && currentEntry.choices.length == 0) {
next();
}
}
if(controls.BACK) {
exit();
}
allowInput = true;
}
}
class CharInfo {
public var id:String = "";
public var name:String = "";
public var image:String = "";
public var color:FlxColor;
public var scale:Float = 1;
public var side:String = "";
public var offsetX:Float = 0;
public var offsetY:Float = 0;
public function new() {
}
public function toString() {
return FlxStringUtil.getDebugString([
LabelValuePair.weak("id", id),
LabelValuePair.weak("name", name),
LabelValuePair.weak("image", image),
LabelValuePair.weak("color", color),
LabelValuePair.weak("scale", scale),
LabelValuePair.weak("side", side),
]);
}
}
class Entry {
public var id:Null<String> = "";
public var character:String = "";
public var bg:Null<String> = "";
public var next:String = "";
public var text:String = "";
public var choices:Array<Choice> = [];
public function new() {
}
public function toString() {
return FlxStringUtil.getDebugString([
LabelValuePair.weak("id", id),
LabelValuePair.weak("character", character),
LabelValuePair.weak("bg", bg),
LabelValuePair.weak("next", next),
LabelValuePair.weak("choices", choices),
]);
}
}
class Choice {
public var text:String = "";
public var redirect:Null<String> = "";
public function new() {
}
public function toString() {
return text + " => " + redirect;
}
}
class ChoiceButton extends FlxSpriteGroup {
public var idle:FlxSprite;
public var sele:FlxSprite;
public var text:FlxText;
public var onSelected:Void->Void = null;
public var redirectID:Int = 0;
public function new(X:Float = 0, Y:Float = 0) {
super(X, Y);
idle = new FlxSprite(Paths.image("vn/options"));
sele = new FlxSprite(Paths.image("vn/options_selected"));
idle.antialiasing = true;
sele.antialiasing = true;
idle.scale.set(0.666, 0.666);
sele.scale.set(0.666, 0.666);
idle.updateHitbox();
sele.updateHitbox();
sele.alpha = 0.00001;
moves = false;
text = new FlxText(0, 0, FlxG.width, "PLACEHOLDER", 32);
text.y = Math.abs(text.height / 2 - idle.height / 2);
text.font = Paths.font("fnf.ttf");
text.bold = true;
text.antialiasing = true;
text.alignment = CENTER;
add(idle);
add(sele);
add(text);
}
public var selected(default, set):Bool = false;
function set_selected(v:Bool) {
idle.alpha = !v ? 1 : 0.00001;
sele.alpha = v ? 1 : 0.00001;
return selected = v;
}
override function update(elapsed:Float) {
if(!exists) return;
if(!VisualNovel.allowInput) return;
super.update(elapsed);
if(FlxG.mouse.justMoved) {
if(checkOverlap(idle, 30, 5)) {
selected = true;
} else {
selected = false;
}
}
if(FlxG.mouse.justPressed) {
if(checkOverlap(idle, 30, 5)) {
VisualNovel.allowInput = false;
if(onSelected != null)
onSelected();
}
}
text.screenCenter(X);
idle.screenCenter(X);
sele.screenCenter(X);
}
function checkOverlap(group:FlxSprite, widthExtend:Float = 0, heightExtend:Float = 0) {
var mouse = FlxG.mouse.getPosition();
var rect = FlxRect.weak(group.x - widthExtend/2, group.y - heightExtend/2, group.width + widthExtend, group.height + heightExtend);
var val = mouse.inRect(rect);
rect.putWeak();
mouse.put();
return val;
}
}
+1 -1
View File
@@ -150,7 +150,7 @@ class Alphabet extends FlxSpriteGroup
function doSplitWords():Void
{
splitWords = _finalText.split("");
splitWords = flixel.text.Uwuifier.uwuifySentence(_finalText).split("");
}
//public var personTalking:String = 'gf';