From e45d8730d951eecdd67be89a6aac659726ce28ea Mon Sep 17 00:00:00 2001 From: ketmar Date: Sun, 26 Aug 2018 04:04:22 +0000 Subject: [PATCH] unstuck dead bodies on drop, so you cannot put 'em in a wall anymore FossilOrigin-Name: 3325e6d23aac50d436ecbed51bca725c3fd761de7d336b21c681737e65621f29 --- PlayerPawn.vc | 87 ++++++++++++++++++++++++++++++++++++++++------- mapent/enemies/caveman.vc | 12 ++++--- spelunky_main.vc | 2 +- 3 files changed, 83 insertions(+), 18 deletions(-) diff --git a/PlayerPawn.vc b/PlayerPawn.vc index 289033c..69d264a 100644 --- a/PlayerPawn.vc +++ b/PlayerPawn.vc @@ -636,6 +636,72 @@ bool scrPickupItem (MapObject obj) { } +// ////////////////////////////////////////////////////////////////////////// // +//transient MapObject itck; +void unstuckDroppedObject (MapObject it) { + if (!it || !it.isInstanceAlive || it.width < 1 || it.height < 1) return; + + if (it isa MapEnemy) { + it.ix = ix+(dir == Dir.Left ? -8 : -4); + it.iy = iy-12; + } + + // prevent getting stuck in a wall + writeln("???STUCK: (", it.objType, "), hitbox=(", it.hitboxX, ",", it.hitboxY, ")-(", it.hitboxW, "x", it.hitboxH, ")"); + auto ospec = it.spectral; + it.spectral = true; + if (!it.isCollision()) { it.spectral = ospec; return; } + writeln("***STUCK! (", it.objType, ")"); + // unstuck it + auto ox = it.ix, oy = it.iy; + it.ix = ox; + it.iy = oy; + if (!it.isCollision()) { it.spectral = ospec; it.saveInterpData(); it.updateGrid(); return; } + /* + itck = it; + level.checkTilesInRect(it.x0, it.y0, width, height, delegate bool (MapTile t) { + if (t.solid) { + writeln("mypos=(", itck.x0, ",", itck.y0, ")-(", itck.x1, ",", itck.y1, "); tpos=(", t.x0, ",", t.y0, ")-(", t.x1, ",", t.y1, ")"); + } + return false; + }); + itck = none; + */ + foreach (int dy; 0..16) { + // only left-right + int dx = (dir == Dir.Left ? 1 : -1); + writeln(" only horizontal; dir=", dx); + it.ix = ox; + foreach (auto step; 1..16) { + it.ix = ox+dx*step; + if (!it.isCollision()) { writeln(" OK at dx=", dx); break; } + it.ix = ox-dx*step; + if (!it.isCollision()) { writeln(" OK at dx=-", dx); break; } + } + if (!it.isCollision()) break; + if (it.isCollisionBottom(0)) { + writeln(" slide up"); + it.iy = it.iy-1; + } else if (it.isCollisionTop(0)) { + writeln(" slide down"); + it.iy = it.iy+1; + } + } + if (it.isCollision()) { + writeln(" CANNOT UNSTUCK!"); + it.ix = ox; + it.iy = oy; + } else { + writeln(" MOVED BY (", it.ix-ox, ",", it.iy-oy, ")"); + if (it.isCollision()) FatalError("FUCK?!"); + } + it.spectral = ospec; + it.saveInterpData(); + it.updateGrid(); +} + + +// ////////////////////////////////////////////////////////////////////////// // // drop currently held item bool scrDropItem (LostCause cause, optional float xVel, optional float yVel) { if (holdItem isa PlayerWeapon) return false; @@ -658,6 +724,8 @@ bool scrDropItem (LostCause cause, optional float xVel, optional float yVel) { madeOffer = false; + unstuckDroppedObject(hi); + scrSwitchToPocketItem(forceIfEmpty:true); return true; } @@ -711,9 +779,8 @@ void scrUseThrowIt (MapObject it) { it.myGrav = 0.1; } - // prevent getting stuck in a wall + //unstuckDroppedObject(it); if (it.isCollision()) { - //foreach (; 0..8) if (level.isSolidAtPoint(ix-8, iy)) it.shiftX(1); if (it.xVel < 0) { if (level.isSolidAtPoint(it.ix-8, it.iy)) it.shiftX(8); } else if (it.xVel > 0) { @@ -727,16 +794,6 @@ void scrUseThrowIt (MapObject it) { } } } - /* - int dx = 1; - while (dx > 8 && it.isCollisionLeft(dx)) ++dx; - if (dx < 8) it.shiftX(8); - else { - dx = 1; - while (dx > 8 && it.isCollisionRight(dx)) ++dx; - if (dx < 8) it.shiftX(-8); - } - */ } /* @@ -819,10 +876,11 @@ void scrUsePutItOnGroundHelper (MapObject it, optional float xVelMult, optional it.xVel *= xVelMult; it.yVel = yVelNew; - //hi.fltx = ix; + it.fltx = ix; it.flty = iy+2; if (ItemGoldIdol(it)) it.flty = iy; + /* foreach (; 0..16) { if (it.isCollisionBottom(0) && !it.isCollisionTop(1)) { it.flty -= 1; @@ -842,6 +900,9 @@ void scrUsePutItOnGroundHelper (MapObject it, optional float xVelMult, optional break; } } + */ + + unstuckDroppedObject(it); } diff --git a/mapent/enemies/caveman.vc b/mapent/enemies/caveman.vc index 8f70998..87109e7 100644 --- a/mapent/enemies/caveman.vc +++ b/mapent/enemies/caveman.vc @@ -252,12 +252,12 @@ override void thinkFrame () { int x = ix, y = iy; - //if (collision_rectangle(x, y, x+16, y+16, oWeb, false, false)) inWeb = true; else inWeb = false; - inWeb = !!level.isObjectInRect(ix, iy, 17, 17, &level.cbIsObjectWeb); - if (status >= STUNNED) { imageSpeed = 0.5; - if (level.isSolidAtPoint(x+8, y+12)) { + if (level.isSolidAtPoint(x+8, y+8)) { + auto t = level.isSolidAtPoint(x+8, y+8); + writeln("!!!CAVEMAN IN A WALL(0): hitbox=(", hitboxX, ",", hitboxY, ")-(", hitboxW, "x", hitboxH, "); coll=", !!isCollision()); + writeln("mypos=(", x0, ",", y0, ")-(", x1, ",", y1, "); tpos=(", t.x0, ",", t.y0, ")-(", t.x1, ",", t.y1, ")"); spillBlood(); playSound('sndCavemanDie'); instanceRemove(); @@ -265,6 +265,7 @@ override void thinkFrame () { } } else if (!heldBy) { if (level.isSolidAtPoint(x+8, y+8)) { + writeln("!!!CAVEMAN IN A WALL(1): hitbox=(", hitboxX, ",", hitboxY, ")-(", hitboxW, "x", hitboxH, "); coll=", !!isCollision()); spillBlood(); playSound('sndCavemanDie'); instanceRemove(); @@ -272,6 +273,9 @@ override void thinkFrame () { } } + //if (collision_rectangle(x, y, x+16, y+16, oWeb, false, false)) inWeb = true; else inWeb = false; + inWeb = !!level.isObjectInRect(ix, iy, 17, 17, &level.cbIsObjectWeb); + if (status != DEAD && status != STUNNED && hp < 1) status = DEAD; if (colBot && status != STUNNED) yVel = 0; diff --git a/spelunky_main.vc b/spelunky_main.vc index a29c11a..185e841 100644 --- a/spelunky_main.vc +++ b/spelunky_main.vc @@ -2269,7 +2269,7 @@ void performTimeCheck () { void setupCheats () { - return; + //return; startMode = StartMode.Alive; global.currLevel = 13; -- 2.11.4.GIT