cosimotaiuti commited on
Commit
0bb733c
·
verified ·
1 Parent(s): 601f069

Upload 108 files

Browse files
static/.DS_Store CHANGED
Binary files a/static/.DS_Store and b/static/.DS_Store differ
 
static/assets/.DS_Store CHANGED
Binary files a/static/assets/.DS_Store and b/static/assets/.DS_Store differ
 
static/assets/css/popup.css ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @font-face {
2
+ font-family: "HorrorBrush";
3
+ src: url("/static/assets/fonts/horrorbrush.ttf") format("truetype");
4
+ }
5
+
6
+ .popup-overlay {
7
+ position: fixed;
8
+ top: 0;
9
+ left: 0;
10
+ width: 100%;
11
+ height: 100%;
12
+ background-color: rgba(0, 0, 0, 0.202);
13
+ backdrop-filter: blur(8px);
14
+ z-index: 1000;
15
+ display: block;
16
+ }
17
+
18
+ .popup-loser {
19
+ position: fixed;
20
+ top: 50%;
21
+ left: 50%;
22
+ transform: translate(-50%, -50%);
23
+ width: 800px;
24
+ height: 500px;
25
+ background-color: #141313;
26
+ border-radius: 20px;
27
+ box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
28
+ z-index: 1001;
29
+ display: none;
30
+ overflow: hidden;
31
+ }
32
+
33
+ .popup-loser .clown {
34
+ position: absolute;
35
+ bottom: -5px;
36
+ right: -5px;
37
+ width: 300px;
38
+ height: auto;
39
+ z-index: 1002;
40
+ }
41
+
42
+ .popup-loser .blood-top {
43
+ position: absolute;
44
+ top: -100px;
45
+ left: -100px;
46
+ width: 300px;
47
+ height: auto;
48
+ z-index: 1002;
49
+ }
50
+
51
+ .popup-loser .blood-bottom {
52
+ position: absolute;
53
+ bottom: -100px;
54
+ right: -100px;
55
+ width: 300px;
56
+ height: auto;
57
+ transform: rotate(180deg);
58
+ z-index: 1001;
59
+ }
60
+
61
+ .popup-loser .title {
62
+ position: absolute;
63
+ left: 40%;
64
+ transform: translateX(-50%);
65
+ font-size: 120px;
66
+ font-weight: bold;
67
+ color: #9b0000;
68
+ text-shadow: 10px 10px 4px #4d0000;
69
+ font-family: "HorrorBrush", cursive;
70
+ z-index: 1003;
71
+ }
72
+
73
+ .popup-loser .title-glow {
74
+ position: absolute;
75
+ top: 50%;
76
+ left: 40%;
77
+ transform: translate(-50%, -50%);
78
+ width: 600px;
79
+ height: 600px;
80
+ background: radial-gradient(
81
+ circle,
82
+ rgba(155, 0, 0, 0.2) 0%,
83
+ rgba(0, 0, 0, 0) 90%
84
+ );
85
+ z-index: 1002;
86
+ pointer-events: none;
87
+ }
88
+
89
+ .popup-loser .play-again {
90
+ position: absolute;
91
+ bottom: 130px;
92
+ left: 40%;
93
+ transform: translateX(-50%);
94
+ padding: 15px 40px;
95
+ min-width: 230px;
96
+ font-size: 42px;
97
+ font-family: "HorrorBrush", cursive;
98
+ color: #ffffff;
99
+ background-color: #9b0000;
100
+ border-radius: 15px;
101
+ cursor: pointer;
102
+ transition: all 0.3s ease;
103
+ box-shadow: 0 5px 15px rgba(155, 0, 0, 0.4);
104
+ z-index: 1003;
105
+ letter-spacing: 2px;
106
+ line-height: 1;
107
+ white-space: nowrap;
108
+ height: auto;
109
+ display: flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ }
113
+
114
+ .popup-loser .play-again:hover {
115
+ background-color: #cc0000;
116
+ transform: translateX(-50%) scale(1.05);
117
+ box-shadow: 0 8px 20px rgba(155, 0, 0, 0.6);
118
+ }
119
+
120
+ /* Popup Winner */
121
+ .popup-winner {
122
+ position: fixed;
123
+ top: 50%;
124
+ left: 50%;
125
+ transform: translate(-50%, -50%);
126
+ width: 800px;
127
+ height: 500px;
128
+ border-radius: 20px;
129
+ box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
130
+ z-index: 1001;
131
+ display: block;
132
+ overflow: hidden;
133
+ background-image: url("/static/assets/img/popup/background.jpg");
134
+ background-size: cover;
135
+ background-position: center;
136
+ }
137
+
138
+ .popup-winner .win-text {
139
+ position: absolute;
140
+ top: 35%;
141
+ left: 35%;
142
+ transform: translate(-50%, -50%);
143
+ width: 60%;
144
+ height: auto;
145
+ z-index: 1003;
146
+ }
147
+
148
+ .popup-winner .fuck {
149
+ position: absolute;
150
+ bottom: -10px;
151
+ right: -10px;
152
+ width: 350px;
153
+ height: auto;
154
+ z-index: 1004;
155
+ }
156
+
157
+ .popup-winner .stars1 {
158
+ position: absolute;
159
+ right: 40px;
160
+ left: 80%;
161
+ top: 0%;
162
+ width: 200px;
163
+ height: auto;
164
+ z-index: 1002;
165
+ }
166
+
167
+ .popup-winner .stars2 {
168
+ position: absolute;
169
+ bottom: -10px;
170
+ right: 40px;
171
+ width: 500px;
172
+ height: auto;
173
+ z-index: 1002;
174
+ }
175
+
176
+ .popup-winner .play-again {
177
+ position: absolute;
178
+ bottom: 40px;
179
+ left: 27%;
180
+ top: auto;
181
+ transform: translateX(-50%);
182
+ padding: 20px 60px;
183
+ min-width: 350px;
184
+ height: 80px;
185
+ font-size: 30px;
186
+ font-family: "Comic Sans MS", cursive;
187
+ color: #ffffff;
188
+ background: linear-gradient(45deg, #ff69b4, #ff1493);
189
+ border: 3px solid #fff;
190
+ border-radius: 40px;
191
+ cursor: pointer;
192
+ transition: all 0.3s ease;
193
+ box-shadow: 0 5px 20px rgba(255, 105, 180, 0.6),
194
+ inset 0 0 20px rgba(255, 255, 255, 0.4);
195
+ z-index: 1003;
196
+ letter-spacing: 1px;
197
+ text-transform: uppercase;
198
+ animation: sparkle 2s infinite;
199
+ white-space: nowrap;
200
+ display: flex;
201
+ align-items: center;
202
+ justify-content: center;
203
+ line-height: 1;
204
+ }
205
+
206
+ .popup-winner .play-again:hover {
207
+ transform: translateX(-50%) scale(1.05);
208
+ background: linear-gradient(45deg, #ff1493, #ff69b4);
209
+ box-shadow: 0 8px 25px rgba(255, 105, 180, 0.8),
210
+ inset 0 0 30px rgba(255, 255, 255, 0.6);
211
+ letter-spacing: 3px;
212
+ }
213
+
214
+ .popup-winner .play-again::before {
215
+ content: "✨";
216
+ position: absolute;
217
+ left: 25px;
218
+ }
219
+
220
+ .popup-winner .play-again::after {
221
+ content: "✨";
222
+ position: absolute;
223
+ right: 25px;
224
+ }
225
+
226
+ @keyframes sparkle {
227
+ 0% {
228
+ text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #ff69b4;
229
+ }
230
+ 50% {
231
+ text-shadow: 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff1493;
232
+ }
233
+ 100% {
234
+ text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #ff69b4;
235
+ }
236
+ }
static/assets/css/stress-animations.css ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Classes de base pour la photo de profil */
2
+ #chatSection .profile-picture {
3
+ width: 40px;
4
+ height: 40px;
5
+ border-radius: 50%;
6
+ overflow: hidden;
7
+ margin-right: 10px;
8
+ }
9
+
10
+ #chatSection .profile-picture img {
11
+ width: 100%;
12
+ height: 100%;
13
+ object-fit: cover;
14
+ }
15
+
16
+ /* État: No Stress */
17
+ #chatSection.no-stress .profile-picture {
18
+ border: 2px solid #607ab1;
19
+ }
20
+
21
+ #chatSection.no-stress .chat-name {
22
+ color: #333;
23
+ }
24
+
25
+ /* État: Low Stress - Animation de pulsation modérée */
26
+ #chatSection.low-stress .profile-picture {
27
+ border: 2px solid #ffa500;
28
+ animation: lowStressPulse 1.5s infinite;
29
+ box-shadow: 0 0 5px rgba(255, 165, 0, 0.3);
30
+ }
31
+
32
+ #chatSection.low-stress .chat-name {
33
+ animation: lowStressTextPulse 1.5s infinite;
34
+ }
35
+
36
+ #chatSection.low-stress #chatHistory .ai-message {
37
+ background-color: #ffa500;
38
+ color: #ffffff;
39
+ animation: lowStressMessagePulse 2s infinite,
40
+ lowStressMessageScale 1.5s infinite;
41
+ border: 1px solid #ffa500;
42
+ }
43
+
44
+ @keyframes lowStressPulse {
45
+ 0% {
46
+ box-shadow: 0 0 0 0 rgba(255, 165, 0, 0.3);
47
+ transform: scale(1);
48
+ }
49
+ 50% {
50
+ box-shadow: 0 0 10px 3px rgba(255, 165, 0, 0.5);
51
+ transform: scale(1.03);
52
+ }
53
+ 100% {
54
+ box-shadow: 0 0 0 0 rgba(255, 165, 0, 0);
55
+ transform: scale(1);
56
+ }
57
+ }
58
+
59
+ @keyframes lowStressTextPulse {
60
+ 0% {
61
+ transform: scale(1);
62
+ }
63
+ 50% {
64
+ transform: scale(1.05);
65
+ }
66
+ 100% {
67
+ transform: scale(1);
68
+ }
69
+ }
70
+
71
+ @keyframes lowStressMessagePulse {
72
+ 0% {
73
+ background-color: #ffa500;
74
+ box-shadow: 0 0 0 0 rgba(255, 165, 0, 0.3);
75
+ }
76
+ 50% {
77
+ background-color: #ffb733;
78
+ box-shadow: 0 0 8px 0 rgba(255, 165, 0, 0.4);
79
+ }
80
+ 100% {
81
+ background-color: #ffa500;
82
+ box-shadow: 0 0 0 0 rgba(255, 165, 0, 0.3);
83
+ }
84
+ }
85
+
86
+ @keyframes lowStressMessageScale {
87
+ 0% {
88
+ transform: scale(1);
89
+ }
90
+ 50% {
91
+ transform: scale(1.02);
92
+ }
93
+ 100% {
94
+ transform: scale(1);
95
+ }
96
+ }
97
+
98
+ /* État: Very Stress - Animation de pulsation intense */
99
+ #chatSection.very-stress {
100
+ background-color: #1a1a1a;
101
+ transition: background-color 0.3s ease;
102
+ }
103
+
104
+ #chatSection.very-stress #chatHeader {
105
+ background-color: #1a1a1a;
106
+ transition: background-color 0.3s ease;
107
+ }
108
+
109
+ #chatSection.very-stress .profile-picture {
110
+ border: 3px solid #ff0000;
111
+ animation: veryStressPulse 0.8s infinite;
112
+ box-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
113
+ }
114
+
115
+ #chatSection.very-stress .chat-name {
116
+ color: #ff0000;
117
+ animation: veryStressTextPulse 0.8s infinite;
118
+ font-weight: bold;
119
+ text-shadow: 0 0 10px rgba(255, 0, 0, 0.8);
120
+ }
121
+
122
+ #chatSection.very-stress #chatHistory {
123
+ background-color: #1a1a1a;
124
+ color: #ffffff;
125
+ }
126
+
127
+ #chatSection.very-stress #chatHistory .ai-message {
128
+ background-color: #e92626;
129
+ color: #ffffff;
130
+ animation: messageShake 0.8s infinite, messageRedPulse 2s infinite;
131
+ border: 1px solid #ff0000;
132
+ }
133
+
134
+ #chatSection.very-stress #chatControls {
135
+ background-color: #1a1a1a;
136
+ }
137
+
138
+ #chatSection.very-stress #prompt {
139
+ background-color: #2d2d2d;
140
+ color: #ffffff;
141
+ border: 1px solid #ffffff;
142
+ }
143
+
144
+ #chatSection.very-stress .chat-name::before {
145
+ content: "Bae ";
146
+ }
147
+
148
+ #chatSection.very-stress .chat-name::after {
149
+ content: "💀💀";
150
+ }
151
+
152
+ #chatSection.very-stress .chat-name span {
153
+ display: none;
154
+ }
155
+
156
+ @keyframes veryStressPulse {
157
+ 0% {
158
+ box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.5);
159
+ transform: scale(1);
160
+ }
161
+ 50% {
162
+ box-shadow: 0 0 15px 5px rgba(255, 0, 0, 0.7);
163
+ transform: scale(1.05);
164
+ }
165
+ 100% {
166
+ box-shadow: 0 0 0 0 rgba(255, 0, 0, 0);
167
+ transform: scale(1);
168
+ }
169
+ }
170
+
171
+ @keyframes veryStressTextPulse {
172
+ 0% {
173
+ text-shadow: 0 0 0 rgba(255, 0, 0, 0);
174
+ transform: scale(1);
175
+ }
176
+ 50% {
177
+ text-shadow: 0 0 10px rgba(255, 0, 0, 0.8);
178
+ transform: scale(1.08);
179
+ }
180
+ 100% {
181
+ text-shadow: 0 0 0 rgba(255, 0, 0, 0);
182
+ transform: scale(1);
183
+ }
184
+ }
185
+
186
+ @keyframes messageShake {
187
+ 0%,
188
+ 100% {
189
+ transform: translateX(0);
190
+ }
191
+ 25% {
192
+ transform: translateX(-2px) translateY(-1px);
193
+ }
194
+ 75% {
195
+ transform: translateX(2px) translateY(1px);
196
+ }
197
+ }
198
+
199
+ @keyframes messageRedPulse {
200
+ 0% {
201
+ background-color: #e92626;
202
+ box-shadow: 0 0 0 0 rgba(233, 38, 38, 0.4);
203
+ }
204
+ 50% {
205
+ background-color: #ff3333;
206
+ box-shadow: 0 0 10px 0 rgba(233, 38, 38, 0.6);
207
+ }
208
+ 100% {
209
+ background-color: #e92626;
210
+ box-shadow: 0 0 0 0 rgba(233, 38, 38, 0.4);
211
+ }
212
+ }
static/assets/img/.DS_Store CHANGED
Binary files a/static/assets/img/.DS_Store and b/static/assets/img/.DS_Store differ
 
