Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5299 | igevorse | 1 | /****************************************************************** |
2 | * 21 days: a game for programmers |
||
3 | * Copyright (C) 2014 Maxim Grishin |
||
4 | * |
||
5 | * This program is free software; you can redistribute it and/or |
||
6 | * modify it under the terms of the GNU General Public License |
||
7 | * as published by the Free Software Foundation; either version 2 |
||
8 | * of the License, or (at your option) any later version. |
||
9 | * |
||
10 | * This program is distributed in the hope that it will be useful, |
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | * GNU General Public License for more details. |
||
14 | * |
||
15 | * You should have received a copy of the GNU General Public License |
||
16 | * along with this program; if not, write to the Free Software |
||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
||
18 | * MA 02110-1301, USA. |
||
19 | *******************************************************************/ |
||
20 | |||
21 | #define DEFAULT_PATH 0 |
||
22 | #define WORK_PATH 1 |
||
23 | #define STARTUP_PATH 2 |
||
24 | |||
25 | #include "sys.h" |
||
26 | #include "strings.h" |
||
27 | #include "interface.h" |
||
28 | #include "pq.h" |
||
29 | |||
30 | #ifdef _KOS32 |
||
31 | #include |
||
32 | #define vector vector21 |
||
33 | extern "C" { |
||
34 | void *__dso_handle = 0; |
||
35 | void *__cxa_atexit = 0; |
||
36 | void *__stack_chk_fail = 0; |
||
37 | } |
||
38 | #else |
||
39 | #define printf2 printf |
||
40 | #include |
||
41 | #include |
||
42 | using std::vector; |
||
43 | #include |
||
44 | #endif |
||
45 | |||
46 | #include |
||
47 | #include |
||
48 | using std::string; |
||
49 | |||
50 | Undo2 history; |
||
51 | |||
52 | /************************************** |
||
53 | * Player |
||
54 | *****************************************/ |
||
55 | long double playerMoney = 100; |
||
56 | int playerSalary = 0; |
||
57 | int playerSalaryFirstDay = 0; |
||
58 | int playerPath = DEFAULT_PATH; |
||
59 | int playerKarma = 20; |
||
60 | double dt = 1.0; // days per secons |
||
61 | long double gameTime = 0; // Time in days |
||
62 | double unreadMessages = 0; |
||
63 | unsigned int timeHops = 0; |
||
64 | bool allAchievesShowed = false; |
||
65 | bool charityUnlocked = false; |
||
66 | |||
67 | int playerFreelanceAttempts = 0; |
||
68 | bool controlFreelanceAttempts = false; |
||
69 | |||
70 | bool sentBotsmannLetter = false; |
||
71 | bool astraLetterSent = false; |
||
72 | bool shitCodeDetected = false; |
||
73 | bool shitLettersSent[3] = {0,0,0}; |
||
74 | bool shitLettersFinished[3] = {0,0,0}; |
||
75 | bool showCoursesTab = false; |
||
76 | PQ3 pq; // events priority queue |
||
77 | bool noPopularity = false; |
||
78 | short finalCardsUnlocked = 0; |
||
79 | bool finalCardUnlocked[5] = {0,0,0,0,0}; |
||
80 | bool returnTo21HintShowed = false; |
||
81 | // Player Stats |
||
82 | time_t playerStartedPlaying; |
||
83 | unsigned long playerTimeHops = 0; |
||
84 | unsigned long playerMessagesRead = 0; |
||
85 | unsigned long playerHelped = 0; |
||
86 | unsigned long playerDidntHelped = 0; |
||
87 | long double playerSpentRealDays = 0; |
||
88 | long double playerPrevUndo = 0; |
||
89 | long double playerMoneyEarned = 100; |
||
90 | long double playerMoneySpent = 0; |
||
91 | double playerMoneySpentForCharity = 0; |
||
92 | |||
93 | |||
94 | void mainGameCycle(); |
||
95 | int showSettingsScreen(); |
||
96 | int chooseCourse(); |
||
97 | void showAchievesScreen(); |
||
98 | |||
99 | void startNewGame(); |
||
100 | void initSendingMessage(); |
||
101 | void undo(long double toTime); |
||
102 | |||
103 | string getStatusLine(); |
||
104 | |||
105 | void addTimer(event e) { |
||
106 | if (e.type == SPECIAL_LETTER && |
||
107 | (e.idata == LETTER_SHITCODE_1 |
||
108 | || e.idata == LETTER_SHITCODE_2 |
||
109 | || e.idata == LETTER_SHITCODE_3) |
||
110 | && pq.containsType(e.type, e.idata)) |
||
111 | return; |
||
112 | if (e.type == MESSAGE && pq.containsType((int)e.type)) |
||
113 | return; |
||
114 | |||
115 | pq.insert(e); |
||
116 | history.insert(event(e.time + gameTime, e.type, e.idata)); |
||
117 | } |
||
118 | |||
119 | void unlockFinalCards(short p) { |
||
120 | if (!finalCardUnlocked[p]) |
||
121 | finalCardsUnlocked++; |
||
122 | |||
123 | finalCardUnlocked[p] = true; |
||
124 | } |
||
125 | |||
126 | void increaseMoney(long double m) { |
||
127 | playerMoney += m; |
||
128 | if (m > 0) |
||
129 | playerMoneyEarned += m; |
||
130 | if (m < 0) |
||
131 | playerMoneySpent -= m; |
||
132 | } |
||
133 | |||
134 | void increaseKarma(int k, bool addTimerMsg = true) { |
||
135 | if (playerKarma <= 0 && playerKarma+k>0) |
||
136 | initSendingMessage(); |
||
137 | int oldKarma = playerKarma; |
||
138 | playerKarma += k; |
||
139 | if (playerKarma < -100) |
||
140 | playerKarma = -100; |
||
141 | |||
142 | if (playerKarma > 100) |
||
143 | playerKarma = 100; |
||
144 | |||
145 | if (addTimerMsg && playerKarma - oldKarma != 0) |
||
146 | history.insert(event(2*dt, INCREASEPOPULARITY, playerKarma - oldKarma)); |
||
147 | } |
||
148 | |||
149 | void changePath(int to) { |
||
150 | history.insert(event(gameTime, CHANGEPATH, playerPath)); |
||
151 | playerPath = to; |
||
152 | } |
||
153 | |||
154 | void changeSalary(int to) { |
||
155 | history.insert(event(gameTime, CHANGESALARY, playerSalary)); |
||
156 | playerSalary = to; |
||
157 | } |
||
158 | |||
159 | void changeSalaryFirstDay(int to) { |
||
160 | history.insert(event(gameTime, CHANGESALARYFIRSTDAY, playerSalaryFirstDay)); |
||
161 | playerSalaryFirstDay = to; |
||
162 | } |
||
163 | |||
164 | int karma() { |
||
165 | return playerKarma; |
||
166 | } |
||
167 | |||
168 | void initSendingMessage() { |
||
169 | double newTime = (karma() <= 0)?0.0:0.5 ;//* karma() / 100.0; |
||
170 | if (newTime > 0) { |
||
171 | addTimer(event(newTime, MESSAGE)); |
||
172 | } |
||
173 | else { |
||
174 | noPopularity = true; |
||
175 | addTimer(event(0, NOPOPULARITY)); |
||
176 | } |
||
177 | } |
||
178 | |||
179 | void checkAchieves() { |
||
180 | /// No popularity |
||
181 | if (!achievesPicked[1] && noPopularity) |
||
182 | achievesPicked[1] = true; |
||
183 | /// Millionaire |
||
184 | if (!achievesPicked[3] && playerMoney >= 1000000.0) { |
||
185 | achievesPicked[3] = true; |
||
186 | charityUnlocked = true; |
||
187 | } |
||
188 | /// Time jumper |
||
189 | if (!achievesPicked[8] && timeHops >= 3) |
||
190 | achievesPicked[8] = true; |
||
191 | |||
192 | allAchievesShowed = true; |
||
193 | /// Show achieve notification |
||
194 | for (unsigned int i = 0; i < achievesNumber; i++) { |
||
195 | if (achievesPicked[i] && !achievesShowed[i]) { |
||
196 | drawModalWindow(achieves[i], newAchievement); |
||
197 | wait(); |
||
198 | if (i == 3) { |
||
199 | drawModalWindow(pressRForCharity, 0, "[R]"); |
||
200 | wait('r','R'); |
||
201 | } |
||
202 | achievesShowed[i] = true; |
||
203 | } |
||
204 | else if (!achievesShowed[i]) |
||
205 | allAchievesShowed = false; |
||
206 | } |
||
207 | } |
||
208 | |||
209 | void showMainMenu() { |
||
210 | string s = days21; |
||
211 | s+=mainMenuText; |
||
212 | drawWindow(s, gameName, "", txt("%s %s", one_or_two, developer)); |
||
213 | char menu = getAnswer('1', '2'); |
||
214 | |||
215 | switch(menu) { |
||
216 | case '1': |
||
217 | startNewGame(); |
||
218 | break; |
||
219 | case '2': // TODO: Save? |
||
220 | |||
221 | break; |
||
222 | } |
||
223 | } |
||
224 | |||
225 | void showAchievesScreen() { |
||
226 | string s; |
||
227 | for (unsigned short i = 0; i < achievesNumber; i++) |
||
228 | s += txt("[%c] %s \n", achievesPicked[i]?'X':' ', achieves[i]); |
||
229 | |||
230 | s += txt(finalCardsUnlockedText, finalCardsUnlocked, 5); |
||
231 | char totalCoursesCount = 12; |
||
232 | s += txt(coursesFinishedText, (int)finishedCoursesCount, (int)totalCoursesCount); |
||
233 | drawWindow(s, achievementsTitle, getStatusLine(), enter); |
||
234 | } |
||
235 | |||
236 | string printExactTask(int course, int task, int word) { |
||
237 | switch (course) { |
||
238 | case 1: |
||
239 | case 2: |
||
240 | return string(programmingTasks[task]); |
||
241 | break; |
||
242 | case 3: |
||
243 | case 4: |
||
244 | return string(mobileTasks[task]); |
||
245 | break; |
||
246 | case 5: |
||
247 | return string(webProgrammingTasks[task]); |
||
248 | break; |
||
249 | case 6: |
||
250 | return string(systemProgrammingTask[task]); |
||
251 | break; |
||
252 | case 7: |
||
253 | return string(adminTasks[task]); |
||
254 | break; |
||
255 | case 0: |
||
256 | default: |
||
257 | return txt(level1Task[task], level1TaskWords[word]); |
||
258 | break; |
||
259 | } |
||
260 | } |
||
261 | |||
262 | void showLearnDialog() { |
||
263 | string s = selectCourseText; |
||
264 | for (unsigned short i = 0; i < coursesNumber; i++) { |
||
265 | if (!coursesUnlocked[i]) |
||
266 | continue; |
||
267 | |||
268 | if (i == 2) { |
||
269 | s+=txt("3.%s\n", courses[2]); |
||
270 | for (int j = 0; j < advancedProgrammingCourses; j++) { |
||
271 | s+=txt(" %c.%s [%c]", (char)('a'+j), advProgCourses[j], (advProgCoursesFinished[j])?'X':' '); |
||
272 | if (!advProgCoursesFinished[j] && !pq.hasCourse('a'+j)) |
||
273 | s+=txt(takeCourseCost, advProgLearningCost[j]); |
||
274 | else if (pq.hasCourse('a'+j)) |
||
275 | s+=takingThisCourse; |
||
276 | else |
||
277 | s+="\n"; |
||
278 | } |
||
279 | continue; |
||
280 | } |
||
281 | |||
282 | s+=txt("%c.%s [%c]", (char)('1'+i), courses[i], (coursesFinished[i])?'X':' '); |
||
283 | if (!coursesFinished[i] && !pq.hasCourse(i)) |
||
284 | s+=txt(takeCourseCost, learningCost[i]); |
||
285 | else if (pq.hasCourse(i)) { |
||
286 | s+=takingThisCourse; |
||
287 | } |
||
288 | else |
||
289 | s+="\n"; |
||
290 | } |
||
291 | |||
292 | drawWindow(s, coursesTitle ,"", number_or_enter); |
||
293 | unsigned char answer = 0; |
||
294 | answer = getKey(); |
||
295 | |||
296 | if (answer == ENTER_KEY) |
||
297 | return; |
||
298 | |||
299 | else if (answer >='1' && answer <=(char)('0'+coursesNumber) && answer != '3') { |
||
300 | answer -- ; |
||
301 | answer -='0'; |
||
302 | |||
303 | if (coursesUnlocked[answer]){ |
||
304 | if (coursesFinished[answer]) { |
||
305 | drawModalWindow(courseAlreadyPassed, errorMsg); |
||
306 | wait(); |
||
307 | showLearnDialog(); |
||
308 | return; |
||
309 | } |
||
310 | else if (playerMoney > learningCost[answer] && !pq.hasCourse(answer)) { |
||
311 | drawModalWindow(txt(successfullyEnrolled, courses[answer]).c_str(), congratsMsg); |
||
312 | wait(); |
||
313 | increaseMoney(-learningCost[answer]); |
||
314 | addTimer(event(learningTime[answer], COURSE, answer)); |
||
315 | } |
||
316 | else if (playerMoney <= learningCost[answer] && !pq.hasCourse(answer)){ |
||
317 | drawModalWindow(notEnoughMoney, errorMsg); |
||
318 | wait(); |
||
319 | showLearnDialog(); |
||
320 | } |
||
321 | else |
||
322 | showLearnDialog(); |
||
323 | return; |
||
324 | } |
||
325 | else |
||
326 | showLearnDialog(); |
||
327 | } |
||
328 | else if (answer == '3' && coursesUnlocked[2]) { |
||
329 | drawModalWindow(ae_advanced_courses,errorMsg); |
||
330 | wait(); |
||
331 | showLearnDialog(); |
||
332 | } |
||
333 | /// only small letters |
||
334 | else if (answer >='a' && answer <= 'e') { |
||
335 | answer -= 'a'; |
||
336 | if (coursesUnlocked[2] && playerMoney > advProgLearningCost[answer] && !advProgCoursesFinished[answer] && !pq.hasCourse('a'+answer)) { |
||
337 | drawModalWindow(txt(successfullyEnrolled,advProgCourses[answer]).c_str(), congratsMsg); |
||
338 | wait(); |
||
339 | |||
340 | increaseMoney(-advProgLearningCost[answer]); |
||
341 | int learnCourseNumber = answer+'a'; |
||
342 | if (advProgLearningTime[answer] != 0 && learnCourseNumber != -1) |
||
343 | addTimer(event(advProgLearningTime[answer], COURSE, learnCourseNumber)); |
||
344 | return; |
||
345 | } |
||
346 | else if (coursesUnlocked[2] && playerMoney <= advProgLearningCost[answer] && !advProgCoursesFinished[answer] && !pq.hasCourse('a'+answer)) { |
||
347 | drawModalWindow(notEnoughMoney, errorMsg); |
||
348 | wait(); |
||
349 | showLearnDialog(); |
||
350 | } |
||
351 | else if (advProgCoursesFinished[answer]) { |
||
352 | drawModalWindow(courseAlreadyPassed, errorMsg); |
||
353 | wait(); |
||
354 | showLearnDialog(); |
||
355 | return; |
||
356 | } |
||
357 | else |
||
358 | showLearnDialog(); |
||
359 | } |
||
360 | else if (answer == '3') { |
||
361 | showLearnDialog(); |
||
362 | } |
||
363 | else if (coursesUnlocked[2]) { |
||
364 | drawModalWindow(ae_advanced_courses,errorMsg); |
||
365 | wait(); |
||
366 | showLearnDialog(); |
||
367 | } |
||
368 | else |
||
369 | showLearnDialog(); |
||
370 | return; |
||
371 | } |
||
372 | |||
373 | void startNewGame() { |
||
374 | // Intro |
||
375 | drawWindow(gameIntroTextPart1, introTitle, "", enter, true); |
||
376 | wait(); |
||
377 | drawWindow(gameIntroTextPart2, introTitle, "", enter, true); |
||
378 | wait(); |
||
379 | drawWindow(gameIntroTextPart3, introTitle, "", enter, true); |
||
380 | wait(); |
||
381 | // Goals |
||
382 | drawWindow(gameIntroPlan, 0, "", enter, true); |
||
383 | wait(); |
||
384 | // Desktop |
||
385 | drawWindow("", introDesktop, "", enter); |
||
386 | wait(); |
||
387 | // Top line |
||
388 | drawWindow(introStatusLine,"", getStatusLine(), enter); |
||
389 | wait(); |
||
390 | // Keys |
||
391 | drawWindow("", "", "", introAllowedKeys); |
||
392 | wait('1'); |
||
393 | // Dialog window |
||
394 | drawModalWindow(introFinished, introLetsBegin); |
||
395 | wait(); |
||
396 | // Start game! |
||
397 | mainGameCycle(); |
||
398 | } |
||
399 | |||
400 | void showFinalStats() { |
||
401 | // Show player stats |
||
402 | int minutesInGame = (time(NULL) - playerStartedPlaying)/60; |
||
403 | playerSpentRealDays += (gameTime - playerPrevUndo); |
||
404 | long unsigned int val[9] = { |
||
405 | static_cast |
||
406 | static_cast |
||
407 | playerMessagesRead, |
||
408 | playerHelped, |
||
409 | playerDidntHelped, |
||
410 | static_cast |
||
411 | static_cast |
||
412 | static_cast |
||
413 | playerTimeHops}; |
||
414 | string s = "\n |
||
415 | s += playerStatsTitle; |
||
416 | for (int i = 0; i < 9; i++) { |
||
417 | s += txt(playerStats[i], static_cast |
||
418 | if (i == 0 || i == 3 || i == 4) |
||
419 | s += getWordEnding(val[i], i); |
||
420 | } |
||
421 | s += playerStatsEnd; |
||
422 | drawWindow(s); |
||
423 | wait(ESCAPE_KEY, ESCAPE_KEY); |
||
424 | } |
||
425 | |||
426 | bool isGameOver() { |
||
427 | if (noPopularity && !finalCardUnlocked[3] && !pq.containsType(SPECIAL_LETTER, LETTER_FINALPATH_NOPOPULARITY)) { |
||
428 | addTimer(event(2.0, SPECIAL_LETTER, LETTER_FINALPATH_NOPOPULARITY)); |
||
429 | return false; |
||
430 | } |
||
431 | |||
432 | if ((playerPath == DEFAULT_PATH || playerPath == STARTUP_PATH) && playerMoney < 0.0 && !finalCardUnlocked[4] && !pq.containsType(SPECIAL_LETTER, LETTER_FINALPATH_NOMONEY)) { |
||
433 | addTimer(event(2.0, SPECIAL_LETTER, LETTER_FINALPATH_NOMONEY)); |
||
434 | return false; |
||
435 | } |
||
436 | // You win! |
||
437 | if (finishedCoursesCount >= 12 && finalCardsUnlocked >= 5 && gameTime <= 22.0 && allAchievesShowed) { |
||
438 | std::string s = youWin; |
||
439 | s += gameOver; |
||
440 | drawWindow(s, congratsMsg, "", pressF); |
||
441 | wait('f','F'); |
||
442 | showFinalStats(); |
||
443 | return true; |
||
444 | } |
||
445 | // Game over |
||
446 | if (playerMoney < 0 && karma() < 0 && noPopularity && floor(unreadMessages) == 0 && gameTime > 22.0 && |
||
447 | achievesShowed[1] && finalCardUnlocked[3] && finalCardUnlocked[4] && |
||
448 | !pq.containsType(SPECIAL_LETTER) && !pq.containsType(MESSAGE)) { |
||
449 | string s = gameOverLogo; |
||
450 | s += gameOverText; |
||
451 | drawWindow(s, gameOverTitle, "", pressF); |
||
452 | wait('f','F'); |
||
453 | showFinalStats(); |
||
454 | return true; |
||
455 | } |
||
456 | return false; |
||
457 | } |
||
458 | |||
459 | int getAvailableCoursesCount() { |
||
460 | int a = 0; |
||
461 | for (unsigned int i = 0; i < coursesNumber; i++) { |
||
462 | if (i!= 2 && coursesUnlocked[i] && !coursesFinished[i]) |
||
463 | a++; |
||
464 | } |
||
465 | // Anvanced programming |
||
466 | if (coursesUnlocked[2]) { |
||
467 | for (int i = 0; i < advancedProgrammingCourses; i++) |
||
468 | if (!advProgCoursesFinished[i]) |
||
469 | a++; |
||
470 | } |
||
471 | return a; |
||
472 | } |
||
473 | |||
474 | std::string getStatusLine() { |
||
475 | string s = txt(statusLine, (int)gameTime, (int)playerMoney, karma(), (int)floor(unreadMessages)); |
||
476 | if (showCoursesTab) |
||
477 | s += txt(statusLineCoursesNotFinished, getAvailableCoursesCount()); |
||
478 | return s; |
||
479 | } |
||
480 | |||
481 | string getBottomLine() { |
||
482 | string s; |
||
483 | if (showCoursesTab) |
||
484 | s += bottomLineCourses; |
||
485 | s += bottomLineMsgAchieves; |
||
486 | if (charityUnlocked) { |
||
487 | s += charityTitle; |
||
488 | s += "[R] "; |
||
489 | } |
||
490 | s += bottomLineSpeedAndExit; |
||
491 | return s; |
||
492 | } |
||
493 | |||
494 | int showUnreadMessages() { |
||
495 | int newTaskLevel = chooseCourse(); |
||
496 | |||
497 | unsigned int task = rand() % taskCount[newTaskLevel]; |
||
498 | unsigned int word = rand() % level1TaskWordNumber; |
||
499 | unsigned int yes = rand() % levelYesAnswerNumber; |
||
500 | unsigned int no = rand() % levelNoAnswerNumber; |
||
501 | |||
502 | string s = printExactTask(newTaskLevel, task, word); |
||
503 | s += txt(yourAnswer,levelYesAnswer[yes],levelNoAnswer[no]); |
||
504 | string buttons = one_or_two; |
||
505 | buttons += escToBreakReading; |
||
506 | drawWindow(s, unread_message, getStatusLine(), buttons); |
||
507 | return newTaskLevel; |
||
508 | } |
||
509 | |||
510 | bool messageGetAnswer(int level) { |
||
511 | long double reward = taskReward[level] + rand() % 20; |
||
512 | char answerKey = getAnswer('1', '2', ESCAPE_KEY); |
||
513 | |||
514 | switch (answerKey) { |
||
515 | case '1': |
||
516 | // Player Stats |
||
517 | playerHelped++; |
||
518 | increaseMoney(reward); |
||
519 | increaseKarma(reward/5.0, false); |
||
520 | if (playerPath == WORK_PATH && controlFreelanceAttempts) { |
||
521 | playerFreelanceAttempts++; |
||
522 | if (playerFreelanceAttempts > 5) { |
||
523 | addTimer(event(1.0, SPECIAL_LETTER, LETTER_ANGRYBOSS_2)); |
||
524 | controlFreelanceAttempts = false; |
||
525 | } |
||
526 | } |
||
527 | // Repairing computer takes 0.5 days |
||
528 | gameTime += 0.5; |
||
529 | break; |
||
530 | case '2': |
||
531 | // Player Stats |
||
532 | playerDidntHelped++; |
||
533 | increaseKarma(-reward/2.0, false); |
||
534 | break; |
||
535 | case ESCAPE_KEY: |
||
536 | return true; |
||
537 | break; |
||
538 | } |
||
539 | return false; |
||
540 | } |
||
541 | |||
542 | double showChangeSpeedDialog(string e = "") { |
||
543 | string s; |
||
544 | if (dt >= 1.0) |
||
545 | s = txt(daysPerSecond, (int)dt); |
||
546 | else { |
||
547 | s = txt(daysPerSecond, 0); |
||
548 | s += txt(".%d", (int)(dt*10)%10); // Actually not the best way of printing double values |
||
549 | } |
||
550 | if (!e.empty()) |
||
551 | s += e; |
||
552 | drawModalWindow(s.c_str(), changeSpeedTitle, changeSpeedButtons); |
||
553 | char ch = getAnswer('+','-','Y','y'); |
||
554 | if (ch == 'y' || ch == 'Y') |
||
555 | return dt; |
||
556 | else if (ch == '+') { |
||
557 | if (dt >= 1.0) |
||
558 | dt += 1.0; |
||
559 | else |
||
560 | dt += 0.10; |
||
561 | if (dt >= 10.0) { |
||
562 | dt = 10.0; |
||
563 | return showChangeSpeedDialog(" max"); |
||
564 | } |
||
565 | return showChangeSpeedDialog(); |
||
566 | } |
||
567 | else if (ch == '-') { |
||
568 | if (dt >= 2.0) |
||
569 | dt -= 1.0; |
||
570 | else |
||
571 | dt -= 0.10; |
||
572 | if (dt <= 0.10) { |
||
573 | dt = 0.10; |
||
574 | return showChangeSpeedDialog(" min"); |
||
575 | } |
||
576 | return showChangeSpeedDialog(); |
||
577 | } |
||
578 | return dt; |
||
579 | } |
||
580 | |||
581 | // returns 1 if program have to be closed |
||
582 | bool keyPressed(char k) { |
||
583 | switch (k) { |
||
584 | // Courses |
||
585 | case 'c': |
||
586 | case 'C': |
||
587 | if (!showCoursesTab) |
||
588 | break; |
||
589 | showLearnDialog(); |
||
590 | break; |
||
591 | // Achieves |
||
592 | case 'a': |
||
593 | case 'A': |
||
594 | showAchievesScreen(); |
||
595 | wait(); |
||
596 | break; |
||
597 | // Messages |
||
598 | case 'm': |
||
599 | case 'M': { |
||
600 | int oldPopularity = karma(); |
||
601 | // Player Stats |
||
602 | bool breakReading = false; |
||
603 | while (floor(unreadMessages) > 0) { |
||
604 | breakReading = messageGetAnswer(showUnreadMessages()); |
||
605 | if (breakReading) { |
||
606 | break; |
||
607 | } |
||
608 | else { |
||
609 | if (floor(unreadMessages) > 0.0) unreadMessages--; |
||
610 | playerMessagesRead++; |
||
611 | } |
||
612 | } |
||
613 | if (!breakReading) { |
||
614 | drawModalWindow(noUnreadMessages); |
||
615 | wait(); |
||
616 | } |
||
617 | if (karma() != oldPopularity) |
||
618 | history.insert(event(gameTime, INCREASEPOPULARITY, karma()-oldPopularity)); |
||
619 | // Hack |
||
620 | #ifdef _KOS32 |
||
621 | initSendingMessage(); |
||
622 | #endif |
||
623 | } |
||
624 | break; |
||
625 | case 'u': |
||
626 | case 'U': |
||
627 | undo(gameTime - 10); |
||
628 | break; |
||
629 | case 'r': |
||
630 | case 'R': { |
||
631 | if (!charityUnlocked) |
||
632 | break; |
||
633 | |||
634 | if (playerMoney <= 0) { |
||
635 | drawModalWindow(notEnoughMoneyForCharity, 0, enter); |
||
636 | wait(); |
||
637 | break; |
||
638 | } |
||
639 | drawModalWindow(charityQuestion, charityTitle, yesNoDialog); |
||
640 | char ch = getAnswer('y', 'n', 'Y', 'N'); |
||
641 | if (ch == 'y' || ch == 'Y') { |
||
642 | // Player Stats |
||
643 | playerMoneySpentForCharity += (playerMoney / 2.0); |
||
644 | |||
645 | increaseMoney(-playerMoney / 2.0); |
||
646 | increaseKarma(abs(karma())); |
||
647 | } |
||
648 | } |
||
649 | break; |
||
650 | case 's': |
||
651 | case 'S': |
||
652 | dt = showChangeSpeedDialog(); |
||
653 | break; |
||
654 | // Escape |
||
655 | case ESCAPE_KEY: { |
||
656 | drawModalWindow(doYouReallyWantToExit,0 , yesNoDialog); |
||
657 | char ans = getAnswer('y','Y','n','N'); |
||
658 | if (ans == 'y' || ans == 'Y') |
||
659 | return true; |
||
660 | } |
||
661 | break; |
||
662 | } |
||
663 | return false; |
||
664 | } |
||
665 | |||
666 | void breakingNews(int newsID) { |
||
667 | drawWindow(news[newsID], breaking_news, getStatusLine(), enter); |
||
668 | wait(); |
||
669 | } |
||
670 | |||
671 | void checkPq() { |
||
672 | vector |
||
673 | // Messages in PQ are in reverse order |
||
674 | for (int i = pq.n()-1; i >= 0; i--) { |
||
675 | event* e = pq.get(i); |
||
676 | if (e->time > dt) { |
||
677 | e->time -= dt; |
||
678 | continue; |
||
679 | } |
||
680 | switch (e->type) { |
||
681 | case COURSE: { |
||
682 | string s; |
||
683 | |||
684 | if (e->idata >= 0 && e->idata < (int)coursesNumber) { |
||
685 | s += txt(courseSuccessfullyFinished,courses[e->idata]); |
||
686 | // Not the best fix for the bug with mobile dev |
||
687 | if (!coursesFinished[e->idata]) |
||
688 | finishedCoursesCount++; |
||
689 | coursesFinished[e->idata] = true; |
||
690 | } |
||
691 | // Advanced programming |
||
692 | else if (e->idata >='a' && e->idata <= 'e') { |
||
693 | e->idata -= 'a'; |
||
694 | s += txt(courseSuccessfullyFinished,advProgCourses[e->idata]); |
||
695 | if (!advProgCoursesFinished[e->idata]) |
||
696 | finishedCoursesCount++; |
||
697 | advProgCoursesFinished[e->idata] = true; |
||
698 | } |
||
699 | increaseKarma(+5); |
||
700 | |||
701 | pq.delMin(); |
||
702 | drawModalWindow(s.c_str(), congratsMsg); |
||
703 | wait(); |
||
704 | } |
||
705 | break; |
||
706 | case SPECIAL_LETTER: |
||
707 | switch (e->idata) { |
||
708 | case LETTER_RETURN_TO_DAY_21: |
||
709 | drawModalWindow(returnToDay21, 0, pressP); |
||
710 | wait('p','P'); |
||
711 | returnTo21HintShowed = true; |
||
712 | break; |
||
713 | case LETTER_SHITCODE_1: |
||
714 | case LETTER_SHITCODE_2: |
||
715 | case LETTER_SHITCODE_3: { |
||
716 | if (playerPath == WORK_PATH) |
||
717 | break; |
||
718 | string s; |
||
719 | int letterIndex = e->idata*2; |
||
720 | s += specialLetters[letterIndex]; |
||
721 | s += shitCodeYourAnswer; |
||
722 | drawWindow(s, new_letter, getStatusLine(), one_or_two); |
||
723 | |||
724 | char ch = getAnswer('1', '2'); |
||
725 | if (ch == '1') { |
||
726 | if (e->idata == LETTER_SHITCODE_1 && advProgCoursesFinished[0] && advProgCoursesFinished[1]) { |
||
727 | // sussessfull |
||
728 | increaseMoney(300.0); |
||
729 | increaseKarma(+5); |
||
730 | drawWindow(txt(specialLetters[24], (int)gameTime, 300), answerLetter, getStatusLine(), enter); |
||
731 | shitLettersFinished[0] = true; |
||
732 | } |
||
733 | else if (e->idata == LETTER_SHITCODE_2 && advProgCoursesFinished[2]) { |
||
734 | // sussessfull |
||
735 | increaseMoney(500.0); |
||
736 | increaseKarma(+5); |
||
737 | drawWindow(txt(specialLetters[24], (int)gameTime, 500), answerLetter, getStatusLine(), enter); |
||
738 | shitLettersFinished[1] = true; |
||
739 | } |
||
740 | else if (e->idata == LETTER_SHITCODE_3 && advProgCoursesFinished[3]) { |
||
741 | // sussessfull |
||
742 | increaseMoney(800.0); |
||
743 | increaseKarma(+5); |
||
744 | drawWindow(txt(specialLetters[24], (int)gameTime, 800), answerLetter, getStatusLine(), enter); |
||
745 | shitLettersFinished[2] = true; |
||
746 | } |
||
747 | else { |
||
748 | drawModalWindow(specialLetters[letterIndex+1], answerLetter); |
||
749 | coursesUnlocked[2] = true; |
||
750 | shitCodeDetected = true; |
||
751 | increaseKarma(-5); |
||
752 | } |
||
753 | |||
754 | if (shitLettersFinished[0] && shitLettersFinished[1] && shitLettersFinished[2]) |
||
755 | achievesPicked[0] = true; |
||
756 | |||
757 | wait(); |
||
758 | } |
||
759 | else if (ch == '2') { |
||
760 | increaseKarma(-2); |
||
761 | } |
||
762 | } |
||
763 | break; |
||
764 | case LETTER_BOTSMANN: |
||
765 | if (playerPath == DEFAULT_PATH) { |
||
766 | string s = specialLetters[6]; |
||
767 | drawWindow(s, new_letter, getStatusLine(), enter); |
||
768 | wait(); |
||
769 | lateEvents.push_back(event(10.0, SPECIAL_LETTER, LETTER_ASTRA)); |
||
770 | } |
||
771 | break; |
||
772 | case LETTER_ASTRA: |
||
773 | if (playerPath == DEFAULT_PATH) { |
||
774 | string s = specialLetters[7]; |
||
775 | s += shitCodeYourAnswer; |
||
776 | |||
777 | drawWindow(s, new_letter, getStatusLine(), one_or_two); |
||
778 | char ch = getAnswer('1', '2'); |
||
779 | if (ch == '1') { |
||
780 | s = specialLetters[8]; |
||
781 | drawWindow(s, new_letter, getStatusLine(), enter); |
||
782 | increaseKarma(-10); |
||
783 | } |
||
784 | else if (ch == '2') { |
||
785 | s = specialLetters[9]; |
||
786 | drawWindow(s, new_letter, getStatusLine(), enter); |
||
787 | // Unlock mobile development |
||
788 | coursesUnlocked[3] = true; |
||
789 | if (!coursesFinished[3] && !pq.hasCourse(3)); |
||
790 | lateEvents.push_back(event(learningTime[3], COURSE, 3)); |
||
791 | changePath(WORK_PATH); |
||
792 | changeSalary(800); |
||
793 | changeSalaryFirstDay((int)gameTime); |
||
794 | increaseKarma(+5); |
||
795 | } |
||
796 | wait(); |
||
797 | } |
||
798 | break; |
||
799 | case LETTER_UNNAMEDSTUDIO_1: { |
||
800 | string s = specialLetters[10]; |
||
801 | if (playerPath == WORK_PATH) { |
||
802 | lateEvents.push_back(event(15.0, SPECIAL_LETTER, LETTER_ANGRYBOSS_1)); |
||
803 | drawWindow(s, new_letter, getStatusLine(), enter); |
||
804 | wait(); |
||
805 | } |
||
806 | else if(playerPath == DEFAULT_PATH) { |
||
807 | s += unnamedStudio1Answer; |
||
808 | drawWindow(s, new_letter, getStatusLine(), one_or_two); |
||
809 | char ch = getAnswer('1', '2'); |
||
810 | if (ch == '1') { |
||
811 | changePath(STARTUP_PATH); |
||
812 | increaseMoney(-500); |
||
813 | lateEvents.push_back(event(12.0, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_2)); |
||
814 | } |
||
815 | } |
||
816 | } |
||
817 | break; |
||
818 | case LETTER_UNNAMEDSTUDIO_2: { |
||
819 | string s = specialLetters[13]; |
||
820 | if (coursesFinished[4]) |
||
821 | s+=specialLetters[27]; |
||
822 | else |
||
823 | s+=specialLetters[26]; |
||
824 | drawWindow(s, new_letter, getStatusLine(), enter); |
||
825 | // Design basics course unlocked |
||
826 | coursesUnlocked[4] = true; |
||
827 | unnamedStudioLettersSent[1] = true; |
||
828 | wait(); |
||
829 | } |
||
830 | break; |
||
831 | case LETTER_UNNAMEDSTUDIO_3: { |
||
832 | int needMoney = (int)(playerMoney * 0.5); |
||
833 | if (needMoney > 50000) |
||
834 | needMoney = 50000; |
||
835 | else if (needMoney < 0) |
||
836 | needMoney *= -1; |
||
837 | string s = txt(specialLetters[14], needMoney); |
||
838 | s += unnamedStudio3Answer; |
||
839 | drawWindow(s, new_letter, getStatusLine(), one_or_two); |
||
840 | |||
841 | char ch = getAnswer('1', '2'); |
||
842 | if (ch == '1') { |
||
843 | increaseMoney(-needMoney); |
||
844 | lateEvents.push_back(event(15.0, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_4)); |
||
845 | } |
||
846 | else if(ch == '2') { |
||
847 | changePath(DEFAULT_PATH); |
||
848 | achievesPicked[5] = true; |
||
849 | increaseKarma(-10); |
||
850 | } |
||
851 | } |
||
852 | break; |
||
853 | case LETTER_UNNAMEDSTUDIO_4: { |
||
854 | string s = specialLetters[15]; |
||
855 | // Creating web-sites |
||
856 | if (coursesFinished[5]) { |
||
857 | s+=specialLetters[29]; |
||
858 | drawWindow(s, new_letter, getStatusLine(), enter); |
||
859 | wait(); |
||
860 | // Waiting for 40 days |
||
861 | lateEvents.push_back(event(40.0, SPECIAL_LETTER, LETTER_WEBMASTER_CHECK_UNNAMEDSTUDIO)); |
||
862 | break; |
||
863 | } |
||
864 | int needMoney = (int)(playerMoney * 0.5); |
||
865 | if (needMoney > 50000) |
||
866 | needMoney = 50000; |
||
867 | else if (needMoney < 0) |
||
868 | needMoney *= -1; |
||
869 | s += txt(specialLetters[28], needMoney); |
||
870 | s += unnamedStudio4Answer; |
||
871 | drawWindow(s, new_letter, getStatusLine(), one_two_or_three); |
||
872 | char ch = getAnswer('1', '2', '3'); |
||
873 | if (ch == '1') { |
||
874 | increaseMoney(-needMoney); |
||
875 | increaseKarma(+5); |
||
876 | // Pay for the webmaster |
||
877 | lateEvents.push_back(event(40.0, NEWS, 3)); |
||
878 | } |
||
879 | else if (ch == '2') { |
||
880 | coursesUnlocked[5] = true; |
||
881 | lateEvents.push_back(event(40.0, SPECIAL_LETTER, LETTER_WEBMASTER_CHECK_UNNAMEDSTUDIO)); |
||
882 | } |
||
883 | else if (ch == '3') { |
||
884 | changePath(DEFAULT_PATH); |
||
885 | achievesPicked[5] = true; |
||
886 | increaseKarma(-5); |
||
887 | } |
||
888 | } |
||
889 | break; |
||
890 | case LETTER_WEBMASTER_CHECK_UNNAMEDSTUDIO: |
||
891 | if (coursesFinished[5]) { |
||
892 | lateEvents.push_back(event(1.0, NEWS, 3)); |
||
893 | } |
||
894 | else { |
||
895 | // SHow letter about fail |
||
896 | drawWindow(specialLetters[16], new_letter, getStatusLine(), enter); |
||
897 | wait(); |
||
898 | drawModalWindow(startupFailedTip); |
||
899 | wait(); |
||
900 | increaseMoney(1000); |
||
901 | achievesPicked[5] = true; |
||
902 | increaseKarma(-15); |
||
903 | } |
||
904 | break; |
||
905 | case LETTER_UNNAMEDSTUDIO_5: { |
||
906 | drawWindow(specialLetters[17], new_letter, getStatusLine(), enter); |
||
907 | increaseMoney(200000); |
||
908 | increaseKarma(+20); |
||
909 | wait(); |
||
910 | achievesPicked[2] = true; |
||
911 | lateEvents.push_back(event(5.0, SPECIAL_LETTER, LETTER_FINALPATH_STARTUP)); |
||
912 | } |
||
913 | break; |
||
914 | case LETTER_ANGRYBOSS_1: { |
||
915 | string s = specialLetters[11]; |
||
916 | s += angryBossAnswer; |
||
917 | drawWindow(s, new_letter, getStatusLine(), one_or_two); |
||
918 | char ch = getAnswer('1', '2'); |
||
919 | if (ch == '1') { |
||
920 | changeSalary(1200); |
||
921 | coursesUnlocked[5] = true; |
||
922 | coursesUnlocked[6] = true; |
||
923 | coursesUnlocked[7] = true; |
||
924 | playerFreelanceAttempts = 0; |
||
925 | controlFreelanceAttempts = true; |
||
926 | lateEvents.push_back(event(20.0, SPECIAL_LETTER, NO_POPULARITY_HINT)); |
||
927 | } |
||
928 | else if(ch == '2') { |
||
929 | changePath(STARTUP_PATH); |
||
930 | changeSalary(0); |
||
931 | lateEvents.push_back(event(9.0, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_2)); |
||
932 | achievesPicked[4] = true; |
||
933 | increaseKarma(-10); |
||
934 | } |
||
935 | } |
||
936 | break; |
||
937 | case NO_POPULARITY_HINT: |
||
938 | if (!noPopularity && controlFreelanceAttempts && playerFreelanceAttempts < 5) { |
||
939 | drawWindow(specialLetters[25], new_letter, getStatusLine(), enter); |
||
940 | wait(); |
||
941 | } |
||
942 | break; |
||
943 | case LETTER_ANGRYBOSS_2: |
||
944 | drawWindow(specialLetters[12], new_letter, getStatusLine(), enter); |
||
945 | changePath(DEFAULT_PATH); |
||
946 | changeSalary(0); |
||
947 | wait(); |
||
948 | increaseKarma(-20); |
||
949 | break; |
||
950 | case LETTER_BORING_WORK: |
||
951 | if (playerPath == WORK_PATH) { |
||
952 | drawWindow(specialLetters[18], new_letter, getStatusLine(), enter); |
||
953 | wait(); |
||
954 | lateEvents.push_back(event(15.0, SPECIAL_LETTER, LETTER_PERSISTENT_AND_PATIENT)); |
||
955 | } |
||
956 | break; |
||
957 | case LETTER_BORING_DEFAULT_PATH: |
||
958 | if (playerPath == DEFAULT_PATH && !pq.containsType(SPECIAL_LETTER, LETTER_FINALPATH_DEF |
||
959 | && !pq.containsType(SPECIAL_LETTER, LETTER_BORING_DEFAULT_PATH))) { |
||
960 | drawWindow(specialLetters[19], new_letter, getStatusLine(), enter); |
||
961 | wait(); |
||
962 | lateEvents.push_back(event(5.0, SPECIAL_LETTER, LETTER_FINALPATH_DEF)); |
||
963 | } |
||
964 | break; |
||
965 | case LETTER_FINALPATH_DEF: |
||
966 | if (playerPath == DEFAULT_PATH) { |
||
967 | drawWindow(defaultFinalCard, finalCard, getStatusLine(), pressF); |
||
968 | unlockFinalCards(0); |
||
969 | wait('f', 'F'); |
||
970 | } |
||
971 | break; |
||
972 | case LETTER_FINALPATH_WORK: |
||
973 | if (playerPath == WORK_PATH) { |
||
974 | drawWindow(workFinalCard, finalCard, getStatusLine(), pressF); |
||
975 | unlockFinalCards(1); |
||
976 | wait('f', 'F'); |
||
977 | } |
||
978 | break; |
||
979 | case LETTER_FINALPATH_STARTUP: |
||
980 | if (playerPath == STARTUP_PATH) { |
||
981 | drawWindow(startupFinalCard, finalCard, getStatusLine(), pressF); |
||
982 | unlockFinalCards(2); |
||
983 | wait('f', 'F'); |
||
984 | } |
||
985 | break; |
||
986 | case LETTER_FINALPATH_NOPOPULARITY: |
||
987 | drawWindow(zeroKarmaFinalCard, finalCard, getStatusLine(), pressF); |
||
988 | unlockFinalCards(3); |
||
989 | wait('f', 'F'); |
||
990 | break; |
||
991 | case LETTER_FINALPATH_NOMONEY: |
||
992 | drawWindow(noMoneyFinalCard, finalCard, getStatusLine(), pressF); |
||
993 | unlockFinalCards(4); |
||
994 | wait('f', 'F'); |
||
995 | break; |
||
996 | case LETTER_PERSISTENT_AND_PATIENT: |
||
997 | achievesPicked[7] = true; |
||
998 | lateEvents.push_back(event(2.0, SPECIAL_LETTER, LETTER_FINALPATH_WORK)); |
||
999 | break; |
||
1000 | case LETTER_TEST_OF_KNOWLEDGE: |
||
1001 | drawWindow(specialLetters[20], new_letter, getStatusLine(), enter); |
||
1002 | wait(); |
||
1003 | nextKnowledgeLetterIndex = 0; |
||
1004 | lateEvents.push_back(event(5.0, SPECIAL_LETTER, LETTER_KNOWLEDGE_QUESTION)); |
||
1005 | break; |
||
1006 | case LETTER_KNOWLEDGE_QUESTION: { |
||
1007 | if (playerPath != WORK_PATH) { |
||
1008 | break; |
||
1009 | } |
||
1010 | |||
1011 | if (klowledgeCorrectAnswers == 5) { |
||
1012 | /// премия |
||
1013 | drawWindow(specialLetters[21], new_letter, getStatusLine(), enter); |
||
1014 | increaseMoney(400); |
||
1015 | wait(); |
||
1016 | klowledgeCorrectAnswers = 0; |
||
1017 | } |
||
1018 | if (klowledgeUncorrectAnswers >= 5) { |
||
1019 | /// Didn't pass the knowledge check |
||
1020 | drawWindow(specialLetters[22], new_letter, getStatusLine(), enter); |
||
1021 | wait(); |
||
1022 | changePath(DEFAULT_PATH); |
||
1023 | changeSalary(0); |
||
1024 | break; |
||
1025 | } |
||
1026 | if (nextKnowledgeLetterIndex > 27) { |
||
1027 | /// Knowledge check finished |
||
1028 | /// TODO: add a timer for this |
||
1029 | drawWindow(specialLetters[23], new_letter, getStatusLine(), enter); |
||
1030 | achievesPicked[6] = true; |
||
1031 | wait(); |
||
1032 | lateEvents.push_back(event(30.0, SPECIAL_LETTER, LETTER_BORING_WORK)); |
||
1033 | } |
||
1034 | else { |
||
1035 | string s = knowledgeCheck[nextKnowledgeLetterIndex]; |
||
1036 | short yes = rand() % 2 + 1; // 1 or 2 |
||
1037 | short no = (yes == 1)?2:1; |
||
1038 | s+=txt(yourAnswer, knowledgeCheck[nextKnowledgeLetterIndex+yes], knowledgeCheck[nextKnowledgeLetterIndex+no]); |
||
1039 | drawWindow(s, new_letter, getStatusLine(), one_or_two); |
||
1040 | char ch = getAnswer('1', '2');//getch(); |
||
1041 | if ((ch - '0') == yes) { |
||
1042 | drawModalWindow(rightAnswer, congratsMsg); |
||
1043 | klowledgeCorrectAnswers++; |
||
1044 | } |
||
1045 | else { |
||
1046 | drawModalWindow(wrongAnswer, failMsg); |
||
1047 | klowledgeUncorrectAnswers++; |
||
1048 | } |
||
1049 | wait(); |
||
1050 | nextKnowledgeLetterIndex+=3; |
||
1051 | lateEvents.push_back(event(7.0, SPECIAL_LETTER, LETTER_KNOWLEDGE_QUESTION)); |
||
1052 | } |
||
1053 | } |
||
1054 | break; |
||
1055 | default: |
||
1056 | break; |
||
1057 | } |
||
1058 | pq.delMin(); |
||
1059 | break; |
||
1060 | case MESSAGE: |
||
1061 | unreadMessages+=(karma() > 0)?dt * karma()/50:0; |
||
1062 | pq.delMin(); |
||
1063 | lateEvents.push_back(event(2*dt, MESSAGE)); |
||
1064 | break; |
||
1065 | case NEWS: { |
||
1066 | switch (e->idata) { |
||
1067 | // Programming in the world |
||
1068 | case 0: |
||
1069 | showCoursesTab = true; |
||
1070 | coursesUnlocked[1] = true; |
||
1071 | break; |
||
1072 | // Java programmers |
||
1073 | case 1: |
||
1074 | coursesUnlocked[2] = true; |
||
1075 | break; |
||
1076 | // Mobile development |
||
1077 | case 2: |
||
1078 | coursesUnlocked[3] = true; |
||
1079 | break; |
||
1080 | case 3: |
||
1081 | // Your game is very popular |
||
1082 | lateEvents.push_back(event(3.0, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_5)); |
||
1083 | break; |
||
1084 | default: |
||
1085 | break; |
||
1086 | } |
||
1087 | breakingNews(e->idata); |
||
1088 | pq.delMin(); |
||
1089 | } |
||
1090 | break; |
||
1091 | case NOPOPULARITY: |
||
1092 | case INCREASEPOPULARITY: |
||
1093 | // nop |
||
1094 | pq.delMin(); |
||
1095 | break; |
||
1096 | default: |
||
1097 | break; |
||
1098 | } |
||
1099 | } |
||
1100 | // Add new messages only after checking all existing messages |
||
1101 | for (unsigned short i = 0; i< lateEvents.size(); i++) { |
||
1102 | event e = lateEvents[i]; |
||
1103 | if (e.type == MESSAGE) { |
||
1104 | initSendingMessage(); |
||
1105 | continue; |
||
1106 | } |
||
1107 | else if (e.type == SPECIAL_LETTER && e.idata == LETTER_ASTRA) |
||
1108 | astraLetterSent = true; |
||
1109 | addTimer(e); |
||
1110 | } |
||
1111 | } |
||
1112 | |||
1113 | void makeStory() { |
||
1114 | switch (playerPath) { |
||
1115 | case DEFAULT_PATH: |
||
1116 | if (playerMoney > 200.0 && !showCoursesTab && !pq.containsType(NEWS, 0)) { // Basics of programming |
||
1117 | addTimer(event(10.0, NEWS, 0)); |
||
1118 | newsShowed[0] = true; |
||
1119 | } |
||
1120 | else if (playerMoney > 300.0 && !shitCodeDetected && !shitLettersSent[0] && coursesFinished[1]) { |
||
1121 | addTimer(event(9.0, SPECIAL_LETTER, LETTER_SHITCODE_1)); |
||
1122 | shitLettersSent[0] = true; |
||
1123 | } |
||
1124 | else if (playerMoney > 400.0 && !newsShowed[2] && coursesFinished[1] && !pq.containsType(NEWS, 2)) { // Frappy Perd |
||
1125 | addTimer(event(9.0, NEWS, 2)); |
||
1126 | newsShowed[2] = true; |
||
1127 | } |
||
1128 | else if (playerMoney > 500 && !sentBotsmannLetter && coursesFinished[1]) { // Letter from Botsmann |
||
1129 | addTimer(event(17.0, SPECIAL_LETTER, LETTER_BOTSMANN)); |
||
1130 | sentBotsmannLetter = true; |
||
1131 | } |
||
1132 | else if (playerMoney > 600.0 && !shitCodeDetected && !shitLettersSent[1] && coursesFinished[1] && !pq.containsType(SPECIAL_LETTER, LETTER_SHITCODE_1)) { |
||
1133 | addTimer(event(13.0, SPECIAL_LETTER, LETTER_SHITCODE_2)); |
||
1134 | shitLettersSent[1] = true; |
||
1135 | } |
||
1136 | else if (playerMoney > 800.0 && sentBotsmannLetter && !unnamedStudioLettersSent[0] && coursesFinished[3] && astraLetterSent && !pq.containsType(SPECIAL_LETTER, LETTER_ASTRA)) { // Startup |
||
1137 | addTimer(event(15.0, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_1)); |
||
1138 | unnamedStudioLettersSent[0] = true; |
||
1139 | } |
||
1140 | else if (playerMoney > 1000.0 && !shitCodeDetected && !shitLettersSent[2] && coursesFinished[1] && !pq.containsType(SPECIAL_LETTER, LETTER_SHITCODE_2)) { // Send 3 letters with checking for a shit code |
||
1141 | addTimer(event(14.0, SPECIAL_LETTER, LETTER_SHITCODE_3)); |
||
1142 | shitLettersSent[2] = true; |
||
1143 | } |
||
1144 | else if (getAvailableCoursesCount() == 0 && playerMoney > 2000 && sentBotsmannLetter |
||
1145 | && unnamedStudioLettersSent[0] && !finalCardUnlocked[0] && !pq.containsType(SPECIAL_LETTER, LETTER_BORING_DEFAULT_PATH)) { |
||
1146 | addTimer(event(10.0, SPECIAL_LETTER, LETTER_BORING_DEFAULT_PATH)); |
||
1147 | } |
||
1148 | break; |
||
1149 | case WORK_PATH: |
||
1150 | if (playerSalary == 1200 && noPopularity && !knowledgeLetterSent && unnamedStudioLettersSent[0] && controlFreelanceAttempts && playerFreelanceAttempts <= 5) { |
||
1151 | addTimer(event(5.0, SPECIAL_LETTER, LETTER_TEST_OF_KNOWLEDGE)); |
||
1152 | knowledgeLetterSent = true; |
||
1153 | } |
||
1154 | else if (playerMoney > 500.0 && !newsShowed[2] && !pq.containsType(NEWS, 2)) { // Frappy Perd |
||
1155 | addTimer(event(7.0, NEWS, 2)); |
||
1156 | newsShowed[2] = true; |
||
1157 | } |
||
1158 | else if (playerMoney > 600.0 && !unnamedStudioLettersSent[0] && coursesFinished[3]) { // Startup |
||
1159 | addTimer(event(14.0, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_1)); |
||
1160 | unnamedStudioLettersSent[0] = true; |
||
1161 | } |
||
1162 | break; |
||
1163 | case STARTUP_PATH: |
||
1164 | if (unnamedStudioLettersSent[1] && !unnamedStudioLettersSent[2] && coursesFinished[4]) { |
||
1165 | addTimer(event(15.0, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_3)); |
||
1166 | unnamedStudioLettersSent[2] = true; |
||
1167 | } |
||
1168 | else if (playerMoney > 600.0 && !shitCodeDetected && !shitLettersSent[1] && coursesFinished[1] && !pq.containsType(SPECIAL_LETTER, LETTER_SHITCODE_1)) { |
||
1169 | addTimer(event(14.0, SPECIAL_LETTER, LETTER_SHITCODE_2)); |
||
1170 | shitLettersSent[1] = true; |
||
1171 | } |
||
1172 | else if (playerMoney > 1000.0 && !shitCodeDetected && !shitLettersSent[2] && coursesFinished[1] && !pq.containsType(SPECIAL_LETTER, LETTER_SHITCODE_2)) { // Send 3 letters with checking for a shit code |
||
1173 | addTimer(event(19.0, SPECIAL_LETTER, LETTER_SHITCODE_3)); |
||
1174 | shitLettersSent[2] = true; |
||
1175 | } |
||
1176 | break; |
||
1177 | } |
||
1178 | // News about JAVA programmers |
||
1179 | if (playerMoney > 1500.0 && !newsShowed[1] && shitLettersSent[0] && shitLettersSent[1] |
||
1180 | && shitLettersSent[2] && !shitCodeDetected && coursesFinished[1] && !coursesUnlocked[2]) { // JAVA programmers |
||
1181 | addTimer(event(5.0, NEWS, 1)); |
||
1182 | newsShowed[1] = true; |
||
1183 | } |
||
1184 | if (!returnTo21HintShowed && finishedCoursesCount == 12 && finalCardsUnlocked == 5 && gameTime > 21.0 && allAchievesShowed && !pq.containsType(SPECIAL_LETTER, LETTER_RETURN_TO_DAY_21)) { |
||
1185 | addTimer(event(2.0, SPECIAL_LETTER, LETTER_RETURN_TO_DAY_21)); |
||
1186 | } |
||
1187 | } |
||
1188 | |||
1189 | // Desktop is your main screen |
||
1190 | string getDesktop(int &lines) { |
||
1191 | string s = "\n\n"; |
||
1192 | // Information about courses |
||
1193 | if (!pq.hasCourses()) { |
||
1194 | s += noCurrentCurses; |
||
1195 | } |
||
1196 | else { |
||
1197 | // Check courses in pq |
||
1198 | s += " "; |
||
1199 | s += coursesTitle; |
||
1200 | s += ":\n"; |
||
1201 | for(int i = 0; i< pq.n(); i++) { |
||
1202 | event* e = pq.get(i); |
||
1203 | if (e->type == COURSE) { |
||
1204 | s += " "; |
||
1205 | if (e->idata >= 0 && e->idata <= 7) { |
||
1206 | s += courses[e->idata]; |
||
1207 | s += " "; |
||
1208 | int percent = (int)(100 * (learningTime[e->idata] - e->time) / learningTime[e->idata]); |
||
1209 | for (int i = 0; i < 20; i++) { |
||
1210 | if (i > 2*percent/10) |
||
1211 | s += " "; |
||
1212 | else |
||
1213 | s += pseudoEqual; |
||
1214 | } |
||
1215 | s += txt(" %d%\n", percent); |
||
1216 | } |
||
1217 | else if (e->idata >= 'a' && e->idata <= 'e') { |
||
1218 | s += advProgCourses[e->idata - 'a']; |
||
1219 | s += " "; |
||
1220 | int percent = (int)(100 * (advProgLearningTime[e->idata-'a'] - e->time) / advProgLearningTime[e->idata - 'a']); |
||
1221 | for (int i = 0; i < 20; i++) { |
||
1222 | if (i > 2*percent/10) |
||
1223 | s+=" "; |
||
1224 | else |
||
1225 | s+=pseudoEqual; |
||
1226 | } |
||
1227 | s += txt(" %d%\n", percent); |
||
1228 | } |
||
1229 | } |
||
1230 | } |
||
1231 | } |
||
1232 | |||
1233 | for(unsigned int i = 0; i < s.length(); i++) |
||
1234 | if (s[i] == '\n') |
||
1235 | lines++; |
||
1236 | |||
1237 | return s; |
||
1238 | } |
||
1239 | |||
1240 | void mainGameCycle() { |
||
1241 | float hintBegins = 0.0; //days |
||
1242 | unsigned short hintIndex = 0; |
||
1243 | |||
1244 | playerMoney = 100; |
||
1245 | dt = 0.5; |
||
1246 | int update = 0; |
||
1247 | |||
1248 | // Add initial letter |
||
1249 | initSendingMessage(); |
||
1250 | |||
1251 | string status = playerStatus; |
||
1252 | status += helpDesker; |
||
1253 | int currentPath = playerPath; |
||
1254 | |||
1255 | playerStartedPlaying = time(NULL); |
||
1256 | string buffer, oldStatusLine; |
||
1257 | while (1) { |
||
1258 | // We update screen 10 times a second |
||
1259 | if (update % 10 == 0) |
||
1260 | increaseMoney(-dt * 1.0); // Money needs per day |
||
1261 | |||
1262 | int lines = 0; |
||
1263 | |||
1264 | string s = getDesktop(lines); |
||
1265 | for (int i = 0; i < 11-lines; i++) |
||
1266 | s += "\n"; |
||
1267 | s += " "; |
||
1268 | s += hintOfTheMonth; |
||
1269 | if (gameTime > hintBegins + 30) { |
||
1270 | hintBegins = gameTime; |
||
1271 | hintIndex++; |
||
1272 | if (hintIndex >= hintsCount) |
||
1273 | hintIndex = 0; |
||
1274 | } |
||
1275 | // This could happen when jumping in the past |
||
1276 | else if (hintBegins > gameTime) |
||
1277 | hintBegins = gameTime; |
||
1278 | |||
1279 | s += " "; |
||
1280 | s += hints[hintIndex]; |
||
1281 | |||
1282 | if (playerPath != currentPath) { |
||
1283 | currentPath = playerPath; |
||
1284 | status=playerStatus; |
||
1285 | if (playerPath == DEFAULT_PATH) status += helpDesker; |
||
1286 | else if (playerPath == WORK_PATH) status += worker; |
||
1287 | else if (playerPath == STARTUP_PATH) status += startupper; |
||
1288 | } |
||
1289 | // redraw screen only if necessary |
||
1290 | string newStatusLine = getStatusLine(); |
||
1291 | if (!(s == buffer) || !(oldStatusLine == newStatusLine)) |
||
1292 | drawWindow(s, status.c_str(), newStatusLine, getBottomLine()); |
||
1293 | buffer = s; |
||
1294 | oldStatusLine = newStatusLine; |
||
1295 | if (update % 10 == 0) { |
||
1296 | checkAchieves(); |
||
1297 | if (isGameOver()) |
||
1298 | break; |
||
1299 | |||
1300 | if (playerSalary != 0 && gameTime-playerSalaryFirstDay >= 30) { |
||
1301 | increaseMoney(playerSalary); |
||
1302 | changeSalaryFirstDay(playerSalaryFirstDay+30); |
||
1303 | } |
||
1304 | makeStory(); |
||
1305 | checkPq(); |
||
1306 | } |
||
1307 | |||
1308 | // Some key was pressed |
||
1309 | if (kbhit()) { |
||
1310 | char k = getch(); |
||
1311 | #ifdef _KOS32 |
||
1312 | // We have to make a second call for special keys in KolibriOS |
||
1313 | if (k == 0) |
||
1314 | k = getch(); |
||
1315 | #endif |
||
1316 | if (keyPressed(k)) |
||
1317 | return; |
||
1318 | // Force redraw desktop |
||
1319 | buffer = ""; |
||
1320 | oldStatusLine = ""; |
||
1321 | } |
||
1322 | |||
1323 | if (update % 10 == 0) |
||
1324 | gameTime += dt; |
||
1325 | |||
1326 | int delayTime = 10; |
||
1327 | #ifdef _KOS32 |
||
1328 | __menuet__delay100(delayTime); |
||
1329 | #else |
||
1330 | usleep(delayTime*10000); |
||
1331 | #endif |
||
1332 | update++; |
||
1333 | } |
||
1334 | } |
||
1335 | |||
1336 | // Jump in the past to a certain time |
||
1337 | void undo(long double toTime) { |
||
1338 | if (toTime < 0 ) |
||
1339 | return; |
||
1340 | |||
1341 | if (playerMoney < 100) { |
||
1342 | drawModalWindow(need100ForUndo, errorMsg); |
||
1343 | wait(); |
||
1344 | return; |
||
1345 | } |
||
1346 | // Jump cost: $100 |
||
1347 | increaseMoney(-100); |
||
1348 | drawModalWindow(prepareForTimeJump); |
||
1349 | wait(); |
||
1350 | |||
1351 | while(!pq.empty()) |
||
1352 | pq.delMin(); |
||
1353 | |||
1354 | // Player Stats |
||
1355 | playerTimeHops++; |
||
1356 | playerSpentRealDays += (gameTime - playerPrevUndo); |
||
1357 | playerPrevUndo = toTime; |
||
1358 | |||
1359 | vector |
||
1360 | history.prepareForUndo(); |
||
1361 | while (!history.empty() && history.getMax().time > toTime) { |
||
1362 | event e = history.getMax(); |
||
1363 | switch (e.type) { |
||
1364 | case INCREASEPOPULARITY: |
||
1365 | increaseKarma(-e.idata, false); |
||
1366 | break; |
||
1367 | case NOPOPULARITY: |
||
1368 | noPopularity = false; |
||
1369 | break; |
||
1370 | case CHANGEPATH: |
||
1371 | playerPath = e.idata; // Previous path |
||
1372 | break; |
||
1373 | case CHANGESALARY: |
||
1374 | playerSalary = e.idata; |
||
1375 | break; |
||
1376 | case CHANGESALARYFIRSTDAY: |
||
1377 | playerSalaryFirstDay = e.idata; |
||
1378 | break; |
||
1379 | // Letters' time is time of sending a letter + time to end timer = time to get letter in the future |
||
1380 | case SPECIAL_LETTER: |
||
1381 | switch(e.idata) { |
||
1382 | case LETTER_BOTSMANN: |
||
1383 | sentBotsmannLetter = false; |
||
1384 | astraLetterSent = false; |
||
1385 | break; |
||
1386 | case LETTER_ASTRA: |
||
1387 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_BOTSMANN, toTime)) |
||
1388 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_ASTRA)); |
||
1389 | break; |
||
1390 | case LETTER_UNNAMEDSTUDIO_2: |
||
1391 | // Unnamed letter 1 -> AngryBoss -> Unnamed letter 2 |
||
1392 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_ANGRYBOSS_1, e.time)) { |
||
1393 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_ANGRYBOSS_1, toTime)) |
||
1394 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_2)); |
||
1395 | } |
||
1396 | // Unnamed letter 1 -> Unnamed letter 2 |
||
1397 | else { |
||
1398 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_1, toTime)) |
||
1399 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_2)); |
||
1400 | } |
||
1401 | break; |
||
1402 | case NO_POPULARITY_HINT: |
||
1403 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_ANGRYBOSS_1, toTime)) |
||
1404 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, NO_POPULARITY_HINT)); |
||
1405 | break; |
||
1406 | case LETTER_ANGRYBOSS_1: |
||
1407 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_1, toTime)) { |
||
1408 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_ANGRYBOSS_1)); |
||
1409 | controlFreelanceAttempts = false; |
||
1410 | } |
||
1411 | break; |
||
1412 | case LETTER_UNNAMEDSTUDIO_1: |
||
1413 | unnamedStudioLettersSent[0] = false; |
||
1414 | break; |
||
1415 | case LETTER_WEBMASTER_CHECK_UNNAMEDSTUDIO: |
||
1416 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_4, toTime)) |
||
1417 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_WEBMASTER_CHECK_UNNAMEDSTUDIO)); |
||
1418 | break; |
||
1419 | case LETTER_UNNAMEDSTUDIO_4: |
||
1420 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_3, toTime)) |
||
1421 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_4)); |
||
1422 | break; |
||
1423 | case LETTER_UNNAMEDSTUDIO_3: |
||
1424 | unnamedStudioLettersSent[2] = false; |
||
1425 | break; |
||
1426 | case LETTER_UNNAMEDSTUDIO_5: |
||
1427 | if (history.containsTypeBefore(NEWS, 3, toTime) && !pq.containsType(SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_5)) |
||
1428 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_5)); |
||
1429 | break; |
||
1430 | case LETTER_FINALPATH_DEF: |
||
1431 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_BORING_DEFAULT_PATH, toTime)) |
||
1432 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_FINALPATH_DEF)); |
||
1433 | break; |
||
1434 | case LETTER_FINALPATH_STARTUP: |
||
1435 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_5, toTime) && !pq.containsType(SPECIAL_LETTER, LETTER_FINALPATH_STARTUP)) |
||
1436 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_FINALPATH_STARTUP)); |
||
1437 | break; |
||
1438 | case LETTER_FINALPATH_WORK: |
||
1439 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_PERSISTENT_AND_PATIENT, toTime)) |
||
1440 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_FINALPATH_WORK)); |
||
1441 | break; |
||
1442 | case LETTER_ANGRYBOSS_2: |
||
1443 | if (e.time - toTime <= 1) |
||
1444 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_ANGRYBOSS_2)); |
||
1445 | break; |
||
1446 | case LETTER_PERSISTENT_AND_PATIENT: |
||
1447 | if (history.containsTypeBefore(SPECIAL_LETTER,LETTER_BORING_WORK, toTime)) |
||
1448 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_PERSISTENT_AND_PATIENT)); |
||
1449 | break; |
||
1450 | case LETTER_BORING_WORK: |
||
1451 | if (e.time - toTime <= 40) |
||
1452 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_BORING_WORK)); |
||
1453 | break; |
||
1454 | case LETTER_TEST_OF_KNOWLEDGE: |
||
1455 | knowledgeLetterSent = false; |
||
1456 | playerFreelanceAttempts = 0; |
||
1457 | klowledgeCorrectAnswers = 0; |
||
1458 | klowledgeUncorrectAnswers = 0; |
||
1459 | break; |
||
1460 | case LETTER_SHITCODE_1: |
||
1461 | shitCodeDetected = false; |
||
1462 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_SHITCODE_1)); |
||
1463 | shitLettersSent[1] = false; |
||
1464 | shitLettersSent[2] = false; |
||
1465 | break; |
||
1466 | case LETTER_SHITCODE_2: |
||
1467 | shitCodeDetected = false; |
||
1468 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_SHITCODE_2)); |
||
1469 | shitLettersSent[2] = false; |
||
1470 | break; |
||
1471 | case LETTER_SHITCODE_3: |
||
1472 | shitCodeDetected = false; |
||
1473 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_SHITCODE_3)); |
||
1474 | break; |
||
1475 | case LETTER_BORING_DEFAULT_PATH: |
||
1476 | lateEvents.push_back(event(e.time - toTime, SPECIAL_LETTER, LETTER_BORING_DEFAULT_PATH)); |
||
1477 | break; |
||
1478 | } |
||
1479 | break; |
||
1480 | case NEWS: |
||
1481 | // News about JAVA programmers |
||
1482 | newsShowed[e.idata] = false; |
||
1483 | if (e.idata == 3) { |
||
1484 | // Unnamed letter 3 -> Unnamed letter 4 -> Need webmaster -> news about Java |
||
1485 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_WEBMASTER_CHECK_UNNAMEDSTUDIO, e.time)) { |
||
1486 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_WEBMASTER_CHECK_UNNAMEDSTUDIO, toTime)) |
||
1487 | lateEvents.push_back(event(e.time - toTime, NEWS, 3)); |
||
1488 | } |
||
1489 | // Unnamed letter 3 -> Unnamed letter 4 -> news about Java |
||
1490 | else { |
||
1491 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_UNNAMEDSTUDIO_4, toTime)) |
||
1492 | lateEvents.push_back(event(e.time - toTime, NEWS, 3)); |
||
1493 | } |
||
1494 | } |
||
1495 | break; |
||
1496 | case COURSE: { |
||
1497 | // e.time - course finished |
||
1498 | // e.idata - course number |
||
1499 | long double courseStarted = 0; |
||
1500 | bool courseFinished = false; |
||
1501 | if (e.idata >='a' && e.idata <= 'e') { |
||
1502 | courseStarted = e.time - advProgLearningTime[e.idata-'a']; |
||
1503 | courseFinished = advProgCoursesFinished[e.idata-'a']; |
||
1504 | } |
||
1505 | else if(e.idata >= 0 && e.idata < (int)coursesNumber) { |
||
1506 | courseStarted = e.time - learningTime[e.idata]; |
||
1507 | courseFinished = coursesFinished[e.idata]; |
||
1508 | } |
||
1509 | |||
1510 | if (!courseFinished && toTime >= courseStarted) |
||
1511 | // Player is currently taking a course |
||
1512 | lateEvents.push_back(event(e.time - toTime, COURSE, e.idata)); |
||
1513 | } |
||
1514 | break; |
||
1515 | case MESSAGE: |
||
1516 | break; |
||
1517 | } |
||
1518 | history.delMax(); |
||
1519 | } |
||
1520 | unreadMessages = 0; |
||
1521 | gameTime = toTime; |
||
1522 | timeHops++; |
||
1523 | |||
1524 | for (unsigned short i = 0; i< lateEvents.size(); i++) |
||
1525 | addTimer(lateEvents[i]); |
||
1526 | |||
1527 | |||
1528 | // Messages would not arive without this: |
||
1529 | if (!pq.containsType(MESSAGE)) |
||
1530 | initSendingMessage(); |
||
1531 | |||
1532 | // Undo shouldn't stop during the knowledge check |
||
1533 | if (history.containsTypeBefore(SPECIAL_LETTER, LETTER_TEST_OF_KNOWLEDGE, toTime) |
||
1534 | && !history.containsTypeBefore(SPECIAL_LETTER, LETTER_BORING_WORK, toTime)) { |
||
1535 | double newTime = toTime-10; |
||
1536 | for (int i = 0; i < history.n(); i++) { |
||
1537 | event* e = history.get(i); |
||
1538 | if (e->type == SPECIAL_LETTER && e->idata == LETTER_TEST_OF_KNOWLEDGE) { |
||
1539 | newTime = e->time - 10; |
||
1540 | break; |
||
1541 | } |
||
1542 | } |
||
1543 | drawModalWindow(cantStopDuringKnowledgeCheck, errorMsg); |
||
1544 | wait(); |
||
1545 | undo(newTime); |
||
1546 | } |
||
1547 | } |
||
1548 | |||
1549 | int chooseCourse() { |
||
1550 | double p[coursesNumber]; |
||
1551 | long double sum = 0.0; |
||
1552 | for (unsigned int i = 0; i < coursesNumber; i++) { |
||
1553 | if (coursesFinished[i]) |
||
1554 | p[i] = probability[i]; |
||
1555 | else |
||
1556 | p[i] = 0.0; |
||
1557 | sum += p[i]; |
||
1558 | } |
||
1559 | if (sum <= 0.001) |
||
1560 | return 0; |
||
1561 | int N = (int) (sum * 100); |
||
1562 | int r = rand() % N; |
||
1563 | |||
1564 | int n1 = (p[0] / sum) * N; |
||
1565 | int n2 = (p[1] / sum) * N; |
||
1566 | int n3 = (p[2] / sum) * N; |
||
1567 | int n4 = (p[3] / sum) * N; |
||
1568 | int n5 = (p[4] / sum) * N; |
||
1569 | |||
1570 | if (r >= 0 && r < n1) |
||
1571 | return 0; |
||
1572 | else if (coursesFinished[1] && r >= n1 && r < n1+n2) |
||
1573 | return 1; |
||
1574 | else if (coursesFinished[2] && r >= n1+n2 && r < n1+n2+n3) |
||
1575 | return 2; |
||
1576 | else if (coursesFinished[3] && r >= n1+n2+n3 && r < n1+n2+n3+n4) |
||
1577 | return 3; |
||
1578 | else if (coursesFinished[4] && r >= n1+n2+n3+n4 && r < n1+n2+n3+n4+n5) |
||
1579 | return 4; |
||
1580 | else if (coursesFinished[5] && r >= n1+n2+n3+n4+n5 && r <= N) |
||
1581 | return 5; |
||
1582 | |||
1583 | return 0; |
||
1584 | }=>>>>>>=>>>>>=>=>=>>>>>>=>>=>>=>>>>>=>>=>=>>>>>=>>>=>=>=>=(char)('0'+coursesNumber)>>>>>=>>=>> |