/** * Try to move sideways while in a ledge. One can simply move to the sides, * around a block or toward a block. * * @param dir Relative direction of the movement (Left or Right) * @param innerTurn New direction when moving **toward** a block * @param outerTurn New direction when moving **around** a block * @param moveDir Base direction of sideways movement * @param moveDelay How long the movement should take */ private void tryMoveLedgeSide(RelPos dir, Dir innerTurn, Dir outerTurn, Dir moveDir, float moveDelay) { GO dirObj, frontDirObj, topDirObj; bool isWall, isInner; dirObj = this.getBlockAt(dir); frontDirObj = this.getBlockAt(RelPos.FrontSomething | dir); topDirObj = this.getBlockAt(RelPos.TopSomething | dir); isWall = (dirObj == null) && (frontDirObj != null); isInner = (dirObj != null); if (isWall && (topDirObj == null)) { Dir d = moveDir.toLocal(this.facing); this.move(d, moveDelay); } else if (isInner) { this.turn(innerTurn); } else { GO frontTopDirObj; bool isOuter; frontTopDirObj = this.getBlockAt(RelPos.FrontTopSomething | dir); isOuter = (dirObj == null) && (frontDirObj == null); if (isOuter && (frontTopDirObj == null) && (topDirObj == null)) { Dir d = moveDir.toLocal(this.facing) | Dir.Front.toLocal(this.facing); this.move(d, moveDelay); this.turn(outerTurn); } } }
public void TryPush(ref float delay, ref bool didPush, Dir d, GO ignored = null) { GO next = null; RelPos p; float localDelay; bool isShaking = false; this.issueEvent <IsShaking>((x, y) => x.Check(out isShaking)); if (isShaking) { /* Pushing while shaking causes a bug, so block it */ didPush = false; return; } /* Use the slowest movement */ if (this.moveDelay > delay) { localDelay = this.moveDelay; } else { localDelay = delay; } switch (d.toLocal(this.localDir)) { case Dir.Back: p = RelPos.Front; break; case Dir.Left: p = RelPos.Right; break; case Dir.Right: p = RelPos.Left; break; case Dir.Front: p = RelPos.Back; break; default: p = RelPos.None; break; } this.issueEvent <GetRelativeObject>( (x, y) => x.GetObjectAt(out next, p)); if (next != null && next != ignored) { bool localPush = false; /* Check whether the next object in this direction can be pushed */ this.issueEvent <PushController>( (x, y) => x.TryPush(ref localDelay, ref localPush, d), next); if (!localPush) { /* Since the object can't be pushed, bail out! */ didPush = false; return; } } /* Reaching this points means: * 1. That every touching object can be pushed * 2. That delay has the slowest movement * So just move the object */ this.issueEvent <MovementController>( (x, y) => x.Move(d, localDelay)); /* Assign the return variables */ delay = localDelay; didPush = true; }