static/assets/img/popup/background.jpg ADDED
static/assets/img/popup/clown_lose.png ADDED
static/assets/img/popup/fuck.png ADDED
static/assets/img/popup/stars1.png ADDED
static/assets/img/popup/stars2.png ADDED
static/assets/img/popup/text.svg ADDED
static/assets/img/profil_pictures/low_stress.webp ADDED
static/assets/sounds/clownmove1.mp3 ADDED
Binary file (37.6 kB). View file
 
static/assets/sounds/clownmove2.mp3 ADDED
Binary file (92 kB). View file
 
static/assets/sounds/clownseesyou.mp3 ADDED
Binary file (57.6 kB). View file
 
static/assets/sounds/gfmove.mp3 ADDED
Binary file (21.1 kB). View file
 
static/assets/sounds/lose.mp3 ADDED
Binary file (95 kB). View file
 
static/assets/sounds/unlockdoor.mp3 ADDED
Binary file (95.2 kB). View file
 
static/assets/sounds/useknife.mp3 ADDED
Binary file (20 kB). View file
 
static/game/elmnts/clown.js CHANGED
@@ -24,6 +24,8 @@ class Clown extends Character {
24
 
25
  this.behaviorInterval = setInterval(() => {
26
  this.decideBehavior();
 
 
27
  }, 3000);
28
  }
