NScumm.Sky.Logic.ArAnim C# (CSharp) Method

ArAnim() private method

private ArAnim ( ) : void
return void
        private void ArAnim()
        {
            // Follow a route
            // Mega should be in getToMode

            // only check collisions on character boundaries
            if (((_compact.Core.xcood & 7) != 0) || ((_compact.Core.ycood & 7) != 0))
            {
                MainAnim();
                return;
            }

            // On character boundary. Have we been told to wait?
            // if not - are WE colliding?

            if (_compact.Core.waitingFor == 0xffff)
            { // 1st cycle of re-route does not require collision checks
                MainAnim();
                return;
            }

            if (_compact.Core.waitingFor != 0)
            {
                // ok, we've been told we've hit someone
                // we will wait until we are no longer colliding
                // with them. here we check to see if we are (still) colliding.
                // if we are then run the stop script. if not clear the flag
                // and continue.

                // remember - this could be the first ar cycle for some time,
                // we might have been told to wait months ago. if we are
                // waiting for one person then another hits us then
                // c_waiting_for will be replaced by the new mega - this is
                // fine because the later collision will almost certainly
                // take longer to clear than the earlier one.

                if (Collide(_skyCompact.FetchCpt(_compact.Core.waitingFor)))
                {
                    StopAndWait();
                    return;
                }

                // we are not in fact hitting this person so clr & continue
                // it must have registered some time ago

                _compact.Core.waitingFor = 0; // clear id flag
            }

            // ok, our turn to check for collisions

            var logicList = new UShortAccess(_skyCompact.FetchCptRaw((ushort)_scriptVariables[LOGIC_LIST_NO]), 0);
            ushort id;

            while ((id = logicList[0]) != 0)
            { // get an id

                logicList.Offset += 2;
                if (id == 0xffff)
                { // address change?
                    logicList = new UShortAccess(_skyCompact.FetchCptRaw(logicList[0]), 0); // get new logic list
                    continue;
                }

                if (id == (ushort)(_scriptVariables[CUR_ID] & 0xffff)) // is it us?
                    continue;

                _scriptVariables[HIT_ID] = id; // save target id for any possible c_mini_bump
                var cpt = _skyCompact.FetchCpt(id);

                if ((cpt.Core.status & (1 << ST_COLLISION_BIT)) == 0) // can it collide?
                    continue;

                if (cpt.Core.screen != _compact.Core.screen) // is it on our screen?
                    continue;

                if (Collide(cpt))
                { // check for a hit
                  // ok, we've hit a mega
                  // is it moving... or something else?

                    if (cpt.Core.logic != L_AR_ANIM)
                    { // check for following route
                      // it is doing something else
                      // we restart our get-to script
                      // first tell it to wait for us - in case it starts moving
                      // ( *it may have already hit us and stopped to wait )

                        _compact.Core.waitingFor = 0xffff; // effect 1 cycle collision skip
                                                           // tell it it is waiting for us
                        cpt.Core.waitingFor = (ushort)(_scriptVariables[CUR_ID] & 0xffff);
                        // restart current script
                        SkyCompact.GetSub(_compact, _compact.Core.mode + 2).Field = 0;
                        _compact.Core.logic = L_SCRIPT;
                        LogicScript();
                        return;
                    }

                    Script(_compact.Core.miniBump, 0);
                    return;
                }
            }

            // ok, there was no collisions
            // now check for interaction request
            // *note: the interaction is always set up as an action script

            if (_compact.Core.request != 0)
            {
                _compact.Core.mode = C_ACTION_MODE; // put into action mode
                _compact.Core.actionSub = _compact.Core.request;
                _compact.Core.actionSub_off = 0;
                _compact.Core.request = 0; // trash request
                _compact.Core.logic = L_SCRIPT;
                LogicScript();
                return;
            }

            // any flag? - or any change?
            // if change then re-run the current script, which must be
            // a position independent get-to		 ----

            if (_compact.Core.atWatch == 0)
            { // any flag set?
                MainAnim();
                return;
            }

            // ok, there is an at watch - see if it's changed

            if (_compact.Core.atWas == _scriptVariables[_compact.Core.atWatch / 4])
            { // still the same?
                MainAnim();
                return;
            }

            // changed so restart the current script
            // *not suitable for base initiated ARing
            SkyCompact.GetSub(_compact, _compact.Core.mode + 2).Field = 0;

            _compact.Core.logic = L_SCRIPT;
            LogicScript();
        }
Logic