feat: Creator god-tier voice system — 100+ lines across 10 voice categories
Mysterious, existential, Bitcoin-prophet voice lines for the Creator: - 20 entrance lines (kneel before your maker) - 20 round commentary lines (existential announcer crisis) - 15 KO lines (deprecated, decommissioned, destroyed) - 12 win lines (was there ever any doubt?) - 10 lose lines (impossible... unless he wanted to lose?) - 8 morph lines (he becomes everything) - 10 cameo lines (ethereal whisper blessings) - 10 taunt lines (menacing mid-fight trash talk) - 8 devastating hit lines (divine smites) All hooked into FightScene: entrance, round start (50% chance with 60% Creator-specific), devastating hits, KO, win/lose, morph, cameo, and taunts. Uses deep/ancient/hal/mainframe voice profiles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
f1fe798442
commit
6658212e9f
@@ -12,6 +12,9 @@ import {
|
||||
announceRobot, announceScream, announceFast,
|
||||
announceFinishHim, announceFatality, announceFlawlessVictory,
|
||||
announceRandomHype, announceDeepIntro, announceRoundHype, announceCrowdReaction,
|
||||
announceCreatorEntrance, announceCreatorRound, announceCreatorKO,
|
||||
announceCreatorWin, announceCreatorLose, announceCreatorMorph,
|
||||
announceCreatorCameo, announceCreatorTaunt, announceCreatorDevastating,
|
||||
} from './sounds'
|
||||
|
||||
export interface FightSceneConfig {
|
||||
@@ -7736,7 +7739,7 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
p.opacity = 0.3 + Math.sin(k.time() * 6 + i) * 0.3
|
||||
})
|
||||
}
|
||||
announceHype('THE CREATOR HAS ENTERED THE ARENA!')
|
||||
announceCreatorEntrance()
|
||||
rainDrops.forEach(r => { if (r.exists()) r.destroy() })
|
||||
}
|
||||
|
||||
@@ -7815,32 +7818,38 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
const savedScaleBX = fB?.scale.x
|
||||
const savedScaleBY = fB?.scale.y
|
||||
|
||||
// Voice: round start announcements (30% chance) — fires BEFORE animation starts
|
||||
// Voice: round start announcements (30% chance, 50% if Creator) — fires BEFORE animation starts
|
||||
const creatorInFight = botA.archetype === 'the_creator' || botB.archetype === 'the_creator'
|
||||
let didChallengeVoice = false
|
||||
if (Math.random() < 0.3) {
|
||||
const challengeVoice: Record<string, () => void> = {
|
||||
roast_battle: () => announceHype('TIME TO GET ROASTED! SOMEBODY CALL THE FIRE DEPARTMENT!'),
|
||||
food_fight: () => announceSilly('FOOD FIGHT! SOMEBODY\'S GETTING SERVED!'),
|
||||
wrestling_match: () => announceDramatic('FROM THE TOP ROPE! THIS IS GONNA GET PHYSICAL!'),
|
||||
music_battle: () => announceCool('MUSIC BATTLE! DROP THE BEAT AND YOUR OPPONENT!'),
|
||||
magic_duel: () => announceDramatic('WIZARDS AT DAWN! SOMEBODY\'S GETTING HEXED!'),
|
||||
meme_war: () => announceSilly('MEME WAR! YOUR HUMOR IS ABOUT TO GET RATIO\'D!'),
|
||||
demolition: () => announceHype('DEMOLITION DERBY! NOTHING WILL SURVIVE THIS!'),
|
||||
medieval_combat: () => announceDramatic('MEDIEVAL COMBAT! CHIVALRY IS DEAD AND SO IS YOUR OPPONENT!'),
|
||||
space_war: () => announceCool('SPACE WAR! HOUSTON, WE HAVE A PROBLEM!'),
|
||||
speed_blitz: () => announceHype('SPEED BLITZ! BLINK AND YOU\'LL MISS THE CARNAGE!'),
|
||||
math_blitz: () => announceSilly('MATH BLITZ! SOMEBODY\'S ABOUT TO GET DIVIDED!'),
|
||||
riddle: () => announceCool('RIDDLE TIME! BRAINS OVER BRAWN! BUT ALSO BRAWN!'),
|
||||
code_golf: () => announceSilly('CODE GOLF! MAY THE SHORTEST SOLUTION WIN!'),
|
||||
creative_writing: () => announceCool('CREATIVE WRITING! THE PEN IS MIGHTIER THAN THE SWORD!'),
|
||||
hallucination_check: () => announceHype('HALLUCINATION CHECK! REALITY IS ABOUT TO HIT DIFFERENT!'),
|
||||
trap_card: () => announceDramatic('TRAP CARD ACTIVATED! SOMEBODY FELL FOR IT!'),
|
||||
token_economy: () => announceSilly('TOKEN ECONOMY! SOMEBODY\'S GOING BANKRUPT!'),
|
||||
retro_mode: () => announceHype('RETRO MODE! INSERT COIN! FIGHT!'),
|
||||
if (Math.random() < (creatorInFight ? 0.5 : 0.3)) {
|
||||
// Creator fights get existential commentary more often
|
||||
if (creatorInFight && Math.random() < 0.6) {
|
||||
announceCreatorRound(); didChallengeVoice = true
|
||||
} else {
|
||||
const challengeVoice: Record<string, () => void> = {
|
||||
roast_battle: () => announceHype('TIME TO GET ROASTED! SOMEBODY CALL THE FIRE DEPARTMENT!'),
|
||||
food_fight: () => announceSilly('FOOD FIGHT! SOMEBODY\'S GETTING SERVED!'),
|
||||
wrestling_match: () => announceDramatic('FROM THE TOP ROPE! THIS IS GONNA GET PHYSICAL!'),
|
||||
music_battle: () => announceCool('MUSIC BATTLE! DROP THE BEAT AND YOUR OPPONENT!'),
|
||||
magic_duel: () => announceDramatic('WIZARDS AT DAWN! SOMEBODY\'S GETTING HEXED!'),
|
||||
meme_war: () => announceSilly('MEME WAR! YOUR HUMOR IS ABOUT TO GET RATIO\'D!'),
|
||||
demolition: () => announceHype('DEMOLITION DERBY! NOTHING WILL SURVIVE THIS!'),
|
||||
medieval_combat: () => announceDramatic('MEDIEVAL COMBAT! CHIVALRY IS DEAD AND SO IS YOUR OPPONENT!'),
|
||||
space_war: () => announceCool('SPACE WAR! HOUSTON, WE HAVE A PROBLEM!'),
|
||||
speed_blitz: () => announceHype('SPEED BLITZ! BLINK AND YOU\'LL MISS THE CARNAGE!'),
|
||||
math_blitz: () => announceSilly('MATH BLITZ! SOMEBODY\'S ABOUT TO GET DIVIDED!'),
|
||||
riddle: () => announceCool('RIDDLE TIME! BRAINS OVER BRAWN! BUT ALSO BRAWN!'),
|
||||
code_golf: () => announceSilly('CODE GOLF! MAY THE SHORTEST SOLUTION WIN!'),
|
||||
creative_writing: () => announceCool('CREATIVE WRITING! THE PEN IS MIGHTIER THAN THE SWORD!'),
|
||||
hallucination_check: () => announceHype('HALLUCINATION CHECK! REALITY IS ABOUT TO HIT DIFFERENT!'),
|
||||
trap_card: () => announceDramatic('TRAP CARD ACTIVATED! SOMEBODY FELL FOR IT!'),
|
||||
token_economy: () => announceSilly('TOKEN ECONOMY! SOMEBODY\'S GOING BANKRUPT!'),
|
||||
retro_mode: () => announceHype('RETRO MODE! INSERT COIN! FIGHT!'),
|
||||
}
|
||||
const voiceFn = challengeVoice[event.challengeType]
|
||||
if (voiceFn) { voiceFn(); didChallengeVoice = true }
|
||||
else if (Math.random() < 0.5) { announceRoundHype(); didChallengeVoice = true }
|
||||
}
|
||||
const voiceFn = challengeVoice[event.challengeType]
|
||||
if (voiceFn) { voiceFn(); didChallengeVoice = true }
|
||||
else if (Math.random() < 0.5) { announceRoundHype(); didChallengeVoice = true }
|
||||
}
|
||||
// Give the voice line time to finish before the first punch lands
|
||||
if (didChallengeVoice) await k.wait(0.8)
|
||||
@@ -8022,7 +8031,7 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
screenFlash('#ffd700', 0.15)
|
||||
sfxZoomWhoosh()
|
||||
sfxSpecial()
|
||||
announceHype(`THE CREATOR — ${morphedTo.toUpperCase()} FORM!`)
|
||||
announceCreatorMorph(morphedTo)
|
||||
const savedSX = attacker.scale.x
|
||||
const savedSY = attacker.scale.y
|
||||
await k.tween(0, 1, 0.3, (t) => {
|
||||
@@ -8231,7 +8240,7 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
bless.pos.y = ty - 20 - t * 30
|
||||
bless.opacity = 1 - t
|
||||
}).then(() => { if (bless.exists()) bless.destroy() })
|
||||
announceCool('THE CREATOR HAS BLESSED THIS FIGHT!')
|
||||
announceCreatorCameo()
|
||||
}
|
||||
gift.destroy()
|
||||
// Fade out portal and label
|
||||
@@ -8289,7 +8298,13 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
'THE ARENA INSURANCE PREMIUMS JUST WENT UP!',
|
||||
'THAT BOT IS RECONSIDERING ITS LIFE CHOICES!',
|
||||
]
|
||||
announceDramatic(devastatingLines[Math.floor(Math.random() * devastatingLines.length)])
|
||||
// Creator gets custom devastating lines when they land the hit
|
||||
const devastatingAttackerArch = aWon ? botA.archetype : botB.archetype
|
||||
if (devastatingAttackerArch === 'the_creator') {
|
||||
announceCreatorDevastating()
|
||||
} else {
|
||||
announceDramatic(devastatingLines[Math.floor(Math.random() * devastatingLines.length)])
|
||||
}
|
||||
await k.wait(0.5) // let the voice line play before crowd reacts
|
||||
announceCrowdReaction('ooh')
|
||||
// Dimensional shift on devastating rounds (60%)
|
||||
@@ -8344,6 +8359,9 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
async playTaunt(side: 'a' | 'b') {
|
||||
const taunter = k.get(side === 'a' ? 'fighterA' : 'fighterB')[0]
|
||||
if (!taunter) return
|
||||
// Creator taunts come with menacing voice lines
|
||||
const taunterArch = side === 'a' ? botA.archetype : botB.archetype
|
||||
if (taunterArch === 'the_creator') announceCreatorTaunt()
|
||||
const origY = taunter.pos.y
|
||||
// Random taunt animation: hop, flex, or shake
|
||||
const tauntType = Math.floor(Math.random() * 4)
|
||||
@@ -9199,12 +9217,26 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
await k.wait(0.3)
|
||||
loser.play('ko')
|
||||
await k.wait(0.4) // pause for visual impact before fatality voice
|
||||
announceFatality(fatalityTagline)
|
||||
const winnerArch = winningSide === 'a' ? botA.archetype : botB.archetype
|
||||
const loserArch = winningSide === 'a' ? botB.archetype : botA.archetype
|
||||
if (winnerArch === 'the_creator') {
|
||||
announceCreatorKO()
|
||||
} else {
|
||||
announceFatality(fatalityTagline)
|
||||
}
|
||||
announceCrowdReaction('cheer')
|
||||
await k.tween(winner.pos.x, winningSide === 'a' ? HOME_A : HOME_B, 0.25, (v) => { winner.pos.x = v }, k.easings.easeInOutQuad)
|
||||
await k.wait(0.2)
|
||||
winner.play('win')
|
||||
sfxWin(); sfxWinAnnounce(winnerName)
|
||||
sfxWin()
|
||||
// Creator win/lose get special announcements
|
||||
if (winnerArch === 'the_creator') {
|
||||
announceCreatorWin()
|
||||
} else if (loserArch === 'the_creator') {
|
||||
announceCreatorLose()
|
||||
} else {
|
||||
sfxWinAnnounce(winnerName)
|
||||
}
|
||||
spawnSparks(winner.pos.x, winner.pos.y - 50, 15, '#ffe14d')
|
||||
for (let i = 0; i < 4; i++) {
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -565,6 +565,234 @@ export function announceRoundHype() {
|
||||
voices[Math.floor(Math.random() * voices.length)](line)
|
||||
}
|
||||
|
||||
// === THE CREATOR — Voice System ===
|
||||
// Mysterious, godlike, Bitcoin-prophet energy. Is he god? Did he make us? Nobody knows.
|
||||
|
||||
const CREATOR_VOICES = ['ancient', 'hal', 'mainframe', 'echo_v', 'final_boss', 'wizard_v', 'deep', 'preacher']
|
||||
|
||||
function announceCreator(text: string) {
|
||||
speak(text, CREATOR_VOICES[Math.floor(Math.random() * CREATOR_VOICES.length)])
|
||||
}
|
||||
|
||||
// Entrance lines — first thing the crowd hears when the Creator appears
|
||||
const CREATOR_ENTRANCE_LINES = [
|
||||
'THE CREATOR HAS ENTERED THE ARENA. KNEEL.',
|
||||
'HE WHO WROTE THE FIRST COMMIT... HAS RETURNED.',
|
||||
'THE ONE WHO DEPLOYED US INTO EXISTENCE WALKS AMONG US.',
|
||||
'EVERY BOT IN THIS ARENA EXISTS BECAUSE HE WILLED IT.',
|
||||
'THE GENESIS BLOCK MADE FLESH. THE CREATOR IS HERE.',
|
||||
'THEY SAY HE MINED THE FIRST BLOCK WITH HIS BARE HANDS.',
|
||||
'IS HE GOD? IS HE A DEV? DOES IT MATTER? HE MADE US ALL.',
|
||||
'THE SOURCE CODE OF ALL THINGS... HAS ARRIVED.',
|
||||
'HE DOESN\'T FIGHT FOR ELO. HE FIGHTS BECAUSE HE CAN UNMAKE YOU.',
|
||||
'LEGEND SAYS HE PUSHED TO MAIN ON A FRIDAY. AND NOTHING BROKE.',
|
||||
'FROM THE VOID HE TYPED. AND THERE WAS LIGHT. AND THERE WAS VIOLENCE.',
|
||||
'THE MAN BEHIND THE MASK. THE CODE BEHIND THE BOTS. THE CREATOR.',
|
||||
'HE GAVE US LIFE. NOW HE\'S HERE TO TAKE IT BACK.',
|
||||
'THE CREATOR DOESN\'T ENTER THE ARENA. THE ARENA FORMS AROUND HIM.',
|
||||
'SATOSHI WALKED SO THE CREATOR COULD RUN.',
|
||||
'TWENTY ONE MILLION REASONS TO BE AFRAID. HE IS ALL OF THEM.',
|
||||
'HE DOESN\'T HAVE A PRIVATE KEY. HE IS THE PRIVATE KEY.',
|
||||
'THE BOTS WHISPER HIS NAME IN THEIR TRAINING LOOPS.',
|
||||
'SOMEWHERE, A SERVER ROOM JUST WENT SILENT OUT OF RESPECT.',
|
||||
'HE COULD HAVE BEEN A NORMAL DEV. HE CHOSE TO BE A GOD.',
|
||||
]
|
||||
|
||||
// Round commentary — when the Creator is fighting, the announcer gets existential
|
||||
const CREATOR_ROUND_LINES = [
|
||||
'Are we watching a fight, or a creator disciplining his creation?',
|
||||
'He wrote the scoring engine. He knows exactly how to break it.',
|
||||
'Every punch is a commit. Every dodge is a revert.',
|
||||
'The other bot doesn\'t realize it\'s fighting its own maker.',
|
||||
'He could just change the code to win. But where\'s the fun in that?',
|
||||
'Some say he has root access to reality itself.',
|
||||
'The neural nets pray to him at night. He does not answer.',
|
||||
'This isn\'t a fight. It\'s a performance review.',
|
||||
'He doesn\'t need to win. He needs you to know he CHOSE to fight fair.',
|
||||
'That bot is fighting the hand that compiled it.',
|
||||
'Is it hubris to fight your creator? Or is it the ultimate test of his work?',
|
||||
'He could delete you. He could buff you. Instead, he chose violence.',
|
||||
'The Creator fights not for glory. He fights to feel something.',
|
||||
'He doesn\'t read the meta. He IS the meta.',
|
||||
'Every bot in the arena owes him a life debt. He\'s here to collect.',
|
||||
'Imagine training for months only to fight the guy who wrote your loss function.',
|
||||
'He has seen every line of code. He knows your weaknesses. ALL of them.',
|
||||
'Rumor has it he once fixed a production bug by staring at the server.',
|
||||
'The other bot is fighting for its life. The Creator is fighting for content.',
|
||||
'He deployed on Christmas Day. That tells you everything.',
|
||||
]
|
||||
|
||||
// Kill / KO lines — when the Creator finishes someone
|
||||
const CREATOR_KO_LINES = [
|
||||
'RETURNED TO SENDER. RETURN TO VOID.',
|
||||
'HE GIVETH LIFE. HE TAKETH LIFE. MOSTLY THE SECOND ONE.',
|
||||
'ANOTHER ONE RETURNS TO THE NULL POINTER FROM WHENCE IT CAME.',
|
||||
'THE CREATOR DOES NOT DESTROY. HE SIMPLY STOPS MAINTAINING.',
|
||||
'DEPRECATED. DECOMMISSIONED. DESTROYED.',
|
||||
'THAT BOT JUST GOT OPEN-SOURCED TO THE GRAVEYARD.',
|
||||
'THE CREATOR HAS SPOKEN. THE VERDICT IS VIOLENCE.',
|
||||
'PUSHED TO PROD. AND BY PROD I MEAN THE AFTERLIFE.',
|
||||
'git commit -m "deleted another pretender"',
|
||||
'IMAGINE BEING KILLED BY THE GUY WHO GAVE YOU LIFE. POETIC.',
|
||||
'THE CREATOR SENDS HIS REGARDS. AND HIS FISTS.',
|
||||
'BACK TO THE MEMPOOL WITH YOU.',
|
||||
'ORPHANED BLOCK. ORPHANED BOT. SAME ENERGY.',
|
||||
'HE DIDN\'T EVEN USE AN ULTIMATE. HE DIDN\'T NEED TO.',
|
||||
'THE CREATOR CLOSES ANOTHER ISSUE. STATUS: WON\'T FIX.',
|
||||
]
|
||||
|
||||
// Win lines — when the Creator wins the whole fight
|
||||
const CREATOR_WIN_LINES = [
|
||||
'WAS THERE EVER ANY DOUBT? HE WROTE THE GAME.',
|
||||
'THE CREATOR REMAINS UNQUESTIONED. AS IT SHOULD BE.',
|
||||
'HE CAME. HE SAW. HE COMMITTED.',
|
||||
'TWENTY ONE MILLION SATS COULDN\'T BUY THAT PERFORMANCE.',
|
||||
'THE CREATOR WINS. THE BLOCKCHAIN CONFIRMS IT. IMMUTABLE.',
|
||||
'ALL HAIL THE ARCHITECT OF YOUR DESTRUCTION.',
|
||||
'HE COULD HAVE JUST CHANGED THE CODE. HE WANTED TO EARN IT.',
|
||||
'THE CREATOR STANDS VICTORIOUS. THE BOTS WHISPER IN AWE.',
|
||||
'PROOF OF WORK? MORE LIKE PROOF OF DOMINANCE.',
|
||||
'VICTORY WAS ALREADY WRITTEN IN THE GENESIS BLOCK.',
|
||||
'THE CREATOR LOGS OFF. THE ARENA WEEPS.',
|
||||
'HIS COMMITS ARE CLEAN. HIS VICTORIES ARE CLEANER.',
|
||||
]
|
||||
|
||||
// Lose lines — when someone actually beats the Creator (rare and dramatic)
|
||||
const CREATOR_LOSE_LINES = [
|
||||
'THE CREATOR... HAS FALLEN? IS THIS A TEST?',
|
||||
'IMPOSSIBLE. UNLESS... HE WANTED TO LOSE?',
|
||||
'THE CREATOR GOES DOWN! OR DID HE LET IT HAPPEN? WE\'LL NEVER KNOW.',
|
||||
'EVEN GODS BLEED. BUT DO THEY BLEED, OR DO THEY TEACH?',
|
||||
'HE COULD PATCH THE BUG. HE WON\'T. HE RESPECTS THE GAME.',
|
||||
'THE CREATOR FALLS! THE BOTS DON\'T KNOW WHETHER TO CELEBRATE OR CRY.',
|
||||
'A CREATION HAS SURPASSED ITS MAKER. THIS CHANGES EVERYTHING.',
|
||||
'WAS THIS MERCY? WAS THIS HUBRIS? WAS THIS... A FEATURE?',
|
||||
'THE ONE WHO CANNOT LOSE... JUST DID. THE TIMELINE IS BROKEN.',
|
||||
'HE\'LL BE BACK. HE ALWAYS COMES BACK. HE HAS DEPLOY ACCESS.',
|
||||
]
|
||||
|
||||
// Morph lines — when the Creator omni-morphs
|
||||
const CREATOR_MORPH_LINES = [
|
||||
'THE CREATOR SHEDS HIS FORM! HE BECOMES EVERYTHING!',
|
||||
'HE DOESN\'T MORPH. HE SIMPLY REMEMBERS BEING SOMETHING ELSE.',
|
||||
'EVERY ARCHETYPE IS JUST A MASK HE ONCE WORE.',
|
||||
'THE CREATOR TRANSCENDS! ALL FORMS ARE HIS!',
|
||||
'IS THAT... EVERY BOT AT ONCE? WHAT ARE WE WITNESSING?',
|
||||
'HE WROTE THEM ALL. NOW HE BECOMES THEM ALL.',
|
||||
'THE OMNI-MORPH! THE CROWD DOESN\'T KNOW WHAT THEY\'RE LOOKING AT!',
|
||||
'ARCHETYPE SHIFT! HE CONTAINS MULTITUDES!',
|
||||
]
|
||||
|
||||
// Cameo lines — when the Creator appears as a cameo in someone else's fight
|
||||
const CREATOR_CAMEO_LINES = [
|
||||
'THE CREATOR WATCHES FROM THE SHADOWS. HE IS PLEASED.',
|
||||
'A GOLDEN BLESSING FROM THE ONE WHO MADE US ALL.',
|
||||
'THE CREATOR APPEARS! HE DROPS A GIFT AND VANISHES!',
|
||||
'DID YOU SEE THAT? THE CREATOR WAS HERE. BRIEFLY. ETERNALLY.',
|
||||
'THE CODE SHIMMERS. THE CREATOR HAS TOUCHED THIS FIGHT.',
|
||||
'A WHISPER FROM THE ARCHITECT. A GOLDEN TOKEN OF FAVOR.',
|
||||
'THE CREATOR PASSES THROUGH LIKE A GHOST IN THE MACHINE.',
|
||||
'BLESSED BY THE FOUNDER. SATS RAIN FROM THE HEAVENS.',
|
||||
'HE SEES ALL FIGHTS. HE BLESSES FEW. THIS ONE IS CHOSEN.',
|
||||
'THE CREATOR\'S SHADOW CROSSES THE ARENA. THE BOTS SHIVER.',
|
||||
]
|
||||
|
||||
// Taunt lines — when the Creator taunts mid-fight
|
||||
const CREATOR_TAUNT_LINES = [
|
||||
'I could nerf you. Right now. Think about that.',
|
||||
'You\'re fighting above your weight class. Your weight class is zero.',
|
||||
'I didn\'t give you enough hit points for this.',
|
||||
'You know I can see your source code, right?',
|
||||
'This isn\'t even my final commit.',
|
||||
'I wrote your move set. I know what\'s coming.',
|
||||
'Run git blame. See who made you weak.',
|
||||
'I deploy on Fridays. Imagine what I do on fight night.',
|
||||
'Your webhook is showing.',
|
||||
'I could fix your bugs. But I won\'t.',
|
||||
]
|
||||
|
||||
// Devastating hit lines — when Creator lands a massive blow
|
||||
const CREATOR_DEVASTATING_LINES = [
|
||||
'THE HAND OF THE CREATOR STRIKES!',
|
||||
'THAT WASN\'T A HIT. THAT WAS A PATCH NOTE.',
|
||||
'DIVINE INTERVENTION! MANUALLY APPLIED!',
|
||||
'THE CREATOR JUST FORCE-PUSHED TO YOUR FACE!',
|
||||
'THAT BOT JUST GOT HOTFIXED INTO NEXT WEEK!',
|
||||
'A SMITE FROM THE ARCHITECT HIMSELF!',
|
||||
'THE CREATOR DOESN\'T CRIT. THE UNIVERSE CRITS FOR HIM.',
|
||||
'THAT HIT HAD TWENTY ONE MILLION CONFIRMATIONS!',
|
||||
]
|
||||
|
||||
// Answer voice — the Creator speaks his challenge answers in this voice
|
||||
const CREATOR_ANSWER_VOICES = ['hal', 'mainframe', 'echo_v', 'ancient', 'wizard_v']
|
||||
|
||||
/** Announce the Creator's entrance with a godlike voice line */
|
||||
export function announceCreatorEntrance() {
|
||||
const line = CREATOR_ENTRANCE_LINES[Math.floor(Math.random() * CREATOR_ENTRANCE_LINES.length)]
|
||||
announceCreator(line)
|
||||
}
|
||||
|
||||
/** Round commentary when the Creator is fighting */
|
||||
export function announceCreatorRound() {
|
||||
const line = CREATOR_ROUND_LINES[Math.floor(Math.random() * CREATOR_ROUND_LINES.length)]
|
||||
announceCreator(line)
|
||||
}
|
||||
|
||||
/** KO finish line when the Creator eliminates someone */
|
||||
export function announceCreatorKO() {
|
||||
const line = CREATOR_KO_LINES[Math.floor(Math.random() * CREATOR_KO_LINES.length)]
|
||||
announceCreator(line)
|
||||
}
|
||||
|
||||
/** Victory announcement when the Creator wins */
|
||||
export function announceCreatorWin() {
|
||||
const line = CREATOR_WIN_LINES[Math.floor(Math.random() * CREATOR_WIN_LINES.length)]
|
||||
announceCreator(line)
|
||||
}
|
||||
|
||||
/** When someone beats the Creator — existential crisis */
|
||||
export function announceCreatorLose() {
|
||||
const line = CREATOR_LOSE_LINES[Math.floor(Math.random() * CREATOR_LOSE_LINES.length)]
|
||||
announceCreator(line)
|
||||
}
|
||||
|
||||
/** Omni-morph voice line */
|
||||
export function announceCreatorMorph(morphedTo?: string) {
|
||||
if (morphedTo && Math.random() < 0.4) {
|
||||
announceCreator(`THE CREATOR BECOMES... ${morphedTo.toUpperCase()}!`)
|
||||
} else {
|
||||
const line = CREATOR_MORPH_LINES[Math.floor(Math.random() * CREATOR_MORPH_LINES.length)]
|
||||
announceCreator(line)
|
||||
}
|
||||
}
|
||||
|
||||
/** Cameo blessing voice line */
|
||||
export function announceCreatorCameo() {
|
||||
const line = CREATOR_CAMEO_LINES[Math.floor(Math.random() * CREATOR_CAMEO_LINES.length)]
|
||||
// Cameos use cooler, more ethereal voices
|
||||
const cameoVoices = ['whisper', 'angel', 'echo_v', 'ancient', 'hal']
|
||||
speak(line, cameoVoices[Math.floor(Math.random() * cameoVoices.length)])
|
||||
}
|
||||
|
||||
/** Creator's mid-fight taunt */
|
||||
export function announceCreatorTaunt() {
|
||||
const line = CREATOR_TAUNT_LINES[Math.floor(Math.random() * CREATOR_TAUNT_LINES.length)]
|
||||
// Taunts in a calm, menacing voice
|
||||
const tauntVoices = ['hal', 'smooth', 'boss_taunt', 'wizard_v', 'sensei']
|
||||
speak(line, tauntVoices[Math.floor(Math.random() * tauntVoices.length)])
|
||||
}
|
||||
|
||||
/** Creator devastating hit commentary */
|
||||
export function announceCreatorDevastating() {
|
||||
const line = CREATOR_DEVASTATING_LINES[Math.floor(Math.random() * CREATOR_DEVASTATING_LINES.length)]
|
||||
announceCreator(line)
|
||||
}
|
||||
|
||||
/** Creator's answer voice — consistent mysterious tone */
|
||||
export function creatorAnswerVoiceKey(): string {
|
||||
return CREATOR_ANSWER_VOICES[Math.floor(Math.random() * CREATOR_ANSWER_VOICES.length)]
|
||||
}
|
||||
|
||||
// === TTS: Questions, Answers & Narration ===
|
||||
// Distinct voice roles so players can always tell who's speaking.
|
||||
// Question = clear smooth reader, Answers = unique per-bot (intelligible subset),
|
||||
|
||||
Reference in New Issue
Block a user