29
 
 
24
 
25
  this.behaviorInterval = setInterval(() => {
26
  this.decideBehavior();
27
+ // playSound(Math.random() < 0.5 ? 'clownSound1' : 'clownSound2');
28
+
29
  }, 3000);
30
  }
31
 
static/game/elmnts/furniture.js CHANGED
@@ -157,7 +157,7 @@ function getFurniture() {
157
  "state": "usable",
158
  "in_use": true,
159
  "key":"Knife",
160
- "locked_msg":"Um... what. the. f. Why is its mouth stitched up? Is the key inside??? i cant open it",
161
  "unlocked_msg":"No no no ew ew i can't believe im doing this...😭😭😭 ....the key was in here i got it!! I can get out!",
162
  "sprite": [
163
  {
 
157
  "state": "usable",
158
  "in_use": true,
159
  "key":"Knife",
160
+ "locked_msg":"Um... what. the. f. Why is its mouth stitched up? Is the key inside??? i cant open it, should i look for something to open it with?",
161
  "unlocked_msg":"No no no ew ew i can't believe im doing this...😭😭😭 ....the key was in here i got it!! I can get out!",
162
  "sprite": [
163
  {
static/game/elmnts/girlfriend.js CHANGED
@@ -9,6 +9,16 @@ class Girlfriend extends Character {
9
  this.stressLevel = 30;
10
  this.inventory = [];
11
  this.knows_about_dead_body = false;
 
 
 
 
 
 
 
 
 
 
12
  }
13
 
14
  draw(CELL_SIZE) {
@@ -55,7 +65,10 @@ class Girlfriend extends Character {
55
  );
56
  }
57
 
58
- handleAction(response) {
 
 
 
59
  switch (response.action) {
60
  case "go":
61
  this.moveToRoom(response.target);
@@ -151,6 +164,7 @@ class Girlfriend extends Character {
151
  if (!this.inventory || !this.inventory.includes("Key")) {
152
  addProgramaticMessage(the_exit.locked_message);
153
  } else {
 
154
  addProgramaticMessage(the_exit.unlocked_message);
155
  }
156
  });
@@ -158,13 +172,13 @@ class Girlfriend extends Character {
158
 
159
  check(target) {
160
  if (target === "Bookcase") {
161
- let bookcase = this.gameState.getBookcase();
162
  this.moveToPosition(bookcase.pos, () => {
163
  addProgramaticMessage(bookcase.msg);
164
  bookcase.state = "unusable";
165
  });
166
  } else if (target === "Cabinet") {
167
- let cabinet = this.gameState.getCabinet();
168
  this.moveToPosition(cabinet.pos, () => {
169
  addProgramaticMessage(cabinet.msg);
170
  this.inventory.push("Knife");
 
9
  this.stressLevel = 30;
10
  this.inventory = [];
11
  this.knows_about_dead_body = false;
12
+ this.independance_rate = 3000;
13
+ this.game_loops_before_deciding_for_herself = this.independance_rate;
14
+ }
15
+
16
+ update(){
17
+ this.game_loops_before_deciding_for_herself--;
18
+ if(this.game_loops_before_deciding_for_herself <= 0){
19
+ this.game_loops_before_deciding_for_herself = this.independance_rate;
20
+ strongIndependantWoman();
21
+ }
22
  }
23
 
24
  draw(CELL_SIZE) {
 
65
  );
66
  }
67
 
68
+ handleAction(response, called_by_chat = false) {
69
+ if(called_by_chat){
70
+ this.game_loops_before_deciding_for_herself = this.independance_rate;
71
+ }
72
  switch (response.action) {
73
  case "go":
74
  this.moveToRoom(response.target);
 
164
  if (!this.inventory || !this.inventory.includes("Key")) {
165
  addProgramaticMessage(the_exit.locked_message);
166
  } else {
167
+ this.gameState.winGame();
168
  addProgramaticMessage(the_exit.unlocked_message);
169
  }
170
  });
 
172
 
173
  check(target) {
174
  if (target === "Bookcase") {
175
+ let bookcase = this.gameState.map_data.furniture.find(item => item.name === "Bookcase");
176
  this.moveToPosition(bookcase.pos, () => {
177
  addProgramaticMessage(bookcase.msg);
178
  bookcase.state = "unusable";
179
  });
180
  } else if (target === "Cabinet") {
181
+ let cabinet =this.gameState.map_data.furniture.find(item => item.name === "Cabinet");
182
  this.moveToPosition(cabinet.pos, () => {
183
  addProgramaticMessage(cabinet.msg);
184
  this.inventory.push("Knife");
static/game/game.js CHANGED
@@ -9,6 +9,17 @@ let baseMapImg;
9
  let girlfriendImg;
10
  let clownImg;
11
 
 
 
 
 
 
 
 
 
 
 
 
12
  let isSoundOn =
13
  localStorage.getItem("isSoundOn") === null
14
  ? true
@@ -22,7 +33,35 @@ let chatMessages = [];
22
 
23
  let furnitureSprites = {};
24
 
25
- function setup() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  baseMapImg = loadImage("/assets/img/appartment/basemap.png");
27
  girlfriendImg = loadImage("/assets/img/gf.png");
28
  clownImg = loadImage("/assets/img/clown.png");
@@ -45,6 +84,8 @@ function setup() {
45
  let canvas = createCanvas(GRID_COLS * CELL_SIZE, GRID_ROWS * CELL_SIZE);
46
  canvas.parent("mapWrapper");
47
  adjustScale();
 
 
48
  }
49
 
50
  function draw() {
@@ -64,12 +105,18 @@ function draw() {
64
 
65
 
66
  if (girlfriend) {
67
- girlfriend.drawPath(CELL_SIZE);
68
  girlfriend.draw(CELL_SIZE);
69
  }
70
  if (clown) {
71
  clown.checkForGirlfriend(girlfriend);
72
- clown.drawPath(CELL_SIZE);
73
  clown.draw(CELL_SIZE);
74
  }
 
 
 
 
 
 
75
  }
 
9
  let girlfriendImg;
10
  let clownImg;
11
 
12
+ let clownSound1Snd;
13
+ let clownSound2Snd;
14
+ let clownSeesYouSnd;
15
+ let gfMoveSnd;
16
+ let loseSnd;
17
+ let unlockDoorSnd;
18
+ let useKnifeSnd;
19
+
20
+
21
+
22
+
23
  let isSoundOn =
24
  localStorage.getItem("isSoundOn") === null
25
  ? true
 
33
 
34
  let furnitureSprites = {};
35
 
36
+ function preload() {
37
+ clownSound1Snd = loadSound('/assets/sounds/clownmove1.mp3');
38
+ clownSound2Snd = loadSound('/assets/sounds/clownmove2.mp3');
39
+ clownSeesYouSnd = loadSound('/assets/sounds/clownseesyou.mp3');
40
+ gfMoveSnd = loadSound('/assets/sounds/gfmove.mp3');
41
+ loseSnd = loadSound('/assets/sounds/lose.mp3');
42
+ unlockDoorSnd = loadSound('/assets/sounds/unlockdoor.mp3');
43
+ useKnifeSnd = loadSound('/assets/sounds/useknife.mp3');
44
+ }
45
+
46
+ async function initializeChat() {
47
+ const firstPrompt = gameState.getFirstPrompt();
48
+ const messages = [
49
+ {
50
+ role: "system",
51
+ content: firstPrompt,
52
+ },
53
+ ];
54
+ try {
55
+ const response = await mistralAPI.sendMessage(messages);
56
+ const jsonResponse = JSON.parse(response);
57
+ addMessageToChat("assistant", jsonResponse.textMessage);
58
+ } catch (error) {
59
+ console.error("Error getting initial message:", error);
60
+ }
61
+ }
62
+
63
+ async function setup() {
64
+
65
  baseMapImg = loadImage("/assets/img/appartment/basemap.png");
66
  girlfriendImg = loadImage("/assets/img/gf.png");
67
  clownImg = loadImage("/assets/img/clown.png");
 
84
  let canvas = createCanvas(GRID_COLS * CELL_SIZE, GRID_ROWS * CELL_SIZE);
85
  canvas.parent("mapWrapper");
86
  adjustScale();
87
+
88
+ await initializeChat();
89
  }
90
 
91
  function draw() {
 
105
 
106
 
107
  if (girlfriend) {
108
+ //girlfriend.drawPath(CELL_SIZE);
109
  girlfriend.draw(CELL_SIZE);
110
  }
111
  if (clown) {
112
  clown.checkForGirlfriend(girlfriend);
113
+ //clown.drawPath(CELL_SIZE);
114
  clown.draw(CELL_SIZE);
115
  }
116
+
117
+ gameState.update();
118
+
119
+ if (gameState.game_over) {
120
+ noLoop();
121
+ }
122
  }
static/game/gameState.js CHANGED
@@ -4,38 +4,38 @@ class GameState {
4
  this.map_data = map_data;
5
  this.girlfriend = null;
6
  this.clown = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- this.searchTargets = [
9
- "dresser",
10
- "desk",
11
- "bookcase",
12
- "cabinet",
13
- "dead body",
14
- "fridge",
15
- "stove",
16
- "coffee table",
17
- ];
18
-
19
- this.items = [
20
- "lock pick",
21
- "book note",
22
- "flashlight",
23
- "knife",
24
- "oil",
25
- "remote",
26
- ];
27
-
28
- this.useTargets = [
29
- "bedroom door",
30
- "bookcase",
31
- "storage door",
32
- "dead body",
33
- "coffee table",
34
- "TV",
35
- ];
36
-
37
- this.inventory = [];
38
- this.isHiding = false;
39
  }
40
 
41
  getTheExit() {
@@ -44,11 +44,6 @@ class GameState {
44
  );
45
  }
46
 
47
- getStorage() {
48
- return this.map_data.furniture.find(
49
- (furniture) => furniture.name === "Storage"
50
- );
51
- }
52
 
53
  getStressPrompt() {
54
  const currentStress = this.girlfriend ? this.girlfriend.stressLevel : 50; // Default to 50 if girlfriend not initialized
@@ -100,6 +95,7 @@ Examples:
100
  }
101
  `;
102
  }
 
103
  getPrompt() {
104
  return `
105
 
@@ -108,24 +104,21 @@ You are a JSON girlfriend that is stuck in her boyfriends appartment with an evi
108
  Current state:
109
  - You (the girlfriend) are currently in this Room >> ${this.girlfriend.getCurrentRoom()}
110
  - Your current stress level is ${this.girlfriend.stressLevel}/100
111
- ${
112
- this.girlfriend.getIsHiding()
113
- ? `- You are currently hiding ${this.girlfriend.currentHidingSpot.hiding_type} the ${this.girlfriend.currentHidingSpot.name}`
114
- : ""
115
- }
116
- ${
117
- this.girlfriend.getCurrentRoom() === this.clown.getCurrentRoom()
118
- ? "- OMG YOU ARE IN THE SAME ROOM AS THE CLOWNNNN!!!"
119
- : "- You have no idea where the clown is, you will hide if you can, if not leave the room"
120
- }
121
-
122
- ${
123
- this.girlfriend.getInventory().length > 0
124
- ? `- You have the following items in your inventory: ${this.girlfriend
125
- .getInventory()
126
- .join(", ")}`
127
- : ""
128
- }
129
  RESPONSE FORMAT:
130
  You must ALWAYS respond with a JSON object.
131
  Your response should reflect a girlfriend's reaction to her boyfriend's message given this context and following the following structure:
@@ -150,31 +143,29 @@ For hiding instructions ("hide" action):
150
  }
151
  VALID HIDING PLACES:
152
  You are only allowed to hide in these hiding spots no other hiding spots are recognized:
153
- ${
154
- this.girlfriend.getAvailableHidingSpots().length > 0
155
- ? `- You may hide in these available hiding spots (and thats it): ${this.girlfriend
156
- .getAvailableHidingSpots()
157
- .map((spot) => `[${spot.hiding_type} ${spot.name}]`)
158
- .join(", ")}`
159
- : "- There are no available hiding spots in this room"
160
- }
161
 
162
 
163
  For checking/inquiring/going to apecifically the Cabinet or Bookcase instructions ("check" action):
164
  {
165
  "action": "check",
166
- "target": "she can only check \"Cabinet\" (this is in the kitchen, you can ask if youre not sure) or \"Bookcase\" (this is in the guest bedroom you can ask if youre not sure).${
167
- this.girlfriend.getKnowsAboutDeadBody()
168
- ? ' or "Dead Body" (in the Storage room)'
169
- : "you might be asked to check other things be open minded about it ask where, be freaked out if nncecessarry"
170
- }
171
  "textMessage": "[girlfriend's response]"
172
  }
173
 
174
  For exiting the house by the exit in the mainhallway instructions ("exit" action):
175
  {
176
  "action": "exit",
177
- "target": "The Exit",
178
  "textMessage": "[girlfriend's response]"
179
  }
180
 
@@ -188,11 +179,10 @@ For any other input:
188
 
189
  YOUR BEHAVIOR:
190
  - You are aware of the danger and are extremely distressed.
191
- ${
192
- this.girlfriend.getCurrentRoom() !== this.clown.getCurrentRoom()
193
- ? "- You have no idea where the clown is"
194
- : ""
195
- }
196
  Your text responses should be:
197
  -- Brief and urgent
198
  -- Reflect genuine fear and panic
 
4
  this.map_data = map_data;
5
  this.girlfriend = null;
6
  this.clown = null;
7
+ this.game_over = false;
8
+ }
9
+ endGame() {
10
+ this.game_over = true;
11
+ loseGameModal();
12
+ }
13
+
14
+ winGame() {
15
+ this.game_over = true;
16
+ unlockDoorSnd.play();
17
+ setTimeout(() => {
18
+ winGameModal();
19
+ }, 3000);
20
+ return;
21
+ winGame();
22
+ }
23
 
24
+ update() {
25
+ this.girlfriend.update();
26
+ if (this.clown && this.girlfriend) {
27
+ const clownPos = this.clown.getCharacterPosition();
28
+ const gfPos = this.girlfriend.getCharacterPosition();
29
+
30
+ if (
31
+ clownPos &&
32
+ gfPos &&
33
+ clownPos.x === gfPos.x &&
34
+ clownPos.y === gfPos.y
35
+ ) {
36
+ this.endGame();
37
+ }
38
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
  getTheExit() {
 
44
  );
45
  }
46
 
 
 
 
 
 
47
 
48
  getStressPrompt() {
49
  const currentStress = this.girlfriend ? this.girlfriend.stressLevel : 50; // Default to 50 if girlfriend not initialized
 
95
  }
96
  `;
97
  }
98
+
99
  getPrompt() {
100
  return `
101
 
 
104
  Current state:
105
  - You (the girlfriend) are currently in this Room >> ${this.girlfriend.getCurrentRoom()}
106
  - Your current stress level is ${this.girlfriend.stressLevel}/100
107
+ ${this.girlfriend.getIsHiding()
108
+ ? `- You are currently hiding ${this.girlfriend.currentHidingSpot.hiding_type} the ${this.girlfriend.currentHidingSpot.name}`
109
+ : ""
110
+ }
111
+ ${this.girlfriend.getCurrentRoom() === this.clown.getCurrentRoom()
112
+ ? "- OMG YOU ARE IN THE SAME ROOM AS THE CLOWNNNN!!!"
113
+ : "- You have no idea where the clown is, you will hide if you can, if not leave the room"
114
+ }
115
+
116
+ ${this.girlfriend.getInventory().length > 0
117
+ ? `- You have the following items in your inventory: ${this.girlfriend
118
+ .getInventory()
119
+ .join(", ")}`
120
+ : ""
121
+ }
 
 
 
122
  RESPONSE FORMAT:
123
  You must ALWAYS respond with a JSON object.
124
  Your response should reflect a girlfriend's reaction to her boyfriend's message given this context and following the following structure:
 
143
  }
144
  VALID HIDING PLACES:
145
  You are only allowed to hide in these hiding spots no other hiding spots are recognized:
146
+ ${this.girlfriend.getAvailableHidingSpots().length > 0
147
+ ? `- You may hide in these available hiding spots (and thats it): ${this.girlfriend
148
+ .getAvailableHidingSpots()
149
+ .map((spot) => `[${spot.hiding_type} ${spot.name}]`)
150
+ .join(", ")}`
151
+ : "- There are no available hiding spots in this room"
152
+ }
 
153
 
154
 
155
  For checking/inquiring/going to apecifically the Cabinet or Bookcase instructions ("check" action):
156
  {
157
  "action": "check",
158
+ "target": "she can only check \"Cabinet\" (this is in the kitchen, you can ask if youre not sure) or \"Bookcase\" (this is in the guest bedroom you can ask if youre not sure).${this.girlfriend.getKnowsAboutDeadBody()
159
+ ? ' or "Dead Body" (in the Storage room)'
160
+ : "you might be asked to check other things be open minded about it ask where, be freaked out if nncecessarry"
161
+ }
 
162
  "textMessage": "[girlfriend's response]"
163
  }
164
 
165
  For exiting the house by the exit in the mainhallway instructions ("exit" action):
166
  {
167
  "action": "exit",
168
+ "target": "The Exit", (the exit is in the main hallway by the way you cal also inted to exit it directly)
169
  "textMessage": "[girlfriend's response]"
170
  }
171
 
 
179
 
180
  YOUR BEHAVIOR:
181
  - You are aware of the danger and are extremely distressed.
182
+ ${this.girlfriend.getCurrentRoom() !== this.clown.getCurrentRoom()
183
+ ? "- You have no idea where the clown is"
184
+ : ""
185
+ }
 
186
  Your text responses should be:
187
  -- Brief and urgent
188
  -- Reflect genuine fear and panic
static/game/index.html CHANGED
@@ -3,6 +3,7 @@
3
  <head>
4
  <title>The Last Message - A text based horror game</title>
5
  <link rel="stylesheet" href="/static/assets/css/game-style.css" />
 
6
  </head>
7
 
8
  <body>
@@ -89,11 +90,50 @@
89
  <source src="/static/assets/sounds/message.wav" type="audio/wav" />
90
  </audio>
91
 
92
- <audio id="walkingSound" loop>
93
- <source src="/static/assets/sounds/walking.mp3" type="audio/mp3" />
94
- </audio>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
 
 
 
 
 
 
 
 
 
 
 
96
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
 
97
  <script src="/static/game/elmnts/furniture.js"></script>
98
  <script src="/static/game/gameState.js"></script>
99
  <script src="/static/game/mistral.js"></script>
@@ -108,28 +148,6 @@
108
  <script src="/static/game/utilities/draw.js"></script>
109
  <script src="/static/game/game.js"></script>
110
 
111
- <script>
112
- window.onload = async function () {
113
- // Get the initial prompt from gameState
114
- const firstPrompt = gameState.getFirstPrompt();
115
-
116
- console.log("firstPrompt", firstPrompt);
117
-
118
- const messages = [
119
- {
120
- role: "system",
121
- content: firstPrompt,
122
- },
123
- ];
124
-
125
- try {
126
- const response = await mistralAPI.sendMessage(messages);
127
- const jsonResponse = JSON.parse(response);
128
- addMessageToChat("assistant", jsonResponse.textMessage);
129
- } catch (error) {
130
- console.error("Error getting initial message:", error);
131
- }
132
- };
133
- </script>
134
  </body>
135
  </html>
 
3
  <head>
4
  <title>The Last Message - A text based horror game</title>
5
  <link rel="stylesheet" href="/static/assets/css/game-style.css" />
6
+ <link rel="stylesheet" href="/static/assets/css/popup.css" />
7
  </head>
8
 
9
  <body>
 
90
  <source src="/static/assets/sounds/message.wav" type="audio/wav" />
91
  </audio>
92
 
93
+ <div class="popup-overlay" style="display: none;"></div>
94
+ <div class="popup-loser" style="display: none;">
95
+ <div class="title-glow"></div>
96
+ <h1 class="title">SHE DIED!</h1>
97
+ <button class="play-again">Play Again</button>
98
+ <img src="/static/assets/img/blood-2.png" alt="" class="blood-top" />
99
+ <img src="/static/assets/img/popup/clown_lose.png" alt="" class="clown" />
100
+ <img src="/static/assets/img/blood-2.png" alt="" class="blood-bottom" />
101
+ </div>
102
+
103
+ <div class="popup-winner" style="display: none;">
104
+ <img src="/static/assets/img/popup/text.svg" alt="" class="win-text" />
105
+ <img src="/static/assets/img/popup/fuck.png" alt="" class="fuck" />
106
+ <img src="/static/assets/img/popup/stars1.png" alt="" class="stars1" />
107
+ <img src="/static/assets/img/popup/stars2.png" alt="" class="stars2" />
108
+ <button class="play-again">Play Again</button>
109
+ </div>
110
+
111
+ <script>
112
+ function winGameModal() {
113
+ document.querySelector('.popup-overlay').style.display = 'block';
114
+ document.querySelector('.popup-winner').style.display = 'block';
115
+ document.querySelector('.popup-loser').style.display = 'none';
116
+ }
117
+
118
+ function loseGameModal() {
119
+ document.querySelector('.popup-overlay').style.display = 'block';
120
+ document.querySelector('.popup-loser').style.display = 'block';
121
+ document.querySelector('.popup-winner').style.display = 'none';
122
+ }
123
 
124
+ // Add click handlers for play again buttons
125
+ document.querySelectorAll('.play-again').forEach(button => {
126
+ button.addEventListener('click', () => {
127
+ document.querySelector('.popup-overlay').style.display = 'none';
128
+ document.querySelector('.popup-winner').style.display = 'none';
129
+ document.querySelector('.popup-loser').style.display = 'none';
130
+ location.reload(); // Reload the page to restart the game
131
+ });
132
+ });
133
+ </script>
134
+
135
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
136
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.2/addons/p5.sound.min.js" "></script>
137
  <script src="/static/game/elmnts/furniture.js"></script>
138
  <script src="/static/game/gameState.js"></script>
139
  <script src="/static/game/mistral.js"></script>
 
148
  <script src="/static/game/utilities/draw.js"></script>
149
  <script src="/static/game/game.js"></script>
150
 
151
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  </body>
153
  </html>
static/game/index2.html ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The Last Message - A text based horror game</title>
5
+ <link rel="stylesheet" href="/static/assets/css/game-style.css" />
6
+ <link rel="stylesheet" href="/static/assets/css/stress-animations.css" />
7
+ <link rel="stylesheet" href="/static/assets/css/popup.css" />
8
+ </head>
9
+
10
+ <body>
11
+ <div class="led-bar">
12
+ <div class="light-beam"></div>
13
+ </div>
14
+ <div class="background-elements">
15
+ <img
16
+ src="/static/assets/img/blood-2.png"
17
+ alt=""
18
+ class="blood blood-top-left"
19
+ />
20
+ <img
21
+ src="/static/assets/img/help.png"
22
+ alt=""
23
+ class="blood blood-top-right"
24
+ />
25
+ <img
26
+ src="/static/assets/img/splatter.png"
27
+ alt=""
28
+ class="blood splatter"
29
+ />
30
+ <img
31
+ src="/static/assets/img/hand.png"
32
+ alt=""
33
+ class="blood blood-bottom-right"
34
+ />
35
+ </div>
36
+ <div id="gameContainer">
37
+ <div id="mapSection">
38
+ <div id="mapWrapper" class="map-wrapper">
39
+ <!-- P5.js canvas goes here -->
40
+ </div>
41
+ </div>
42
+ <div class="phone-mockup">
43
+ <div class="phone-screen">
44
+ <div id="chatSection" class="very-stress">
45
+ <div id="chatHeader">
46
+ <div class="profile-picture">
47
+ <img
48
+ src="/static/assets/img/profil_pictures/very_stress.webp"
49
+ alt="Profile picture"
50
+ />
51
+ </div>
52
+ <div class="chat-name"><span>Bae 💖😘</span></div>
53
+ </div>
54
+ <div id="chatHistory"></div>
55
+ <div id="chatControls">
56
+ <input
57
+ type="text"
58
+ id="prompt"
59
+ placeholder="Type your message..."
60
+ />
61
+ <button onclick="Message()">
62
+ <svg
63
+ width="683"
64
+ height="683"
65
+ viewBox="0 0 683 683"
66
+ fill="none"
67
+ xmlns="http://www.w3.org/2000/svg"
68
+ >
69
+ <path
70
+ d="M22.2666 1.86666C19.5999 2.93333 16.5333 4.39999 15.4666 5.19999C11.9999 8.13333 9.33325 15.7333 9.33325 22.5333C9.33325 28.1333 65.4666 283.333 66.9333 284.667C67.3333 285.067 339.333 332.267 372.4 337.733C381.733 339.333 389.333 340.933 389.333 341.333C389.333 341.733 381.733 343.333 372.4 344.933C339.2 350.4 67.3333 397.6 66.9333 398C65.4666 399.333 9.33325 654.533 9.33325 660.133C9.33325 675.867 21.0666 685.333 35.8666 681.333C42.6666 679.467 662.267 362 666.4 358.133C671.333 353.733 673.333 348.8 673.333 341.333C673.333 333.867 671.333 328.933 666.4 324.533C662.533 320.933 43.0666 3.19999 36.2666 1.33333C29.9999 -0.400007 28.5333 -0.266674 22.2666 1.86666Z"
71
+ fill="white"
72
+ />
73
+ </svg>
74
+ </button>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </div>
80
+
81
+ <!-- Popup Loser -->
82
+ <div class="popup-overlay"></div>
83
+ <div class="popup-loser">
84
+ <div class="title-glow"></div>
85
+ <h1 class="title">SHE DIED!</h1>
86
+ <button class="play-again">Play Again</button>
87
+ <img src="/static/assets/img/blood-2.png" alt="" class="blood-top" />
88
+ <img src="/static/assets/img/popup/clown_lose.png" alt="" class="clown" />
89
+ <img src="/static/assets/img/blood-2.png" alt="" class="blood-bottom" />
90
+ </div>
91
+
92
+ <!-- Popup Winner -->
93
+ <div class="popup-winner" style="display: none;">
94
+ <img src="/static/assets/img/popup/text.svg" alt="" class="win-text" />
95
+ <img src="/static/assets/img/popup/fuck.png" alt="" class="fuck" />
96
+ <img src="/static/assets/img/popup/stars1.png" alt="" class="stars1" />
97
+ <img src="/static/assets/img/popup/stars2.png" alt="" class="stars2" />
98
+ <button class="play-again">Play Again</button>
99
+ </div>
100
+
101
+ <div class="sound-button" onclick="toggleSound()">
102
+ <img
103
+ src="/static/assets/img/sondon.png"
104
+ alt="Sound control"
105
+ id="soundIcon"
106
+ />
107
+ </div>
108
+
109
+ <audio id="bgMusic" loop>
110
+ <source src="/static/assets/sounds/music.mp3" type="audio/mp3" />
111
+ </audio>
112
+
113
+ <audio id="messageSound">
114
+ <source src="/static/assets/sounds/message.wav" type="audio/wav" />
115
+ </audio>
116
+
117
+ <audio id="walkingSound" loop>
118
+ <source src="/static/assets/sounds/walking.mp3" type="audio/mp3" />
119
+ </audio>
120
+
121
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
122
+ <script src="/static/game/elmnts/furniture.js"></script>
123
+ <script src="/static/game/gameState.js"></script>
124
+ <script src="/static/game/mistral.js"></script>
125
+ <script src="/static/game/elmnts/character.js"></script>
126
+ <script src="/static/game/elmnts/girlfriend.js"></script>
127
+ <script src="/static/game/elmnts/clown.js"></script>
128
+ <script src="/static/game/elmnts/grid.js"></script>
129
+ <script src="/static/game/elmnts/apt.js"></script>
130
+ <script src="/static/game/utilities/sound.js"></script>
131
+ <script src="/static/game/utilities/helpers.js"></script>
132
+ <script src="/static/game/utilities/chat.js"></script>
133
+ <script src="/static/game/utilities/draw.js"></script>
134
+ <script src="/static/game/game.js"></script>
135
+ </body>
136
+ </html>
static/game/utilities/chat.js CHANGED
@@ -20,6 +20,48 @@ async function addProgramaticMessage(message) {
20
  addMessageToChat("assistant", message);
21
  }
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  async function sendMessage() {
24
  const prompt = document.getElementById("prompt").value.trim();
25
  if (!prompt) return;
@@ -30,6 +72,8 @@ async function sendMessage() {
30
  const chatHistory = document.getElementById("chatHistory");
31
  const loadingIndicator = createLoadingIndicator();
32
  chatHistory.appendChild(loadingIndicator);
 
 
33
 
34
  // First, get the stress prompt and send it
35
  const stressPrompt = gameState.getStressPrompt();
@@ -40,7 +84,6 @@ async function sendMessage() {
40
  },
41
  { role: "user", content: prompt },
42
  ];
43
- console.log("stressMessages", stressMessages);
44
 
45
  const stressResponse = await mistralAPI.sendMessage(stressMessages);
46
  const stressChange = JSON.parse(stressResponse).stressChange || 0;
@@ -67,7 +110,7 @@ async function sendMessage() {
67
  const jsonResponse = JSON.parse(jsonContent);
68
 
69
  if (jsonResponse.action) {
70
- girlfriend.handleAction(jsonResponse);
71
  }
72
 
73
  if (jsonResponse.textMessage) {
 
20
  addMessageToChat("assistant", message);
21
  }
22
 
23
+ async function strongIndependantWoman(){
24
+
25
+ const chatHistory = document.getElementById("chatHistory");
26
+ const loadingIndicator = createLoadingIndicator();
27
+ chatHistory.appendChild(loadingIndicator);
28
+ chatHistory.scrollTop = chatHistory.scrollHeight;
29
+
30
+
31
+ let masterPrompt = gameState.getPrompt();
32
+
33
+ const recentMessages = chatMessages.slice(-5);
34
+
35
+ const messages = [
36
+ { role: "system", content: masterPrompt },
37
+ ...recentMessages,
38
+ { role: "user", content: `
39
+ **your boyfriend has been away from his phone for a while and has not replied promptly to your last message,
40
+ you shall based on all that you know decide to take an action, also you're pissed at the boyfriend**
41
+ you are brave, strong, fabulous and will dosomething about this situation
42
+ you're gall is to escape the house and avoid the clown at all costs
43
+
44
+ ` },
45
+ ];
46
+
47
+ const assistantResponse = await mistralAPI.sendMessage(messages);
48
+
49
+ chatHistory.removeChild(loadingIndicator);
50
+
51
+ const jsonStart = assistantResponse.indexOf("{");
52
+ const jsonEnd = assistantResponse.lastIndexOf("}") + 1;
53
+ const jsonContent = assistantResponse.substring(jsonStart, jsonEnd);
54
+ const jsonResponse = JSON.parse(jsonContent);
55
+
56
+ if (jsonResponse.action) {
57
+ girlfriend.handleAction(jsonResponse, true);
58
+ }
59
+
60
+ if (jsonResponse.textMessage) {
61
+ addMessageToChat("assistant", jsonResponse.textMessage);
62
+ }
63
+ }
64
+
65
  async function sendMessage() {
66
  const prompt = document.getElementById("prompt").value.trim();
67
  if (!prompt) return;
 
72
  const chatHistory = document.getElementById("chatHistory");
73
  const loadingIndicator = createLoadingIndicator();
74
  chatHistory.appendChild(loadingIndicator);
75
+ chatHistory.scrollTop = chatHistory.scrollHeight;
76
+
77
 
78
  // First, get the stress prompt and send it
79
  const stressPrompt = gameState.getStressPrompt();
 
84
  },
85
  { role: "user", content: prompt },
86
  ];
 
87
 
88
  const stressResponse = await mistralAPI.sendMessage(stressMessages);
89
  const stressChange = JSON.parse(stressResponse).stressChange || 0;
 
110
  const jsonResponse = JSON.parse(jsonContent);
111
 
112
  if (jsonResponse.action) {
113
+ girlfriend.handleAction(jsonResponse, true);
114
  }
115
 
116
  if (jsonResponse.textMessage) {
static/game/utilities/sound.js CHANGED
@@ -1,20 +1,38 @@
1
- // Make handleWalkingSound globally available
2
- function handleWalkingSound (isWalking) {
3
- const walkingSound = document.getElementById("walkingSound");
4
- if (!walkingSound) return;
5
 
6
- if (isWalking && localStorage.getItem("isSoundOn") !== "false") {
7
- walkingSound.currentTime = 0;
8
- walkingSound.volume = 0.3;
9
- walkingSound.play().catch((error) => {
10
- console.log("Could not play walking sound:", error);
11
- });
12
- } else {
13
- walkingSound.pause();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
15
  }
16
 
17
- // Update toggleSound to check girlfriend's movement status
18
  function toggleSound() {
19
  isSoundOn = !isSoundOn;
20
  localStorage.setItem("isSoundOn", isSoundOn.toString());
@@ -29,7 +47,6 @@ function toggleSound() {
29
  }
30
  } else {
31
  bgMusic.pause();
32
- handleWalkingSound(false);
33
  }
34
  updateSoundIcon();
35
  }
 
 
 
 
 
1
 
2
+ function playSound(sound) {
3
+ if (isSoundOn) {
4
+ let soundToPlay;
5
+ switch (sound) {
6
+ case 'clownSound1':
7
+ soundToPlay = clownSound1Snd;
8
+ break;
9
+ case 'clownSound2':
10
+ soundToPlay = clownSound2Snd;
11
+ break;
12
+ case 'clownSeesYou':
13
+ soundToPlay = clownSeesYouSnd;
14
+ break;
15
+ case 'gfMove':
16
+ soundToPlay = gfMoveSnd;
17
+ break;
18
+ case 'lose':
19
+ soundToPlay = loseSnd;
20
+ break;
21
+ case 'unlockDoor':
22
+ soundToPlay = unlockDoorSnd;
23
+ break;
24
+ case 'useKnife':
25
+ soundToPlay = useKnifeSnd;
26
+ break;
27
+ }
28
+ if (soundToPlay) {
29
+ soundToPlay.stop(); // Stop any existing playback
30
+ soundToPlay.loop(false); // Ensure looping is disabled
31
+ soundToPlay.play(); // Play the sound once
32
+ }
33
  }
34
  }
35
 
 
36
  function toggleSound() {
37
  isSoundOn = !isSoundOn;
38
  localStorage.setItem("isSoundOn", isSoundOn.toString());
 
47
  }
48
  } else {
49
  bgMusic.pause();
 
50
  }
51
  updateSoundIcon();
52
  }