tried to fix player death from falling rope (i still don't understand why it happens)
[k8vacspelynky.git] / mapent / items / rope.vc
blobd2a4b9be354383bd8d4e7201fa8ef005e35b9a4b
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 // rope throw
20 class ItemRopeThrow['oRopeThrow'] : MapItem;
22 int startY;
23 int px, py;
24 bool falling;
25 int fallCount;
26 // armed == true means "it is launched by a player"
28 override bool initialize () {
29   if (!::initialize()) return false;
30   setSprite('sRopeEnd');
31   return true;
35 override bool onExplosionTouch (MapObject xplo) {
36   onExploAffected = !falling;
37   return ::onExplosionTouch(xplo);
41 // return `true` to stop player from throwing it
42 override bool onTryUseItem (PlayerPawn plr) {
43   if (!plr./*kDown*/scrPlayerIsDucking() && plr.isCollisionTop(1)) {
44     // do nothing
45   } else {
46     plr.launchRope(plr./*kDown*/scrPlayerIsDucking(), doDrop:false);
47     plr.scrSwitchToPocketItem(forceIfEmpty:false);
48   }
49   return true; // don't throw
53 override void thinkFrame () {
54   if (heldBy) {
55     /*
56     xVel = 0;
57     yVel = 0;
58     xAcc = 0;
59     yAcc = 0;
60     setXY(
61       heldBy.fltx+(heldBy.dir == Dir.Left ? -4 : 4),
62       heldBy.flty+(heldBy.status == DUCKING && fabs(heldBy.xVel) < 2 ? 4 : 0));
63     */
64     return;
65   }
67   if (!falling) {
68     ::thinkFrame();
69     //basicPhysicsStep();
70     if (!isInstanceAlive) return;
71   }
73   if (armed || falling) {
74     // YASM 1.7 prevent upward flying armed rope getting snagged on corners
75     if (armed) {
76       moveSnap(16, 1);
77       if (px < fltx) {
78         shiftX(!level.isSolidAtPoint(ix-8, iy) ? -8 : 8);
79       } else {
80         shiftX(!level.isSolidAtPoint(ix+8, iy) ? 8 : -8);
81       }
83       // hit ceiling?
84       if (yVel < 0 && isCollisionTop(1)) {
85         //writeln("HIT!");
86         if (startY-iy < 32) {
87           armed = false;
88           startY = 0;
89         }
90         yVel = 0;
91       }
93       if (yVel >= 0) {
94         level.MakeMapObject(ix, iy, 'oRopeTop');
95         armed = false;
96         falling = true;
97         flying = true;
98         xVel = 0;
99         yVel = 0;
100       }
101     }
103     if (falling) {
104       armed = false;
105       safe = true; // so if won't hit a player
106       //visible = false;
107       xVel = 0;
108       yVel = 0;
109       shiftY(8);
110       fallCount += 1;
111       if (isCollisionBottom(1) || fallCount > 16) {
112         falling = false;
113         flying = false;
114         //?shiftY(-8);
115         instanceRemove();
116       } else {
117         level.MakeMapRopeTileAt(ix-8, iy);
118       }
119     }
120   }
124 defaultproperties {
125   objName = 'Rope';
126   objType = 'oRopeThrow';
127   desc = "Rope";
128   desc2 = "A long, sturdy length of rope.";
129   setCollisionBounds(-4, -4, 4, 4);
130   burnTimer = 0;
132   //flying = true; // no gravity
133   canHitEnemies = true;
134   armed = false;
135   falling = false;
136   fallCount = 0;
137   px = 0;
138   py = 0;
139   safe = true;
140   alarmDisarmSafe = 30; // prevent from hurting held damsel if thrown while falling
141   startY = 0; // prevent rope from hooking into wall when thrown from standing in confined space (see also scrUseItem, oPlayer1.Step Action)
142   canPickUp = true;
146 ////////////////////////////////////////////////////////////////////////////////
147 // rope top
148 class ItemRopeTop['oRopeTop'] : MapItem;
151 override bool initialize () {
152   if (!::initialize()) return false;
153   setSprite('sRopeTop');
154   return true;
158 override void thinkFrame () {
162 defaultproperties {
163   objName = 'Rope';
164   objType = 'oRopeTop';
165   desc = "Rope";
166   desc2 = "The top of a rope.";
167   setCollisionBounds(-4, -4, 4, 4);
168   flying = true; // no gravity
169   invincible = true;
170   bounce = false;
171   canBeHitByBullet = false;
172   canBeNudged = false;
173   canPickUp = false;