animate "$" on held item
[k8vacspelynky.git] / roomIntro.vc
blob1e628395845ba50c8bb7421a64fb7471ae637826
1 /**********************************************************************************
2  * Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
3  * Copyright (c) 2018, Ketmar Dark
4  *
5  * This file is part of Spelunky.
6  *
7  * You can redistribute and/or modify Spelunky, including its source code, under
8  * the terms of the Spelunky User License.
9  *
10  * Spelunky is distributed in the hope that it will be entertaining and useful,
11  * but WITHOUT WARRANTY.  Please see the Spelunky User License for more details.
12  *
13  * The Spelunky User License should be available in "Game Information", which
14  * can be found in the Resource Explorer, or as an external file called COPYING.
15  * If not, please obtain a new copy of Spelunky from <http://spelunkyworld.com/>
16  *
17  **********************************************************************************/
18 transient string introString1;
19 transient string introString2;
20 transient string introString3;
22 transient int introPhase;
23 transient int introPhaseTimer;
24 transient int titleCutsceneSkip;
27 void introCutscenePlayerControl (PlayerPawn plr) {
28   auto payPress = isKeyPressed(GameConfig::Key.Pay);
29   auto payRelease = isKeyReleased(GameConfig::Key.Pay);
31   if (stats.introViewed && introPhase < 8) {
32     switch (titleCutsceneSkip) {
33       case 0: // nothing was pressed
34         if (payPress) titleCutsceneSkip = 1;
35         break;
36       case 1: // waiting for pay release
37         if (payRelease) titleCutsceneSkip = 2;
38         break;
39       case 2: // pay released, do skip
40         cameFromIntroRoom = false;
41         inIntroCutscene = 0;
42         restartTitle();
43         return;
44     }
45   }
47   if (!plr.visible) return;
49   // in title room
50   if (introPhase == 8) {
51     player.iy = 4;
52     player.visible = true;
53     player.status = MapObject::CLIMBING;
54     MakeMapObject(player.ix, player.y1+1, 'oFlare');
55     ++introPhase;
56   }
58   if (introPhase == 9) {
59     if (plr.status != MapObject::CLIMBING) {
60       plr.kUp = true;
61       return;
62     }
63     ++introPhase;
64   }
66   if (introPhase == 10) {
67     if (plr.iy < 100 || plr.status == MapObject::CLIMBING) {
68       plr.kDown = true;
69       return;
70     }
71     ++introPhase;
72   }
74   if (introPhase == 11) {
75     inIntroCutscene = 0;
76     cameFromIntroRoom = false;
77     ++stats.introViewed;
78     return;
79   }
81   // in intro room
82   if (introPhase == 4) {
83     //plr.kRight = true;
84     if (plr.ix < 262) {
85       plr.kRight = true;
86     }
87     return;
88   }
90   if (introPhase == 5) {
91     plr.kDown = true;
92     if (introPhaseTimer == 2) plr.kRopePressed = true;
93   }
95   if (introPhase == 6) {
96     plr.kDown = true;
97     if (introPhaseTimer > 0) {
98       --introPhaseTimer;
99     } else {
100       //writeln(plr.status);
101       if (plr.status != MapObject::CLIMBING) {
102         plr.kRight = true;
103       } else {
104         if (plr.iy > 280) {
105           plr.visible = false;
106           ++introPhase;
107           introPhaseTimer = 255;
108         }
109       }
110     }
111   }
115 final void renderTitleCutscenePhrase (int phnum, int alpha) {
116   if (phnum > introPhase) return;
117   string ss;
118   switch (phnum) {
119     case 1: ss = introString1; break;
120     case 2: ss = introString2; break;
121     case 3: ss = introString3; break;
122     default: return;
123   }
124   sprStore.loadFont('sFontSmall');
125   Video.color = 0xff_ff_ff|(clamp(255-alpha, 0, 255)<<24);
126   auto twdt = sprStore.getTextWidth(ss);
127   drawTextAt((320-twdt)/2, 80-16-16+phnum*16, ss);
131 void renderTitleCutsceneOverlay () {
132   if (introPhase >= 8) {
133     // in title room
134     return;
135   }
137   if (introPhase == -1) {
138     Video.color = clamp(introPhaseTimer, 0, 255)<<24;
139     Video.fillRect(0, 0, Video.screenWidth, Video.screenHeight);
140   }
142   if (introPhase >= 1) {
143     renderTitleCutscenePhrase(1, (introPhase == 1 ? introPhaseTimer : 255));
144     renderTitleCutscenePhrase(2, (introPhase == 2 ? introPhaseTimer : 255));
145     renderTitleCutscenePhrase(3, (introPhase == 3 ? introPhaseTimer : 255));
146   }
148   if (introPhase == 7) {
149     Video.color = clamp(introPhaseTimer, 0, 255)<<24;
150     Video.fillRect(0, 0, Video.screenWidth, Video.screenHeight);
151   }
153   Video.color = 0xff_ff_ff;
157 void thinkFrameIntro () {
158   // don't let the player fall away
159   if (player.ix <= 0) player.iy = 11*16+8;
160   //writeln(player.ix, ",", player.iy);
162   if (introPhase == -1) {
163     introPhaseTimer += 3;
164     if (introPhaseTimer < 255) return;
165     ++introPhase;
166     introPhaseTimer = 15;
167   }
169   if (introPhase == 0) {
170     if (--introPhaseTimer <= 0) {
171       ++introPhase;
172       introPhaseTimer = 0;
173     }
174     return;
175   }
177   if (introPhase >= 1 && introPhase <= 3) {
178     introPhaseTimer += 3;
179     if (introPhaseTimer >= 255+30*3) {
180       ++introPhase;
181       introPhaseTimer = 0;
182     }
183     return;
184   }
186   if (introPhase == 4) {
187     player.visible = true;
188     if (player.ix < 0) {
189       player.iy = 11*16+8;
190       player.ix = player.ix+1;
191       player.fallTimer = 0;
192       player.status = MapObject::STANDING;
193       if (player.ix < 0) return;
194     }
195     if (player.ix > 200 && player.xVel == 0) {
196       ++introPhase;
197       introPhaseTimer = 30;
198     }
199   }
201   if (introPhase == 5) {
202     if (--introPhaseTimer == 0) {
203       ++introPhase;
204       introPhaseTimer = 10;
205     }
206   }
208   if (introPhase == 7) {
209     introPhaseTimer -= 2;
210     if (introPhaseTimer <= 0) {
211       cameFromIntroRoom = true;
212       restartTitle();
213       ++introPhase;
214       //player.iy = 4;
215       //player.visible = true;
216     }
217   }
221 void createIntroRoom () {
222   clearForTransition();
223   //global.darkLevel = true;
225   inIntroCutscene = 1;
226   introPhase = 0;
227   introPhaseTimer = 30;
228   titleCutsceneSkip = 0;
230   // fade in
231   introPhase = -1;
232   introPhaseTimer = 0;
234   //introPhase = 3;
235   //introPhaseTimer = 255;
237   switch (global.randOther(1, 8)) {
238     case 1: introString1 = "AS THE SUN BURNED BRIGHT ABOVE, "; break;
239     case 2: introString1 = "WITH THE DESERT STRETCHING BEHIND ME, "; break;
240     case 3: introString1 = "AFTER I DOUBLE-CHECKED MY MAP, "; break;
241     case 4: introString1 = "MY LIPS CRACKED AND COVERED IN SAND, "; break;
242     case 5: introString1 = "WITH FATE GUIDING MY EVERY MOVE, "; break;
243     case 6: introString1 = "PUTTING THE FADED PHOTO IN MY POCKET, "; break;
244     case 7: introString1 = "AS I RECALLED MY FATHER'S LAST WORDS, "; break;
245     case 8: introString1 = "MY MEMORY SLIPPING AWAY FROM ME, "; break;
246   }
248   switch (global.randOther(1, 8)) {
249     case 1: introString2 = "I STRODE VALIANTLY TOWARD MY DESTINY, "; break;
250     case 2: introString2 = "I SQUEEZED THE WHIP AT MY SIDE, "; break;
251     case 3: introString2 = "I DRAINED THE REST OF MY CANTEEN, "; break;
252     case 4: introString2 = "I SPOTTED THE CAVE'S ENTRANCE, "; break;
253     case 5: introString2 = "I FURROWED MY BROW, "; break;
254     case 6: introString2 = "I PAID MY BEDOUIN GUIDE, "; break;
255     case 7: introString2 = "I DISMOUNTED MY CAMEL, "; break;
256     case 8: introString2 = "I SQUINTED INTO THE DARKNESS, "; break;
257   }
259   switch (global.randOther(1, 8)) {
260     case 1: introString3 = "AND THOUGHT OF HER ONE LAST TIME."; break;
261     case 2: introString3 = "AND HELD MY HAT AGAINST THE WIND."; break;
262     case 3: introString3 = "AND A COLD CHILL TOOK HOLD OF ME."; break;
263     case 4: introString3 = "AND WONDERED HOW LONG I'D BE BELOW."; break;
264     case 5: introString3 = "AND VOWED TO RETURN VICTORIOUS."; break;
265     case 6: introString3 = "AND SWORE I HEARD VOICES UP AHEAD."; break;
266     case 7: introString3 = "AND FELT THE GODS SMILING UPON ME."; break;
267     case 8: introString3 = "AND THAT'S WHEN IT ALL STARTED."; break;
268   }
270   setRoomBounds(0, 0, 304, 224-16);
271   levBGImgName = 'bgCave';
272   //levBGImgName = 'sTitleBG';
273   //levBGImgName = '';
275   //MakeMapTile(0, 0, 'oIntro');
276   //MakeMapTile(1, 0, 'oBricks');
277   //MakeMapTile(0, 1, 'oGlobals');
278   //MakeMapTile(1, 1, 'oGame');
280   MakeMapTile(0, 0, 'oEnd2BG');
281   MakeMapTile(0, 0, 'oCaveBG3');
283   MakeMapTile(10, 0, 'oBrick');
284   MakeMapTile(11, 0, 'oBrick');
285   MakeMapTile(12, 0, 'oBrick');
286   MakeMapTile(13, 0, 'oBrick');
287   MakeMapTile(14, 0, 'oBrick');
288   MakeMapTile(15, 0, 'oBrick');
289   MakeMapTile(16, 0, 'oBrick');
290   MakeMapTile(17, 0, 'oBrick');
291   MakeMapTile(18, 0, 'oBrick');
292   MakeMapTile(19, 0, 'oBrick');
293   MakeMapTile(9, 1, 'oBrick');
294   MakeMapTile(10, 1, 'oBrick');
295   MakeMapTile(11, 1, 'oBrick');
296   MakeMapTile(12, 1, 'oBrick');
297   MakeMapTile(13, 1, 'oBrick');
298   MakeMapTile(14, 1, 'oBrick');
299   MakeMapTile(15, 1, 'oBrick');
300   MakeMapTile(16, 1, 'oBrick');
301   MakeMapTile(17, 1, 'oBrick');
302   MakeMapTile(18, 1, 'oBrick');
303   MakeMapTile(19, 1, 'oBrick');
304   MakeMapTile(9, 2, 'oBrick');
305   MakeMapTile(10, 2, 'oBrick');
306   MakeMapTile(11, 2, 'oBrick');
307   MakeMapTile(12, 2, 'oBrick');
308   MakeMapTile(13, 2, 'oBrick');
309   MakeMapTile(14, 2, 'oBrick');
310   MakeMapTile(15, 2, 'oBrick');
311   MakeMapTile(16, 2, 'oBrick');
312   MakeMapTile(17, 2, 'oBrick');
313   MakeMapTile(18, 2, 'oBrick');
314   MakeMapTile(19, 2, 'oBrick');
315   MakeMapTile(9, 3, 'oBrick');
316   MakeMapTile(10, 3, 'oBrick');
317   MakeMapTile(11, 3, 'oBrick');
318   MakeMapTile(12, 3, 'oBrick');
319   MakeMapTile(13, 3, 'oBrick');
320   MakeMapTile(14, 3, 'oBrick');
321   MakeMapTile(15, 3, 'oBrick');
322   MakeMapTile(16, 3, 'oBrick');
323   MakeMapTile(17, 3, 'oBrick');
324   MakeMapTile(18, 3, 'oBrick');
325   MakeMapTile(19, 3, 'oBrick');
326   MakeMapTile(8, 4, 'oBrick');
327   MakeMapTile(9, 4, 'oBrick');
328   MakeMapTile(10, 4, 'oBrick');
329   MakeMapTile(11, 4, 'oBrick');
330   MakeMapTile(12, 4, 'oBrick');
331   MakeMapTile(13, 4, 'oBrick');
332   MakeMapTile(14, 4, 'oBrick');
333   MakeMapTile(15, 4, 'oBrick');
334   MakeMapTile(16, 4, 'oBrick');
335   MakeMapTile(17, 4, 'oBrick');
336   MakeMapTile(18, 4, 'oBrick');
337   MakeMapTile(19, 4, 'oBrick');
338   MakeMapTile(8, 5, 'oBrick');
339   MakeMapTile(9, 5, 'oBrick');
340   MakeMapTile(10, 5, 'oBrick');
341   MakeMapTile(11, 5, 'oBrick');
342   MakeMapTile(12, 5, 'oBrick');
343   MakeMapTile(13, 5, 'oBrick');
344   MakeMapTile(14, 5, 'oBrick');
345   MakeMapTile(15, 5, 'oBrick');
346   MakeMapTile(16, 5, 'oBrick');
347   MakeMapTile(17, 5, 'oBrick');
348   MakeMapTile(18, 5, 'oBrick');
349   MakeMapTile(19, 5, 'oBrick');
350   MakeMapTile(7, 6, 'oBrick');
351   MakeMapTile(8, 6, 'oBrick');
352   MakeMapTile(9, 6, 'oBrick');
353   MakeMapTile(10, 6, 'oBrick');
354   MakeMapTile(11, 6, 'oBrick');
355   MakeMapTile(12, 6, 'oBrick');
356   MakeMapTile(13, 6, 'oBrick');
357   MakeMapTile(14, 6, 'oBrick');
358   MakeMapTile(15, 6, 'oBrick');
359   MakeMapTile(16, 6, 'oBrick');
360   MakeMapTile(17, 6, 'oBrick');
361   MakeMapTile(18, 6, 'oBrick');
362   MakeMapTile(19, 6, 'oBrick');
363   MakeMapTile(7, 7, 'oBrick');
364   MakeMapTile(8, 7, 'oBrick');
365   MakeMapTile(9, 7, 'oBrick');
366   MakeMapTile(10, 7, 'oBrick');
367   MakeMapTile(11, 7, 'oBrick');
368   MakeMapTile(12, 7, 'oBrick');
369   MakeMapTile(13, 7, 'oBrick');
370   MakeMapTile(14, 7, 'oBrick');
371   MakeMapTile(15, 7, 'oBrick');
372   MakeMapTile(16, 7, 'oBrick');
373   MakeMapTile(17, 7, 'oBrick');
374   MakeMapTile(18, 7, 'oBrick');
375   MakeMapTile(19, 7, 'oBrick');
376   MakeMapTile(6, 8, 'oBrick');
377   MakeMapTile(7, 8, 'oBrick');
378   MakeMapTile(8, 8, 'oBrick');
379   MakeMapTile(9, 8, 'oBrick');
380   MakeMapTile(10, 8, 'oBrick');
381   MakeMapTile(11, 8, 'oBrick');
382   MakeMapTile(12, 8, 'oBrick');
383   MakeMapTile(13, 8, 'oBrick');
384   MakeMapTile(14, 8, 'oBrick');
385   MakeMapTile(15, 8, 'oBrick');
386   MakeMapTile(16, 8, 'oBrick');
387   MakeMapTile(17, 8, 'oBrick');
388   MakeMapTile(18, 8, 'oBrick');
389   MakeMapTile(19, 8, 'oBrick');
390   MakeMapTile(0, 9, 'oBGEnd3');
391   MakeMapTile(5, 9, 'oBrick');
392   MakeMapTile(6, 9, 'oBrick');
393   MakeMapTile(7, 9, 'oCaveBG2');
394   MakeMapTile(7, 9, 'oBrick');
395   MakeMapTile(8, 9, 'oBrick');
396   MakeMapTile(9, 9, 'oCaveBG2');
397   MakeMapTile(11, 9, 'oCaveBG2');
398   MakeMapTile(12, 9, 'oBrick');
399   MakeMapTile(13, 9, 'oCaveBG2');
400   MakeMapTile(15, 9, 'oCaveBG2');
401   MakeMapTile(17, 9, 'oBrick');
402   MakeMapTile(17, 9, 'oCaveBG2');
403   MakeMapTile(18, 9, 'oBrick');
404   MakeMapTile(19, 9, 'oBrick');
405   MakeMapTile(5, 10, 'oBrick');
406   MakeMapTile(6, 10, 'oBrick');
407   MakeMapTile(18, 10, 'oBrick');
408   MakeMapTile(19, 10, 'oBrick');
409   MakeMapTile(0, 11, 'oDesertTop');
410   MakeMapTile(1, 11, 'oDesertTop');
411   MakeMapTile(2, 11, 'oDesertTop');
412   MakeMapTile(3, 11, 'oDesertTop');
413   MakeMapTile(4, 11, 'oDesertTop');
414   MakeMapTile(5, 11, 'oCaveBG2');
415   MakeMapTile(7, 11, 'oCaveBG2');
416   MakeMapTile(9, 11, 'oCaveBG2');
417   MakeMapTile(11, 11, 'oCaveBG2');
418   MakeMapTile(13, 11, 'oCaveBG2');
419   MakeMapTile(15, 11, 'oCaveBG2');
420   MakeMapTile(17, 11, 'oCaveBG2');
421   MakeMapTile(18, 11, 'oBrick');
422   MakeMapTile(19, 11, 'oBrick');
423   MakeMapTile(0, 12, 'oDesert2');
424   MakeMapTile(1, 12, 'oDesert2');
425   MakeMapTile(2, 12, 'oDesert2');
426   MakeMapTile(3, 12, 'oDesert2');
427   MakeMapTile(4, 12, 'oDesert2');
428   MakeMapTile(5, 12, 'oBrick');
429   MakeMapTile(6, 12, 'oBrick');
430   MakeMapTile(7, 12, 'oBrick');
431   MakeMapTile(8, 12, 'oBrick');
432   MakeMapTile(9, 12, 'oBrick');
433   MakeMapTile(10, 12, 'oBrick');
434   MakeMapTile(11, 12, 'oBrick');
435   MakeMapTile(12, 12, 'oBrick');
436   MakeMapTile(13, 12, 'oBrick');
437   MakeMapTile(14, 12, 'oBrick');
438   MakeMapTile(15, 12, 'oBrick');
439   MakeMapTile(16, 12, 'oBrick');
440   MakeMapTile(18, 12, 'oBrick');
441   MakeMapTile(19, 12, 'oBrick');
442   MakeMapTile(0, 13, 'oDesert');
443   MakeMapTile(1, 13, 'oDesert');
444   MakeMapTile(2, 13, 'oDesert');
445   MakeMapTile(3, 13, 'oDesert');
446   MakeMapTile(4, 13, 'oDesert');
447   MakeMapTile(5, 13, 'oDesert');
448   MakeMapTile(6, 13, 'oBrick');
449   MakeMapTile(7, 13, 'oBrick');
450   MakeMapTile(8, 13, 'oBrick');
451   MakeMapTile(9, 13, 'oBrick');
452   MakeMapTile(10, 13, 'oBrick');
453   MakeMapTile(11, 13, 'oBrick');
454   MakeMapTile(12, 13, 'oBrick');
455   MakeMapTile(13, 13, 'oBrick');
456   MakeMapTile(14, 13, 'oBrick');
457   MakeMapTile(15, 13, 'oBrick');
458   MakeMapTile(16, 13, 'oBrick');
459   MakeMapTile(17, 13, 'oCaveBG2');
460   MakeMapTile(18, 13, 'oBrick');
461   MakeMapTile(19, 13, 'oBrick');
462   MakeMapTile(0, 14, 'oDesert');
463   MakeMapTile(1, 14, 'oDesert');
464   MakeMapTile(2, 14, 'oDesert');
465   MakeMapTile(3, 14, 'oDesert');
466   MakeMapTile(4, 14, 'oDesert');
467   MakeMapTile(5, 14, 'oDesert');
468   MakeMapTile(6, 14, 'oBrick');
469   MakeMapTile(7, 14, 'oBrick');
470   MakeMapTile(8, 14, 'oBrick');
471   MakeMapTile(9, 14, 'oBrick');
472   MakeMapTile(10, 14, 'oBrick');
473   MakeMapTile(11, 14, 'oBrick');
474   MakeMapTile(12, 14, 'oBrick');
475   MakeMapTile(13, 14, 'oBrick');
476   MakeMapTile(14, 14, 'oBrick');
477   MakeMapTile(15, 14, 'oBrick');
478   MakeMapTile(16, 14, 'oBrick');
479   MakeMapTile(18, 14, 'oBrick');
480   MakeMapTile(19, 14, 'oBrick');
482   if (global.randOther(1, 3) > 1) MakeMapTileAtPix(0, 176, 'oShrub');
483   if (global.randOther(1, 3) > 1) MakeMapTileAtPix(32, 176, 'oShrub');
485   if (global.randOther(1, 4) > 1) {
486     int pty;
487     do { pty = global.randOther(1, 6); } while (pty == 2);
488     MakeMapTileAtPix(0, 56+pty*8, (pty < 2 ? 'oPalmTree' : 'oPalmTreeFwd'));
489   }
491   if (global.randOther(1, 4) > 1) {
492     int pty;
493     do { pty = global.randOther(1, 8); } while (pty == 2);
494     MakeMapTileAtPix(32, 56+pty*8, (pty < 2 ? 'oPalmTree' : 'oPalmTreeFwd'));
495   }
497   if (global.randOther(1, 4) == 1) {
498     int xx;
499     switch (global.randOther(0, 3)) {
500       case 0: xx = 144; break;
501       case 1: xx = 176; break;
502       case 2: xx = 208; break;
503       case 3: xx = 256; break;
504     }
505     MakeMapObject(xx, 144, 'oWeb');
506   }
508   if (global.randOther(1, 4) > 1) {
509     int xx;
510     switch (global.randOther(0, 2)) {
511       case 0: xx = 160; break;
512       case 1: xx = 224; break;
513       case 2: xx = 240; break;
514     }
515     MakeMapTileAtPix(xx, 144, 'oLamp');
516   }
518        if (global.randOther(1, 5) == 1) MakeMapObject(144+global.randOther(1, 12)*8, 176+12, 'oRock');
519   else if (global.randOther(1, 4) == 1) MakeMapObject(144+global.randOther(1, 12)*8, 176+10, 'oJar');
520   else if (global.randOther(1, 3) == 1) {
521     int n = 144+global.randOther(1, 12)*8;
522     MakeMapObject(n, 176, 'oBones');
523     MakeMapObject(n+12, 176+12, 'oSkull');
524   }
526   if (global.randOther(1, 2) == 1) MakeMapTileAtPix(112, 160, 'oBrick');
528   // so the player will not fall away
529   /*
530   auto supptile = MakeMapTile(1, 11, 'oBrick');
531   supptile.ix = -16;
532   supptile.updateGrid();
534   supptile = MakeMapTile(1, 11, 'oBrick');
535   supptile.ix = -16*2;
536   supptile.updateGrid();
537   */
539   spawnPlayerAt(-16, 11*16+8);
540   player.dir = MapEntity::Dir.Right;
541   player.flying = true;
542   player.visible = false;