Esempio n. 1
0
    /**
     * 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);
            }
        }
    }
Esempio n. 2
0
    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;
    }