1 /**********************************************************************************
2 * Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
3 * Copyright (c) 2010, Moloch
4 * Copyright (c) 2018, Ketmar Dark
6 * This file is part of Spelunky.
8 * You can redistribute and/or modify Spelunky, including its source code, under
9 * the terms of the Spelunky User License.
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.
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/>
18 **********************************************************************************/
20 class ItemRopeThrow['oRopeThrow'] : MapItem;
26 // armed == true means "it is launched by a player"
28 override bool initialize () {
29 if (!::initialize()) return false;
30 setSprite('sRopeEnd');
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)) {
46 plr.launchRope(plr./*kDown*/scrPlayerIsDucking(), doDrop:false);
47 plr.scrSwitchToPocketItem(forceIfEmpty:false);
49 return true; // don't throw
53 override void thinkFrame () {
61 heldBy.fltx+(heldBy.dir == Dir.Left ? -4 : 4),
62 heldBy.flty+(heldBy.status == DUCKING && fabs(heldBy.xVel) < 2 ? 4 : 0));
70 if (!isInstanceAlive) return;
73 if (armed || falling) {
74 // YASM 1.7 prevent upward flying armed rope getting snagged on corners
78 shiftX(!level.isSolidAtPoint(ix-8, iy) ? -8 : 8);
80 shiftX(!level.isSolidAtPoint(ix+8, iy) ? 8 : -8);
84 if (yVel < 0 && isCollisionTop(1)) {
94 level.MakeMapObject(ix, iy, 'oRopeTop');
105 safe = true; // so if won't hit a player
111 if (isCollisionBottom(1) || fallCount > 16) {
117 level.MakeMapRopeTileAt(ix-8, iy);
126 objType = 'oRopeThrow';
128 desc2 = "A long, sturdy length of rope.";
129 setCollisionBounds(-4, -4, 4, 4);
132 //flying = true; // no gravity
133 canHitEnemies = 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)
146 ////////////////////////////////////////////////////////////////////////////////
148 class ItemRopeTop['oRopeTop'] : MapItem;
151 override bool initialize () {
152 if (!::initialize()) return false;
153 setSprite('sRopeTop');
158 override void thinkFrame () {
164 objType = 'oRopeTop';
166 desc2 = "The top of a rope.";
167 setCollisionBounds(-4, -4, 4, 4);
168 flying = true; // no gravity
171 canBeHitByBullet = false;