fixes for API renaming
[k8vacspelynky.git] / mapent / tiles / speartraps.vc
blob02df693e1400bcf635a3f55a2f38d933bc305dce
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 // bottom: sSpearTrap2 (100)
20 // top: sSpearTrap1 (100)
21 // toplit: sSpearTrapLit (100)
22 class MapTileSpearTrapBase : MapTile abstract;
24 const int firedMax = 50;
25 const int range = 64;
26 int prox = 4;
27 name rightSpriteName;
28 int firedLeft;
29 int firedRight;
32 override void setupTile () {
33   if (global.cityOfGold == 1) {
34     ore = 2;
35   } else {
36     ore = 0;
37   }
38 /*!destroying
39     if (global.cityOfGold != 1)
40     {
41         if (smashed) scrSprayRubble(3, sRubbleTan, sRubbleTanSmall);
42         scrDropRubble(3, sRubbleTan, sRubbleTanSmall);
43     }
44     else
45     {
46         for (i = 0; i &lt; 3; i += 1)
47         {
48             gold = instance_create(x+8+rand(0,4)-rand(0,4), y+8+rand(0,4)-rand(0,4), oGoldChunk);
49             gold.xVel = rand(0,3) - rand(0,3);
50             gold.yVel = rand(2,4) * 1;
51         }
52         gold = instance_create(x+8+rand(0,4)-rand(0,4), y+8+rand(0,4)-rand(0,4), oGoldNugget);
53         gold.xVel = rand(0,3) - rand(0,3);
54         gold.yVel = rand(2,4) * 1;
55     }
61 override void drawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
62   ::drawWithOfs(xpos, ypos, scale, currFrameDelta);
63   if (!fired) {
64     auto oclr = GLVideo.color;
65     GLVideo.color = 0x7f_00_ff_00;
66     GLVideo.fillRect(checkerX*scale-xpos, checkerY*scale-ypos, checkerW*scale, checkerH*scale);
67     GLVideo.color = oclr;
68   }
73 final bool needToCheckForActivation () {
74   return (!firedLeft || !firedRight);
78 final void activateTrap (bool atLeft) {
79   if (atLeft) {
80     if (!firedLeft) {
81       level.MakeMapObject(ix-16, iy, 'oSpearsLeft');
82       firedLeft = firedMax;
83     }
84   } else {
85     if (!firedRight) {
86       level.MakeMapObject(ix+16, iy, 'oSpearsRight');
87       firedRight = firedMax;
88     }
89   }
93 // return `true` to stop checking
94 final bool checkTrapActivationSolid (MapTile obj) {
95   if (obj !isa MapTileSpearTrapBase && obj.solid && obj.moveable) {
96     int x = ix, y = iy;
97     if (abs(obj.iy-y) < prox && (obj.ix < x || obj.iy > x) && pointDistance(x, y, obj.ix, obj.iy) < range) {
98       activateTrap(atLeft:obj.ix < x);
99     }
100     return (firedLeft && firedRight);
101   }
102   return false;
106 // return `true` to stop checking
107 final bool checkTrapActivation (MapObject obj) {
108   if (firedLeft && firedRight) return true;
109   if (obj.spectral || !obj.isInstanceAlive) return false;
111   int x = ix, y = iy;
113   auto plr = PlayerPawn(obj);
114   if (plr) {
115     if (abs(plr.iy-y-8) < prox && (plr.ix < x || plr.ix > x+8) && pointDistance(x+8, y+8, plr.ix, plr.iy) < range) {
116       activateTrap(atLeft:plr.ix < x);
117     }
118     return (firedLeft && firedRight);
119   }
121   auto enemy = MapEnemy(obj);
122   if (enemy) {
123     if (abs(obj.iy-y) < prox && (obj.ix < x || obj.ix > x) && pointDistance(x, y, obj.ix, obj.iy) < range) {
124       activateTrap(atLeft:obj.ix < x);
125     }
126     return (firedLeft && firedRight);
127   }
129   auto item = MapItem(obj);
130   if (item) {
131     if (item.isTreasure) return false;
132     if (abs(obj.iy-y-8) < prox && (obj.ix < x+8 || obj.ix > x+8) && pointDistance(x+8, y+8, obj.ix, obj.iy) < range) {
133       activateTrap(atLeft:obj.ix < x+8);
134     }
135     return (firedLeft && firedRight);
136   }
138   return false;
142 override void thinkFrame () {
143   // remove floating top part after explosion
144   if (!level.isSolidAtPoint(ix+8, iy+16+8)) {
145     //TODO: remove spears
146     invincible = false;
147     smashMe();
148     instanceRemove();
149     return;
150   }
152   if (firedLeft > 0) --firedLeft;
153   if (firedRight > 0) --firedRight;
155   if (needToCheckForActivation) checkTrapActivation(level.player);
157   int x = ix, y = iy;
159   // left and right
160   if (needToCheckForActivation) {
161     level.isObjectInRect(x-range, y-range, range*2, range*2, &checkTrapActivation);
162   }
163   if (needToCheckForActivation) {
164     level.checkTilesInRect(x-range, y-range, range*2, range*2, &checkTrapActivationSolid);
165   }
167   /*+k8:???
168   if ((x > view_xview[0]-8 and x < view_xview[0] + view_wview[0]+8 and
169           y > view_yview[0]-8 and y < view_yview[0] + view_hview[0]+8))
170   {
171     if (not collision_point(x, y+16, oSolid, 0, 0)) instance_destroy();
172   }
173   */
177 defaultproperties {
178   desc = "Spear Trap";
179   desc2 = "A tribal trap with a set of sharp, extendable spears on each side. Should the top be destroyed, the bottom will continue to function.";
181   //hasThinker = true;
182   toSpecialGrid = true; // it need to think, so...
183   solid = true;
184   prox = 4;
185   invincible = false;
186   hideOre = true;
187   //!!!imageSpeed = 0.5; // this is for lit spear trap, it has 4 frames (not here yet)
188   // alarm[0] = 50;
189   //depth = 100;
190   rubbleSprite1 = 'sRubbleLush';
191   rubbleSprite2 = 'sRubbleLushSmall';
192   depth = 92;
196 // ////////////////////////////////////////////////////////////////////////// //
197 class MapTileSpearTrapTop['oSpearTrapTop'] : MapTileSpearTrapBase;
199 bool lit;
202 override void setupTile () {
203   ::setupTile();
204   if (global.cityOfGold == 1) {
205     spriteName = 'sSpearTrapGold1';
206     rightSpriteName = 'sSpearsRightGold';
207   }
211 defaultproperties {
212   objType = 'oSpearTrap';
213   imageSpeed = 0.5;
214   spriteName = 'sSpearTrap1';
215   rightSpriteName = 'sSpearsRight';
219 // ////////////////////////////////////////////////////////////////////////// //
220 class MapTileSpearTrapBottom['oSpearTrapBottom'] : MapTileSpearTrapBase;
223 override void setupTile () {
224   ::setupTile();
225   if (global.cityOfGold == 1) {
226     spriteName = 'sSpearTrapGold2';
227     rightSpriteName = 'sSpearsRightGold';
228   }
232 override void thinkFrame () {
233   if (global.darkLevel) {
234     auto upTrap = MapTileSpearTrapTop(level.checkTileAtPoint(ix, iy-16, delegate bool (MapTile t) { return (t isa MapTileSpearTrapTop); }, castClass:MapTileSpearTrapTop));
235     litWholeTile = (upTrap && upTrap.lit);
236   }
237   ::thinkFrame();
241 defaultproperties {
242   objType = 'oSpearTrap';
243   spriteName = 'sSpearTrap2';
244   rightSpriteName = 'sSpearsRight';
248 // ////////////////////////////////////////////////////////////////////////// //
249 class MapTileSpearTrapTopLit['oSpearTrapTopLit'] : MapTileSpearTrapTop;
251 defaultproperties {
252   lightRadius = 32;
253   objType = 'oSpearTrapLit';
254   spriteName = 'sSpearTrapLit';
255   lit = true;