Created
June 17, 2025 11:32
-
-
Save moxie-coder/7904f9a3cad4206ca71bf13832080bf9 to your computer and use it in GitHub Desktop.
An backup of an Uwuifier from Codename engine used in my own FNF mod, now you can use it anywhere you like (this is the code in raw, so it will need some tweaking to make it work)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package backend; | |
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 { | |
if (disableUWU) return sentence; | |
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 { | |
if (disableUWU) return sentence; | |
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 { | |
if (disableUWU) return sentence; | |
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"))); | |
} | |
}*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment