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 //TODO: laser and water should destory it too!
21 class ItemWeb['oWeb'] : MapItem;
24 override bool initialize () {
25 if (!::initialize()) return false;
31 // return `true` if tile was exploded
32 override bool onExplosionTouch (MapObject xplo) {
38 // return `false` to do standard weapon processing
39 override bool onTouchedByPlayerWeapon (PlayerPawn plr, PlayerWeapon wpn) {
40 life -= wpn.webDamage;
46 override void thinkFrame () {
47 imageAlpha = life/1200.0; //trunc(255-255.0*(life/1200.0));
48 if (dying) life -= 2; //0.02;
49 if (life <= 1) { instanceRemove(); return; }
51 if (isInstanceAlive && !spectral) {
53 level.forEachObjectInRect(x0, y0, width, height, &doObjectColAction);
59 override bool doObjectColAction (MapObject o) {
60 if (!isInstanceAlive) return true; // stop it, we are dead anyway
63 if (!o.collidesWith(self)) return false;
64 if (o.heldBy || o isa ItemRopeThrow || o isa ItemRopeTop) return false;
65 if (fabs(o.xVel) > 1) {
67 if (!dying && global.config.enemyBreakWeb) tear(0.1);
72 if (fabs(o.yVel) > 1) {
74 if (!dying && global.config.enemyBreakWeb) tear(0.1);
79 //!!!if (other.type == "Flare") life -= 0.5;
86 //return ::doObjectColAction(o);
91 void tear (float amount) {
92 if (amount <= 0) return;
93 life -= trunc(amount*100);
100 desc2 = "A sticky silk web.";
101 setCollisionBounds(0, 0, 16, 16);
107 // ////////////////////////////////////////////////////////////////////////// //
109 class ItemBones['oBones'] : MapItem;
112 override bool initialize () {
113 if (!::initialize()) return false;
114 setSprite('sBonesLeft');
119 override void thinkFrame () {
120 if (!isCollisionAtPoint(ix+8, iy+16)) {
125 if (isCollisionAtPoint(ix+8, iy+15)) {
133 objName = 'Bone Pile';
135 desc2 = "A pile of bones.";
136 setCollisionBounds(0, 0, 16, 16); // means nothing
141 // ////////////////////////////////////////////////////////////////////////// //
143 class ItemFakeBones['oFakeBones'] : MapItem;
144 //class ItemFakeBones['oFakeBones'] : replaces(ItemBones);
146 bool raisingSkeleton;
149 override bool initialize () {
150 if (!::initialize()) return false;
151 setSprite('sFakeBonesLeft');
152 writeln("*** FAKE BONES CREATED");
157 override void onAnimationLooped () {
158 if (raisingSkeleton) {
159 // animation complete, raise it
160 //writeln("*** FAKE BONES RAISING: COMPLETE");
161 level.MakeMapObject(ix, iy, 'oSkeleton');
167 override void thinkFrame () {
168 if (!isCollisionAtPoint(ix+8, iy+16)) {
173 if (isCollisionAtPoint(ix+8, iy+15)) {
178 if (level.player && !level.player.dead && !raisingSkeleton) {
179 if (abs(level.player.iy-(iy+8)) < 8 && abs(level.player.ix-(ix+8)) < 64) {
180 //writeln("*** FAKE BONES RAISING: STARTED");
181 //sprite_index = sSkeletonCreateL;
182 // this resets `imageLoopCount`
183 setSprite('sSkeletonCreateL');
184 raisingSkeleton = true;
191 objName = 'Bone Pile';
193 desc2 = "A pile of angry bones.";
194 setCollisionBounds(0, 0, 16, 16); // means nothing