fixes for API renaming
[k8vacspelynky.git] / mapent / tiles / titletiles.vc
blob23b1c59df6220b35f53f3523e779efca2e0e9cf4
1 /**********************************************************************************
2  * Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
3  * Copyright (c) 2010, Moloch
4  * Copyright (c) 2018, Ketmar Dark
5  *
6  * This file is part of Spelunky.
7  *
8  * You can redistribute and/or modify Spelunky, including its source code, under
9  * the terms of the Spelunky User License.
10  *
11  * Spelunky is distributed in the hope that it will be entertaining and useful,
12  * but WITHOUT WARRANTY.  Please see the Spelunky User License for more details.
13  *
14  * The Spelunky User License should be available in "Game Information", which
15  * can be found in the Resource Explorer, or as an external file called COPYING.
16  * If not, please obtain a new copy of Spelunky from <http://spelunkyworld.com/>
17  *
18  **********************************************************************************/
19 class TitleTileBase : MapTile;
21 int tW = 16, tH = 16;
23 override int width () { return tW; }
24 override int height () { return tH; }
26 override void setupTile () {
29 override bool initialize () {
30   if (!::initialize()) return false;
31   auto spr = getSprite();
32   if (spr && spr.frames.length) {
33     tW = spr.frames[0].tex.width;
34     tH = spr.frames[0].tex.height;
35     //writeln("tile '", objType, "': ", tW, "x", tH);
36   }
37   return true;
41 // ////////////////////////////////////////////////////////////////////////// //
42 class TitleTileBG['oTitleBG'] : TitleTileBase;
44 defaultproperties {
45   objType = 'oTitleBG';
46   invincible = true; //???
47   solid = false;
48   spriteName = 'sTitleBG';
49   toSpecialGrid = true;
50   depth = 999_999;
54 // ////////////////////////////////////////////////////////////////////////// //
55 class TitleTileLogo['oTitleLogo'] : TitleTileBase;
57 bool ladderCreated;
58 bool bricksCreated;
61 final void removeTilesAtPix (int px, int py) {
62   for (;;) {
63     auto obj = level.checkTileAtPoint(px, py, delegate bool (MapTile t) { return true; });
64     if (!obj) break;
65     obj.instanceRemove();
66   }
70 void removeLadderAndBricks () {
71   ladderCreated = false;
72   bricksCreated = false;
73   foreach (int tn; 5..12) removeTilesAtPix(352+8, tn*16+8);
74   removeTilesAtPix(320+8, 96+8);
75   removeTilesAtPix(336+8, 96+8);
79 void createLadder () {
80   if (ladderCreated) return;
81   removeLadderAndBricks();
82   foreach (int tn; 5..12) {
83     if (global.config.gameMode != GameConfig::GameMode.Vanilla && !global.config.bizarrePlusTitle) {
84       level.MakeMapTileAtPix(352, tn*16, (tn == 5 ? 'oVineTop' : 'oVine'));
85     } else {
86       if (tn > 5) {
87         level.MakeMapTileAtPix(352, tn*16, (tn == 6 ? 'oLadderOrange' : tn == 7 ? 'oLadderTop' : 'oLadderOrange'));
88       }
89     }
90   }
91   ladderCreated = true;
95 void createBricks () {
96   if (bricksCreated) return;
97   removeLadderAndBricks();
98   level.MakeMapTileAtPix(320, 96, 'oBrick');
99   level.MakeMapTileAtPix(336, 96, 'oBrick');
100   bricksCreated = true;
104 int slidingDir = 0;
107 override void thinkFrame () {
108   if (global.config.scumUnlocked || level.stats.isAnyTunnelActive) {
109     //level.setRoomBounds(0, 0, 624, 232-16);
110     //level.setRoomBounds(624-320+16, 0, 624, 232-16);
111     createLadder();
112   } else {
113     //level.setRoomBounds(624-320+16, 0, 624, 232-16);
114     createBricks();
115   }
116   if (global.config.scumBallAndChain) level.player.spawnBallAndChain(); else level.player.removeBallAndChain();
118   if (ladderCreated) {
119     if (level.player.ix <= 624-320+16 && level.player.dir == Dir.Left) {
120       level.setRoomBounds(0, 0, 624, 232-16);
121       level.cameraSlideToPoint(0, 0, 16, 0);
122       slidingDir = -1;
123     } else if (level.player.ix >= 320 && level.player.dir == Dir.Right) {
124       level.setRoomBounds(0, 0, 624, 232-16);
125       level.cameraSlideToPoint(624-320+16, 0, 16, 0);
126       slidingDir = 1;
127     }
129     if (slidingDir) {
130       if (level.cameraSlideToSpeed.x != 0) {
131         if (level.cameraSlideToCurr.x == level.cameraSlideToDest.x) level.cameraSlideToSpeed.x = 0;
132       }
133       if (level.cameraSlideToSpeed.x == 0) {
134         if (slidingDir < 0) {
135           level.setRoomBounds(0, 0, 320-16, 232-16);
136         } else {
137           level.setRoomBounds(624-320+16, 0, 624, 232-16);
138         }
139         slidingDir = 0;
140       }
141     }
142   }
146 override void drawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
147   if (invisible || !visible) return;
148   ::drawWithOfs(xpos, ypos, scale, currFrameDelta);
150   /*
151   int x = ix*scale-xpos;
152   int y = iy*scale-ypos;
153   int tCol = 0x93_53_11; // light dirt
154   if (global.config.gameMode != GameConfig::GameMode.Vanilla) {
155     tCol = (global.config.bizarrePlusTitle ? 0x25_59_8e : 0x78_61_21);
156   }
158   auto spf = getSpriteFrame();
159   GLVideo.color = tCol;
160   spf.blitAt(x, y, scale);
161   */
163   auto oclr = GLVideo.color;
164   GLVideo.color = 0x8f_81_5b;
165   level.sprStore.loadFont('sFontSmall');
166   level.sprStore.renderText((ix+110)*scale-xpos, (iy+26)*scale-ypos, "K8", scale);
167   //writeln("(", ix, ",", iy, ") : (526, 106)");
168   string bdate = level.getBuildDateString();
169   if (bdate) {
170     level.sprStore.loadFont('sFontTiny');
171     GLVideo.color = 0x8f_81_5b;
172     level.sprStore.renderText((ix+110-32)*scale-xpos, (iy+26+8)*scale-ypos, bdate, scale);
173   }
175   if (level.loserGPU) {
176     GLVideo.color = 0xff_00_00;
177     level.sprStore.loadFont('sFontSmall');
178     level.sprStore.renderText((ix-32)*scale-xpos, (iy+32)*scale-ypos, "YOUR GPU SUX!", scale);
179     level.sprStore.renderText((ix-32)*scale-xpos, (iy+32+8)*scale-ypos, "DARKNESS WILL LOOK UGLY!", scale);
180   }
182   GLVideo.color = oclr;
186 defaultproperties {
187   objType = 'oTitleLogo';
188   invincible = true; //???
189   solid = true;
190   spriteName = 'sTitle';
191   toSpecialGrid = true;
195 // ////////////////////////////////////////////////////////////////////////// //
196 class TitleTileTitleGlow['oTitleGlow'] : TitleTileBase;
198 int burn = 3;
199 int timerGlow;
200 int timerBurn;
203 override void setupTile () {
204   timerGlow = global.randOther(3, 8)*30;
208 override void onAnimationLooped () {
209   imageSpeed = 0;
210   timerGlow = global.randOther(3, 8)*30;
214 override void thinkFrame () {
215   if (timerBurn > 0) {
216     if (--timerBurn == 0) {
217       if (burn > 0) {
218         --burn;
219         if (global.randOther(1, 2) == 1) playSound('sndIgnite');
220         level.MakeMapObject(ix+4+global.randOther(1, 8), iy+global.randOther(1, 15), 'oBurn');
221         level.MakeMapObject(ix+global.randOther(1, 8), iy+10+global.randOther(1, 6), 'oBurn');
222         level.MakeMapObject(ix+8+global.randOther(1, 8), iy+10+global.randOther(1, 6), 'oBurn');
223         timerBurn = global.randOther(10, 20);
224       } else {
225         instanceRemove();
226         return;
227       }
228     }
229   }
231   if (timerGlow > 0) {
232     if (--timerGlow == 0) {
233       imageSpeed = global.randOther(2, 4)/10.0;
234     }
235   }
237   // open test chamber door
238   auto hit = level.player.holdItem;
239   if (hit isa ItemFlare && hit.isRectHitSimple(x0, y0, width, height)) {
240     level.player.holdItem = none;
241     level.MakeMapObject(ix+4+global.randOther(1, 8), iy+4+global.randOther(1, 8), 'oBurn');
242     level.MakeMapObject(ix+2+global.randOther(1, 4), iy+10+global.randOther(1, 4), 'oBurn');
243     level.MakeMapObject(ix+10+global.randOther(1, 4), iy+10+global.randOther(1, 4), 'oBurn');
244     foreach (; 0..5) level.MakeMapObject(ix+8, iy+8, 'oFlame');
245     level.MakeMapTileAtPix(ix, iy, 'oXDebug');
246     playSound('sndChestOpen');
247     global.testChamberRevealed = true;
248     invisible = true;
249     timerBurn = global.randOther(10, 15);
250     hit.instanceRemove();
251   }
255 defaultproperties {
256   objType = 'oTitleGlow';
257   invincible = true; //???
258   solid = false;
259   spriteName = 'sTitleGlow';
260   toSpecialGrid = true;
261   depth = 999998;
262   imageSpeed = 0;
266 // ////////////////////////////////////////////////////////////////////////// //
267 class TitleTileTextSigns : TitleTileBase;
269 defaultproperties {
270   invincible = true; //???
271   solid = true;
272   toSpecialGrid = true;
273   //depth = 5;
277 // ////////////////////////////////////////////////////////////////////////// //
278 class TitleTileQuitSign['oQuitSign'] : TitleTileTextSigns;
280 defaultproperties {
281   objType = 'oQuitSign';
282   spriteName = 'sQuitSign';
286 // ////////////////////////////////////////////////////////////////////////// //
287 class TitleTileTutorialSign['oTutorialSign'] : TitleTileTextSigns;
289 defaultproperties {
290   objType = 'oTutorialSign';
291   spriteName = 'sTutorialSign';
295 // ////////////////////////////////////////////////////////////////////////// //
296 class TitleTileDoorArcs : TitleTileBase;
298 defaultproperties {
299   invincible = true; //???
300   solid = false;
301   toSpecialGrid = true;
302   //depth = 102;
303   depth = 8500;
307 // ////////////////////////////////////////////////////////////////////////// //
308 class TitleTileLevel5Sign['oLevel5Sign'] : TitleTileDoorArcs;
310 defaultproperties {
311   objType = 'oLevel5Sign';
312   spriteName = 'sLevel5Sign';
316 class TitleTileLevel9Sign['oLevel9Sign'] : TitleTileDoorArcs;
318 defaultproperties {
319   objType = 'oLevel9Sign';
320   spriteName = 'sLevel9Sign';
324 class TitleTileLevel13Sign['oLevel13Sign'] : TitleTileDoorArcs;
326 defaultproperties {
327   objType = 'oLevel13Sign';
328   spriteName = 'sLevel13Sign';
332 // ////////////////////////////////////////////////////////////////////////// //
333 class TitleTileStartSignBig['oStartSignBig'] : TitleTileDoorArcs;
335 defaultproperties {
336   objType = 'oStartSignBig';
337   invincible = true; //???
338   solid = false;
339   spriteName = 'sStartSignBig';
340   toSpecialGrid = true;
344 // ////////////////////////////////////////////////////////////////////////// //
345 class TitleTileScoresSign['oScoresSign'] : TitleTileDoorArcs;
347 defaultproperties {
348   objType = 'oScoresSign';
349   spriteName = 'sScoresSign';
353 // ////////////////////////////////////////////////////////////////////////// //
354 class TitleTileModeSign['oModeSign'] : TitleTileDoorArcs;
356 defaultproperties {
357   objType = 'oModeSign';
358   spriteName = 'sModeSign';
362 // ////////////////////////////////////////////////////////////////////////// //
363 class TitleTileCopy['oCopy'] : TitleTileBase;
366 override void drawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
367   if (invisible || !visible) return;
369   int x = ix*scale-xpos;
370   int y = iy*scale-ypos;
371   int tCol = 0x93_53_11; // light dirt
372   if (global.config.gameMode != GameConfig::GameMode.Vanilla) {
373     tCol = (global.config.bizarrePlusTitle ? 0x25_59_8e : 0x78_61_21);
374   }
376   auto spf = getSpriteFrame();
377   auto oclr = GLVideo.color;
378   GLVideo.color = tCol;
379   spf.blitAt(x, y, scale);
380   GLVideo.color = oclr;
384 defaultproperties {
385   objType = 'oCopy';
386   invincible = true; //???
387   solid = false;
388   spriteName = 'sCopy';
389   depth = -5;
390   toSpecialGrid = true;
391   spectral = true;
395 // ////////////////////////////////////////////////////////////////////////// //
396 class TitleTileExitBase : TitleTileBase;
398 override void setupTile () {
401 defaultproperties {
402   spriteName = 'sExit';
403   invincible = true; //???
404   solid = false;
405   toSpecialGrid = true;
406   exit = true;
407   depth = 8000;
411 // ////////////////////////////////////////////////////////////////////////// //
412 class TitleTileXTitle['oXTitle'] : TitleTileExitBase;
414 override string getExitMessage () {
415   return "RETURN TO TITLE SCREEN.";
419 defaultproperties {
420   objType = 'oXTitile';
424 // ////////////////////////////////////////////////////////////////////////// //
425 class TitleTileXTutorial['oXTutorial'] : TitleTileExitBase;
427 override string getExitMessage () {
428   return "BASIC TUTORIAL.";
431 override void setupTile () {
435 defaultproperties {
436   objType = 'oXTutorial';
437   exit = true;
438   //spriteName = 'sEntrance'; // alas
442 // ////////////////////////////////////////////////////////////////////////// //
443 class TitleTileXScores['oXScores'] : TitleTileExitBase;
446 override string getExitMessage () {
447   return "CHALLENGE CHAMBERS.";
451 defaultproperties {
452   objType = 'oXScores';
453   //exit = false;
454   //spriteName = 'sEntrance'; // alas
458 // ////////////////////////////////////////////////////////////////////////// //
459 class TitleTileXMode['oXMode'] : TitleTileExitBase;
462 defaultproperties {
463   objType = 'oXMode';
464   exit = false;
465   spriteName = 'sEntrance'; // alas
469 // ////////////////////////////////////////////////////////////////////////// //
470 class TitleTileXDebug['oXDebug'] : TitleTileExitBase;
473 defaultproperties {
474   objType = 'oXDebug';
475   exit = false;
476   spriteName = 'sEntrance'; // alas
480 // ////////////////////////////////////////////////////////////////////////// //
481 class TitleTileShortcutDoor : TitleTileExitBase;
483 int startLevel = 1;
486 bool isAllowed () { return true; }
488 override bool isExitActive () { return (visible && isAllowed()); }
491 override void thinkFrame () {
492   if (global.config.scumUnlocked || isAllowed()) {
493     invisible = false;
494     visible = true;
495   } else {
496     invisible = true;
497     visible = false;
498   }
502 defaultproperties {
503   invisible = true;
504   visible = false;
508 // ////////////////////////////////////////////////////////////////////////// //
509 class TitleTileXStart['oXStart'] : TitleTileShortcutDoor;
512 override string getExitMessage () {
513   return "START NEW GAME.";
517 override void snapToExit (MapEntity e) {
518   if (!e || !e.isInstanceAlive) return;
519        if (e.ix < ix+14) e.fltx = ix+14;
520   else if (e.ix+14 > ix+width) e.fltx = ix+width-14;
521   //e.flty = iy+8;
522   e.updateGrid();
526 defaultproperties {
527   //<origin x="16" y="32"/>
528   //48x48
529   objType = 'oXStart';
530   spriteName = 'sBigExit';
531   startLevel = 1;
532   ignoreFrameOffsetX = true;
533   ignoreFrameOffsetY = true;
537 // ////////////////////////////////////////////////////////////////////////// //
538 class TitleTileXShortcut5['oXShortcut5'] : TitleTileShortcutDoor;
541 override bool isAllowed () { return (global.config.scumUnlocked || level.stats.isTunnelActive(1)); }
544 override string getExitMessage () {
545   return "START NEW GAME FROM JUNGLE.";
549 defaultproperties {
550   objType = 'oXShortcut5';
551   startLevel = 5;
555 // ////////////////////////////////////////////////////////////////////////// //
556 class TitleTileXShortcut9['oXShortcut9'] : TitleTileShortcutDoor;
559 override bool isAllowed () { return (global.config.scumUnlocked || level.stats.isTunnelActive(2)); }
562 override string getExitMessage () {
563   return "START NEW GAME FROM ICE CAVES.";
567 defaultproperties {
568   objType = 'oXShortcut9';
569   startLevel = 9;
573 // ////////////////////////////////////////////////////////////////////////// //
574 class TitleTileXShortcut13['oXShortcut13'] : TitleTileShortcutDoor;
577 override bool isAllowed () { return (global.config.scumUnlocked || level.stats.isTunnelActive(3)); }
580 override string getExitMessage () {
581   return "START NEW FROM TEMPLE.";
585 defaultproperties {
586   objType = 'oXShortcut13';
587   startLevel = 13;