From 0836656f0f3358c5e0a2c427c1fa903f83b68b36 Mon Sep 17 00:00:00 2001 From: "C. Yang" Date: Thu, 4 Jan 2024 15:10:22 -0500 Subject: [PATCH] generate chat scripts --- assets/emotes/boo.png | Bin 0 -> 231 bytes assets/emotes/grumpy.png | Bin 0 -> 266 bytes assets/emotes/laugh.png | Bin 0 -> 281 bytes assets/emotes/sad.png | Bin 0 -> 216 bytes assets/emotes/smile.png | Bin 0 -> 236 bytes assets/emotes/surprised.png | Bin 0 -> 280 bytes assets/emotes/wave.png | Bin 0 -> 239 bytes assets/emotes/yelling.png | Bin 0 -> 281 bytes assets/speech-bubbles.aseprite | Bin 9442 -> 10695 bytes ideas.txt | 1 - src/actions.js | 2 + src/chats.js | 138 +++++++++++++++++++++++++++++++++ src/fish.js | 18 ++++- src/main.js | 7 ++ src/routines.js | 8 +- src/ui.js | 6 +- 16 files changed, 172 insertions(+), 8 deletions(-) create mode 100644 assets/emotes/boo.png create mode 100644 assets/emotes/grumpy.png create mode 100644 assets/emotes/laugh.png create mode 100644 assets/emotes/sad.png create mode 100644 assets/emotes/smile.png create mode 100644 assets/emotes/surprised.png create mode 100644 assets/emotes/wave.png create mode 100644 assets/emotes/yelling.png create mode 100644 src/chats.js diff --git a/assets/emotes/boo.png b/assets/emotes/boo.png new file mode 100644 index 0000000000000000000000000000000000000000..746814c5d8230c4e01e6ad41d5c437b6b0ed8bf2 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^azHG|!3HExrOA{7DaPU;cPEB*=VV?2ISV~q978-h zlM^Hq4tT6$Q)Qj}|HPka{&N#@*iJfl9(-bNPx##7RU!R7i>ClsyiEFbsta>Ol}owhR_W=`nK@#K6XaI7!lhS~9LvY$PV$!jBVw z&)5OrX=*%+`)(-O`*j=DJPEP9r>UVUkG(v=Wp34Yh#;QDqs; QqyPW_07*qoM6N<$f-j$L*8l(j literal 0 HcmV?d00001 diff --git a/assets/emotes/laugh.png b/assets/emotes/laugh.png new file mode 100644 index 0000000000000000000000000000000000000000..d1bb5d1ddada672966967e98a1ecc007e885d6d6 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^azHG|!3HExrOA{7DaPU;cPEB*=VV?2IhQ?M978-h zlM^H|8zzbz_2N?dzp?XvbwQg-amO}^w1;QCeIlM-{rYd>8-^yXsUklA9&Zwu&D^nd zj)ib0!-uGzchM0Ol$cXC&YnJ_U>Wly9k=Zdo~f#dbZ_Vs`$g# dRpw`4n6xo+mf*fmEnH978-h zlM^H|8zzbz_2N?dzp?XvbwQg-amO}^w1;QCeIlM-{rYd>8-^yXsUklA9&Zwu&D^nd zj)ib0!-uGzchM0Ol$cXC&YnJ_U>Wlyon@*DCzEmteRKXyPW?FdoLHOnT-}t@$;=hO z3fn|_<<8%D(&>3qB~`t2Z+(QW)3oKDWsA~e`0q{Pp3QuL(K7Yx31)^Lw%%c!&JAmU Pu4C|Y^>bP0l+XkKYerF5 literal 0 HcmV?d00001 diff --git a/assets/emotes/smile.png b/assets/emotes/smile.png new file mode 100644 index 0000000000000000000000000000000000000000..c502aa8f643e9ef2bc66894beec4eef1d9e36af9 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^azHG|!3HExrOA{7DaPU;cPEB*=VV?2Im8-^yXsUklA9&Zwu&D^nd zj)ib0!-uGzchM0Ol$cXC&YnJ_U>Wlyon@*DCzEmteRKXyPW?FdoLHOnT-}t@$;>)O zG=enOCnh8`98urJub5=25_#%?!-3=9<>n+FnYN&SF=&%;pj}%d&>Vvxvz>)D72bL| id=BhSrd(C#XJGhd?()Yw!pH>ZVg^rFKbLh*2~7YpC0M-x literal 0 HcmV?d00001 diff --git a/assets/emotes/surprised.png b/assets/emotes/surprised.png new file mode 100644 index 0000000000000000000000000000000000000000..1d35361da44e2537fa7bd20d5147ce2f73fc1e50 GIT binary patch literal 280 zcmV+z0q6dSP)Px#(n&-?R7i>KR67pCAPhB84-#czW8wxm0aNai3*{iqlr2L)CxH$Xm17K;wp;ra zr1va8^RNK;HK>;2p|^qKulF_S6PycbSyVi!erhq?w~p1ddFtE%IaG~@-iDlEMAWsh zL26#^NT7`uaR2}@UM}XUF}|%f9xk`@!H9DE*1eu3ICnUc!KB8~h{jGiZM^8MvjupA zIkOTEP+zoS)Hr6`e4a*_r!nEVVcs%sY1CR literal 0 HcmV?d00001 diff --git a/assets/emotes/wave.png b/assets/emotes/wave.png new file mode 100644 index 0000000000000000000000000000000000000000..f4ad273b273e99e6b90495e4640f3db4e3efd629 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^azHG|!3HExrOA{7DaPU;cPEB*=VV?2IV(L~978-h z-(GR#YEuwkeXv};)9h`O>v#JG?ee@M##?ynq9vKnE(t!g|D~e>OI`0CmVG8EGSh7M zyr(c!t>UwUwI9{ka$@}ik mpB*l+ZlO$2_NVFlpD@I|FH^H?yJ!t`G=rzBpUXO@geCyA+Flm` literal 0 HcmV?d00001 diff --git a/assets/emotes/yelling.png b/assets/emotes/yelling.png new file mode 100644 index 0000000000000000000000000000000000000000..ca73d00fc89a04dcda814ee8817cf5f5d4dc7f6c GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^azHG|!3HExrOA{7DaPU;cPEB*=VV?2IhQ?M978-h zlM^H|8zzbz_2N?dzp?XvbphLI%j}+>f9-Ruk8>=Z_%y;}p3gy+F0_IligvL7UtzrV;R9H{2RtLmE9JMm)ujP(<5x1D zyt*?DYuLneUlewoQ@?eb2MA)F{s-uU10^n~e&JtUH6!)Kv`IOIH?7sCu#{~No3`+c ztf$+Abi-{fZaIgX*)4(<*4cRLC`{RPl3QJ?fpPPU6=(c*JZV}|lElrwNY|~L!Ajxi cp^4lKPitbOABz_F0KLcH>FVdQ&MBb@0APo1oB#j- literal 0 HcmV?d00001 diff --git a/assets/speech-bubbles.aseprite b/assets/speech-bubbles.aseprite index 893956de50bf8b260454f6856b41affbe63f0dc5..8de45165f6948f102b57e84e65a966ef9409f427 100644 GIT binary patch delta 1091 zcmaFlc|4fuxaLHrI$n2828LfB6&X?(7#I{c_AY0f9Lgjx*@Y>V)hDquJ!7&zlLT9E zZe~uZ^ke}hQ8s3V;KUTg$pK8F+?))-r9}lrnZ>CoU{#KJ=|z?DASo_(hRD>MoXos* zIS`kVjlsRBG`FA<%$vN2iGxuZBn~vpDL-EZ%w%B*Pb^E_e1u6xvAz}P6jlXR1|bGE zhW|`J4j2e9@G?})NlrMx;>D%*e`BJK*Tz@B|DNR0K9oc~}_3!;=5l+5WjNyLk2o*xzYtW}83EY&`3eboNl1-Yy%n|4GK| zEFFS}pXrs93lxca=xtX#F1&8TG1b02IUn6!b^_I&m6j5VyOm!b6c0NxqxJOs7vB^% zUp#wg*|Y$gM_l?zmsl5WaqW!!VPLnJVL9){BYj|paZY}&++N=SW^r444qiiVJs&-pn=F`s0kFIsfe67tS64hLY)yL;Vx#Vm`I} z>5_T2<55${=M{qLJI)-QUdM6NaG%9Naq%l3j18Y1JfmV-KOsqP<4aP3SPOgADPwYtG_Yr z!R7ArJToLV)z#$WR3$ug>8XpU@?gDjr}wO1Oij`wp4rlcN15BAo{O=lEf8NXY4OMR zZArs**_0WLIecb3lh_&lp5FGi7HltH8Cr}8Gw=W{o_i^hi$OqyHNbnK>4|^WpIm1T z^x9s2-{G#&6N%tQOP^Sk-kxn4dha^!+U>i8P%_YNCn&e{K%8(k;+7-I^HA|28LfB1sPHp7#IXM_AY0fEXpJ>*@Y>V%`q>%s8Vin0F&tC hd}fZ#>zHK}+53R1SQS_&?^kPQF9EaJCZ}rT0sz^x754xD diff --git a/ideas.txt b/ideas.txt index 832fb51..01b6073 100644 --- a/ideas.txt +++ b/ideas.txt @@ -66,4 +66,3 @@ A: grumpy B: grumpy - If it goes down the negative branch, set both fish moods to unhappy. - If it goes down the positive branch, set both fish moods to happy. - diff --git a/src/actions.js b/src/actions.js index e2d0d5a..a081625 100644 --- a/src/actions.js +++ b/src/actions.js @@ -39,6 +39,8 @@ export default class ActionManager { case 'flip': fish.flipOverride = action.value; break; + case 'mood': + fish.updateMood(action.value, true); } } diff --git a/src/chats.js b/src/chats.js new file mode 100644 index 0000000..7b7bb41 --- /dev/null +++ b/src/chats.js @@ -0,0 +1,138 @@ +let pleasantChat = { + description: "FISH1 and FISH2 are having a nice chat.", + start: ['wave', 'wave', 'smile'], + positive: ['smile', 'happy', 'heart', 'A-happy', 'B-happy'], + negative: ['angry', 'surprised', 'grumpy', 'A-unhappy'], + isPositive: function (fish1, fish2) { + return Math.random() < 0.8; + }, +}; +let prankChat = { + description: "FISH1 is playing a prank on FISH2!", + start: ['boo', 'shocked', 'laugh'], + positive: ['laugh', 'heart', 'heart', 'A-happy', 'B-happy'], + negative: ['angry', 'surprised', 'grumpy', 'B-unhappy'], + isPositive: function (fish1, fish2) { + if (!fish2.goodMood) { + return Math.random() < 0.3; + } + return Math.random() < 0.6; + }, +}; +let cheerUpChat = { + description: "FISH1 is trying to cheer FISH2 up.", + start: ['smile', 'grumpy', 'heart'], + positive: ['heart', 'happy', 'smile', 'B-happy'], + negative: ['angry', 'surprised', 'grumpy'], + isPositive: function (fish1, fish2) { + return Math.random() < 0.7; + }, +}; +let argumentChat = { + description: "FISH1 and FISH2 are arguing about something...", + start: ['yelling', 'angry', 'angry'], + positive: ['sad', 'heart', 'heart', 'A-happy', 'B-happy'], + negative: ['yelling', 'grumpy', 'grumpy', 'A-unhappy', 'B-unhappy'], + isPositive: function (fish1, fish2) { + if (!fish1.goodMood && !fish2.goodMood) { + return false; + } + if (fish1.goodMood && fish2.goodMood) { + return Math.random() < 0.5; + } + return Math.random() < 0.3; + } +}; + +export default function generateChatScripts(fish1, fish2) { + console.log(`${fish1.name} is feeling ${fish1.mood}`); + console.log(`${fish2.name} is feeling ${fish2.mood}`); + + // Choose which chat the fish will have + let chat = null; + let chance = Math.random(); + if (fish1.goodMood && fish2.goodMood) { + // Both fish are in a good mood + if (chance < 0.6) { + chat = pleasantChat; + } else if (chance < 0.9) { + chat = prankChat; + } else { + chat = argumentChat; + } + } else if (fish1.goodMood && !fish2.goodMood) { + // Only first fish is in a good mood + if (chance < 0.7) { + chat = cheerUpChat; + } else if (chance < 0.8) { + chat = pleasantChat; + } else if (chance < 0.9) { + chat = argumentChat; + } else { + chat = prankChat; + } + } else if (!fish1.goodMood && !fish2.goodMood) { + // Both fish are in a bad mood + if (chance < 0.8) { + chat = argumentChat; + } else if (chance < 0.9) { + chat = prankChat; + } else { + chat = pleasantChat; + } + } else { + // Only second fish is in a good mood + if (chance < 0.5) { + chat = argumentChat; + } else if (chance < 0.9) { + chat = pleasantChat; + } else { + chat = prankChat; + } + } + + // Determine whether the chat is positive or negative + let isPositive = chat.isPositive(fish1, fish2); + + // Concatenate the script cues + let cues = chat.start; + if (isPositive) { + cues = cues.concat(chat.positive); + } else { + cues = cues.concat(chat.negative); + } + + // Construct the two actual scripts + let scriptA = []; + let scriptB = []; + let flagA = true; + for(let cue of cues) { + let action = {}; + if (cue.includes("-")) { + action.type = "mood"; + action.value = cue.includes("-happy"); + action.duration = 0; + if (cue.includes("A-")) { + scriptA.push(action); + } else { + scriptB.push(action); + } + } else { + action.type = "emote"; + action.value = cue; + action.duration = 3000; + if (flagA) { + scriptA.push(action); + } else { + scriptB.push(action); + } + flagA = !flagA; + } + } + + return { + record: chat.description, + scriptA, + scriptB, + }; +} diff --git a/src/fish.js b/src/fish.js index 93edeed..35a93e3 100644 --- a/src/fish.js +++ b/src/fish.js @@ -21,7 +21,8 @@ export default class Fish { this.selected = false; // Personal information about this fish - this.name = randomFishName(); + this.name = randomFishName(); + this.updateMood(Math.random() > 0.5); } setRandomVelocity() { @@ -230,4 +231,19 @@ export default class Fish { this.action = false; this.flipOverride = null; } + + updateMood (goodMood, addRecord) { + let goodMoods = ["cheerful", "jovial", "happy", "great"]; + let badMoods = ["grumpy", "upset", "moody", "down"]; + this.goodMood = goodMood; + if (goodMood) { + this.mood = goodMoods[randomIntFromInterval(0, goodMoods.length-1)]; + } else { + this.mood = badMoods[randomIntFromInterval(0, badMoods.length-1)]; + } + + if (addRecord) { + uiManager.addRecord(`FISH1 is feeling ${this.mood}.`, this); + } + } } diff --git a/src/main.js b/src/main.js index ced9de2..7707e83 100644 --- a/src/main.js +++ b/src/main.js @@ -17,6 +17,13 @@ window.emoteImages = { happy: null, sleepy: null, angry: null, + grumpy: null, + wave: null, + smile: null, + surprised: null, + yelling: null, + boo: null, + sad: null, }; window.foodImages = { broccoli: null, diff --git a/src/routines.js b/src/routines.js index 0c506e9..db6bba4 100644 --- a/src/routines.js +++ b/src/routines.js @@ -1,12 +1,12 @@ import { states as fishStates } from './fish.js'; +import generateChatScripts from './chats.js'; export const SCRIPTS = { happy: [ { type: 'emote', value: 'happy', duration: 3000 }, // Set emote to happy, wait 3s { type: 'emote', value: null, duration: 1000 }, // Set emote to nothing, wait 3s - { type: 'state', value: fishStates.IDLING, duration: 1000 }, // Set state to idling - { type: 'state', value: fishStates.BOIDING, duration: 0 }, // Set state to boiding, go to next action { type: 'emote', value: 'heart', duration: 3000 }, // Set emote to heart, wait 3s + { type: 'mood', value: true, duration: 0}, // Set mood to happy ], moveToCorner: [ { type: 'state', value: fishStates.MOVING, duration: 4000, moveto: {x: 500, y: 500} }, @@ -119,6 +119,8 @@ export default class RoutineManager { indexB = randomIntFromInterval(0, filteredFish.length-1); } while (indexB == indexA); + console.log(generateChatScripts(filteredFish[indexA], filteredFish[indexB])); + // Choose two random conversation scripts let scriptA = JSON.parse(JSON.stringify(SCRIPTS.chat1[0])); let scriptB = JSON.parse(JSON.stringify(SCRIPTS.chat1[1])); @@ -149,7 +151,7 @@ export default class RoutineManager { ); // Add record - uiManager.addRecord(`FISH1 and FISH2 are having a nice chat!`, filteredFish[indexA], filteredFish[indexB]); + uiManager.addRecord("FISH1 and FISH2 are having a nice chat!", filteredFish[indexA], filteredFish[indexB]); }); } } diff --git a/src/ui.js b/src/ui.js index 461a630..d193548 100644 --- a/src/ui.js +++ b/src/ui.js @@ -40,11 +40,11 @@ export default class UIManager { fishImage.src = `assets/fish/fish${fish.type}.png`; // Create paragraphs for the name and personality - let nameParagraph = document.createElement("p"); - nameParagraph.innerHTML = `Name: ${fish.name}`; + let fishInfo = document.createElement("div"); + fishInfo.innerHTML = `Name: ${fish.name}
Mood: ${fish.mood}`; fishDiv.appendChild(fishImage); - fishDiv.appendChild(nameParagraph); + fishDiv.appendChild(fishInfo); // Add it to the selected fish div selectedFishDiv.appendChild(fishDiv);