more music fixes
[k8vacspelynky.git] / PlayerPowerup.vc
blobef418414dfc8131a1088a1fd9fa20194057fe856
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 // recoded by Ketmar // Invisible Vector
19 class PlayerPowerup : Object abstract;
21 name id;
22 PlayerPawn owner;
23 int renderPriority; // from lower to higher
24 bool lostOnDeath = true;
25 bool active;
26 bool prePreDucking; // for cape
29 // called when the player get it for the first time
30 bool onActivate () {
31   active = true;
32   return true;
36 // called when the player lost it (for some reason)
37 bool onDeactivate (optional bool forced) {
38   active = false;
39   return true;
43 void onPlayerDied () {
44   onDeactivate(forced:true);
48 void onPreThink () {
52 void onPostThink () {
56 void prePreDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
60 void preDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
64 void postDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
68 void lastDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
72 // ////////////////////////////////////////////////////////////////////////// //
73 class PPCape : PlayerPowerup;
75 bool visible;
76 int dx, dy;
77 name sprName;
78 bool beforePlayer;
79 bool open;
82 // called when the player get it for the first time
83 override bool onActivate () {
84   owner.global.hasCape = true;
85   visible = true;
86   active = true;
87   //open = false;
88   return true;
92 // called when the player lost it (for some reason)
93 override bool onDeactivate (optional bool forced) {
94   owner.global.hasCape = false;
95   visible = false;
96   active = false;
97   open = false;
98   return true;
102 override void onPostThink () {
103   visible = (owner.status != MapObject::DUCKTOHANG);
105   if (!owner.whipping && (owner.status == MapObject::CLIMBING || owner.isExitingSprite())) {
106     dx = 0;
107     dy = 4;
108     sprName = 'sCapeBack';
109     //depth = 0;
110     beforePlayer = true;
111   } else if (owner.dir == MapObject::Dir.Right) {
112     dx = -4;
113     dy = (owner.status == MapObject::DUCKING || owner.stunned ? 2 : -2);
114          if (open) sprName = 'sCapeUR';
115     else if (fabs(owner.xVel) > 0.4 && owner.status != MapObject::DUCKING) sprName = 'sCapeRight';
116     else sprName = 'sCapeDR';
117     //depth = 111;
118     beforePlayer = false;
119   } else {
120     // left
121     dx = 4;
122     dy = (owner.status == MapObject::DUCKING || owner.stunned ? 2 : -2);
123          if (open) sprName = 'sCapeUL';
124     else if (fabs(owner.xVel) > 0.4 && owner.status != MapObject::DUCKING) sprName = 'sCapeLeft';
125     else sprName = 'sCapeDL';
126     //depth = 111;
127     beforePlayer = false;
128   }
130   //writeln("CAPE: '", sprName, "'; before=", beforePlayer);
134 final void doDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
135   if (!sprName) return;
137   auto spr = owner.level.sprStore[sprName];
138   if (!spr || spr.frames.length < 1) return;
139   auto spf = spr.frames[0];
140   if (!spf || spf.width < 1 || spf.height < 1) return;
142   int xi, yi;
143   owner.getInterpCoords(currFrameDelta, scale, out xi, out yi);
145   xi += dx*scale;
146   yi += dy*scale;
148   xi -= spf.xofs*scale;
149   yi -= spf.yofs*scale;
151   spf.tex.blitAt(xi-xpos, yi-ypos, scale);
155 override void prePreDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
156   if (!visible || owner.status != MapObject::DUCKING) return;
157   doDrawWithOfs(xpos, ypos, scale, currFrameDelta);
161 override void preDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
162   if (!visible || beforePlayer || owner.status == MapObject::DUCKING) return;
163   doDrawWithOfs(xpos, ypos, scale, currFrameDelta);
167 override void lastDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
168   if (!visible || !beforePlayer) return;
169   doDrawWithOfs(xpos, ypos, scale, currFrameDelta);
173 defaultproperties {
174   id = 'Cape';
175   renderPriority = 1010; // behind the bricks
176   sprName = 'sCapeRight';
180 // ////////////////////////////////////////////////////////////////////////// //
181 class PPParachute : PlayerPowerup;
183 const int dx = -8;
184 const int dy = -16;
185 int imageFrame = 0;
186 bool opening;
188 // called when the player get it for the first time
189 override bool onActivate () {
190   active = true;
191   opening = true;
192   imageFrame = 0;
193   return true;
197 // called when the player lost it (for some reason)
198 override bool onDeactivate (optional bool forced) {
199   active = false;
200   return true;
204 override void onPostThink () {
205   if (opening) {
206     auto spr = owner.level.sprStore['sParaOpen'];
207     ++imageFrame;
208     if (imageFrame >= spr.frames.length) {
209       opening = false;
210       imageFrame = 0;
211     }
212   } else {
213     imageFrame = 0;
214   }
218 final void doDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
219   auto spr = owner.level.sprStore[opening ? 'sParaOpen' : 'sParachute'];
220   if (!spr || spr.frames.length < 1) return;
221   auto spf = spr.frames[imageFrame];
222   if (!spf || spf.width < 1 || spf.height < 1) return;
224   int xi, yi;
225   owner.getInterpCoords(currFrameDelta, scale, out xi, out yi);
227   xi += dx*scale;
228   yi += dy*scale;
230   xi -= spf.xofs*scale;
231   yi -= spf.yofs*scale;
233   spf.tex.blitAt(xi-xpos, yi-ypos, scale);
237 override void preDrawWithOfs (int xpos, int ypos, int scale, float currFrameDelta) {
238   doDrawWithOfs(xpos, ypos, scale, currFrameDelta);
242 defaultproperties {
243   id = 'Parachute';
244   renderPriority = 1010; // behind the bricks