예제 #1
0
        /// <summary>
        /// Process the next ACMD command in the queue.
        /// </summary>
        /// <returns>True if we should keep processing, False to stop
        /// for the rest of the frame.</returns>
        public bool processCommand(ICommand cmd)
        {
            Hitbox newHitbox = null;

            if (TrueFalseSkipLength > 0)
            {
                //Skip command since its on a true/false block and the variable is set to the other value
                TrueFalseSkipLength -= cmd.Parameters.Count + 1;
                return(true);
            }
            switch (cmd.Ident)
            {
            case 0x42ACFE7D:     // Asynchronous Timer, exact animation frame on which next command should run
            {
                float continueOnFrame = (float)cmd.Parameters[0];
                // A way of saying strictly greater than or equal to (>=) with better precision
                if (doubleEquals(currentFrame, continueOnFrame) || currentFrame > continueOnFrame)
                {
                    return(true);      // Timer finished, keep processing ACMD commands
                }
                return(false);         // Timer hasn't finished yet
            }

            case 0x4B7B6E51:     // Synchronous Timer, number of animation frames to wait until next command should run
            {
                // Formula from ASM is: stopAfterFrames - ((is_active * frameSpeed) + framesSinceSyncTimerStarted) > 0
                // THEN the timer has finished.

                if (framesSinceSyncTimerStarted < 0)
                {
                    // Interesting to note that the first encounter sets the frames to 0
                    // in the game's code, while subsequent timer encounters increment it.
                    // Thus a Synchronous_Timer(Frames=0) would always instantly finish.
                    framesSinceSyncTimerStarted = 0;
                }
                else
                {
                    framesSinceSyncTimerStarted += frameSpeed;
                }

                float  stopAfterFrames = (int)(float)cmd.Parameters[0];
                double framesPassed    = stopAfterFrames - framesSinceSyncTimerStarted;
                // A way of saying strictly greater than (>) with better precision
                if (!doubleEquals(framesPassed, 0d) && framesPassed > 0)
                {
                    return(false);         // Timer hasn't finished yet
                }
                // Timer finished, keep processing ACMD commands
                framesSinceSyncTimerStarted = -1;
                return(true);
            }

            case 0x7172A764:     // Set_Frame_Duration, sets Frame_Speed such that Arg0 ACMD frames are processed per in-game frame
            {
                if (Runtime.useFrameDuration)
                {
                    frameSpeed = 1 / (float)cmd.Parameters[0];
                }
                break;
            }

            case 0xB2E91D0C:     // Used in bayo scripts to set the Frame_Speed to a specific value
            {
                if (Runtime.useFrameDuration)
                {
                    frameSpeed = 1 / (float)cmd.Parameters[0];
                }
                break;
            }

            case 0xA546845C:     // Frame_Speed_Multiplier, sets Frame_Speed = Arg0
            {
                if (Runtime.useFrameDuration)
                {
                    frameSpeed = (float)cmd.Parameters[0];
                }
                break;
            }

            case 0x9126EBA2:     // Subroutine: call another script
            case 0xFA1BC28A:     // Subroutine1: call another script
                // Try and load the other script. If we can't, then just keep going as per normal
                uint crc = (uint)int.Parse(cmd.Parameters[0] + "");
                if (Runtime.Moveset.Game.Scripts.ContainsKey(crc))     //TODO:
                {
                    subscripts.Add((ACMDScript)Runtime.Moveset.Game.Scripts[crc]);

                    // Store the return scriptCommandIndex
                    scriptStates.Push(new ScriptState(
                                          scriptCommandIndex,
                                          loopStart,
                                          loopIterations
                                          ));

                    // Start fresh in the new script
                    scriptCommandIndex = -1;     // This is incremented immediately in the containing loop hence the -1
                    loopStart          = 0;
                    loopIterations     = 0;
                }
                break;

            case 0xB738EABD:     // hitbox
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type                 = Hitbox.HITBOX;
                newHitbox.Part                 = (int)cmd.Parameters[1];
                newHitbox.Bone                 = (int)cmd.Parameters[2];
                newHitbox.Damage               = (float)cmd.Parameters[3];
                newHitbox.Angle                = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth      = (int)cmd.Parameters[5];
                newHitbox.WeightBasedKnockback = (int)cmd.Parameters[6];
                newHitbox.KnockbackBase        = (int)cmd.Parameters[7];
                newHitbox.Size                 = (float)cmd.Parameters[8];
                newHitbox.X = (float)cmd.Parameters[9];
                newHitbox.Y = (float)cmd.Parameters[10];
                newHitbox.Z = (float)cmd.Parameters[11];
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0x2988D50F:     // Extended hitbox
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type                 = Hitbox.HITBOX;
                newHitbox.Part                 = (int)cmd.Parameters[1];
                newHitbox.Extended             = true;
                newHitbox.Bone                 = (int)cmd.Parameters[2];
                newHitbox.Damage               = (float)cmd.Parameters[3];
                newHitbox.Angle                = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth      = (int)cmd.Parameters[5];
                newHitbox.WeightBasedKnockback = (int)cmd.Parameters[6];
                newHitbox.KnockbackBase        = (int)cmd.Parameters[7];
                newHitbox.Size                 = (float)cmd.Parameters[8];
                newHitbox.X  = (float)cmd.Parameters[9];
                newHitbox.Y  = (float)cmd.Parameters[10];
                newHitbox.Z  = (float)cmd.Parameters[11];
                newHitbox.X2 = (float)cmd.Parameters[24];
                newHitbox.Y2 = (float)cmd.Parameters[25];
                newHitbox.Z2 = (float)cmd.Parameters[26];
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0x14FCC7E4:     // special hitbox
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type                 = Hitbox.HITBOX;
                newHitbox.Part                 = (int)cmd.Parameters[1];
                newHitbox.Bone                 = (int)cmd.Parameters[2];
                newHitbox.Damage               = (float)cmd.Parameters[3];
                newHitbox.Angle                = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth      = (int)cmd.Parameters[5];
                newHitbox.WeightBasedKnockback = (int)cmd.Parameters[6];
                newHitbox.KnockbackBase        = (int)cmd.Parameters[7];
                newHitbox.Size                 = (float)cmd.Parameters[8];
                newHitbox.X = (float)cmd.Parameters[9];
                newHitbox.Y = (float)cmd.Parameters[10];
                newHitbox.Z = (float)cmd.Parameters[11];
                newHitbox.FacingRestriction = (int)cmd.Parameters[34];
                if (cmd.Parameters.Count > 39)
                {
                    if ((int)cmd.Parameters[39] == 1)
                    {
                        newHitbox.Type = Hitbox.WINDBOX;
                    }
                }
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0x7075DC5A:     // Extended special hitbox
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type                 = Hitbox.HITBOX;
                newHitbox.Extended             = true;
                newHitbox.Part                 = (int)cmd.Parameters[1];
                newHitbox.Bone                 = (int)cmd.Parameters[2];
                newHitbox.Damage               = (float)cmd.Parameters[3];
                newHitbox.Angle                = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth      = (int)cmd.Parameters[5];
                newHitbox.WeightBasedKnockback = (int)cmd.Parameters[6];
                newHitbox.KnockbackBase        = (int)cmd.Parameters[7];
                newHitbox.Size                 = (float)cmd.Parameters[8];
                newHitbox.X = (float)cmd.Parameters[9];
                newHitbox.Y = (float)cmd.Parameters[10];
                newHitbox.Z = (float)cmd.Parameters[11];
                newHitbox.FacingRestriction = (int)cmd.Parameters[34];
                if ((int)cmd.Parameters[39] == 1)
                {
                    newHitbox.Type = Hitbox.WINDBOX;
                }
                newHitbox.X2 = (float)cmd.Parameters[40];
                newHitbox.Y2 = (float)cmd.Parameters[41];
                newHitbox.Z2 = (float)cmd.Parameters[42];
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0xCC7CC705:     // collateral hitbox (ignored by character being thrown)
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type                 = Hitbox.HITBOX;
                newHitbox.Part                 = (int)cmd.Parameters[1];
                newHitbox.Bone                 = (int)cmd.Parameters[2];
                newHitbox.Damage               = (float)cmd.Parameters[3];
                newHitbox.Angle                = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth      = (int)cmd.Parameters[5];
                newHitbox.WeightBasedKnockback = (int)cmd.Parameters[6];
                newHitbox.KnockbackBase        = (int)cmd.Parameters[7];
                newHitbox.Size                 = (float)cmd.Parameters[8];
                newHitbox.X = (float)cmd.Parameters[9];
                newHitbox.Y = (float)cmd.Parameters[10];
                newHitbox.Z = (float)cmd.Parameters[11];

                newHitbox.Ignore_Throw = true;

                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0xED67D5DA:     // Extended collateral hitbox (ignored by character being thrown)
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type                 = Hitbox.HITBOX;
                newHitbox.Extended             = true;
                newHitbox.Part                 = (int)cmd.Parameters[1];
                newHitbox.Bone                 = (int)cmd.Parameters[2];
                newHitbox.Damage               = (float)cmd.Parameters[3];
                newHitbox.Angle                = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth      = (int)cmd.Parameters[5];
                newHitbox.WeightBasedKnockback = (int)cmd.Parameters[6];
                newHitbox.KnockbackBase        = (int)cmd.Parameters[7];
                newHitbox.Size                 = (float)cmd.Parameters[8];
                newHitbox.X  = (float)cmd.Parameters[9];
                newHitbox.Y  = (float)cmd.Parameters[10];
                newHitbox.Z  = (float)cmd.Parameters[11];
                newHitbox.X2 = (float)cmd.Parameters[24];
                newHitbox.Y2 = (float)cmd.Parameters[25];
                newHitbox.Z2 = (float)cmd.Parameters[26];

                newHitbox.Ignore_Throw = true;

                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0x9245E1A8:     // clear all hitboxes
                Hitboxes.Clear();
                break;

            case 0xFF379EB6:     // delete hitbox
                if (Hitboxes.ContainsKey((int)cmd.Parameters[0]))
                {
                    Hitboxes.Remove((int)cmd.Parameters[0]);
                }
                break;

            case 0x7698BB42:     // deactivate previous hitbox
                Hitboxes.RemoveAt(Hitboxes.Keys.Max());
                break;

            case 0x684264C9:     // Change_Hitbox_Size
            {
                int    id             = (int)cmd.Parameters[0];
                float  size           = (float)cmd.Parameters[1];
                Hitbox hitboxToChange = null;
                if (Hitboxes.TryGetValue(id, out hitboxToChange))
                {
                    hitboxToChange.Size = size;
                }
                else
                {
                    Console.WriteLine($"Could not find hitbox with ID={id} to change size");
                }
                break;
            }

            case 0xDFA4517A:     // Change_Hitbox_Damage
            {
                int    id             = (int)cmd.Parameters[0];
                float  damage         = (float)cmd.Parameters[1];
                Hitbox hitboxToChange = null;
                if (Hitboxes.TryGetValue(id, out hitboxToChange))
                {
                    hitboxToChange.Damage = damage;
                }
                else
                {
                    Console.WriteLine($"Could not find hitbox with ID={id} to change damage");
                }
                break;
            }

            case 0x1AFDA8E6:     // Move_Hitbox
            {
                int    id             = (int)cmd.Parameters[0];
                Hitbox hitboxToChange = null;
                if (Hitboxes.TryGetValue(id, out hitboxToChange))
                {
                    hitboxToChange.Bone = (int)cmd.Parameters[1];
                    hitboxToChange.X    = (float)cmd.Parameters[2];
                    hitboxToChange.Y    = (float)cmd.Parameters[3];
                    hitboxToChange.Z    = (float)cmd.Parameters[4];
                }
                else
                {
                    Console.WriteLine($"Could not find hitbox with ID={id} to move position");
                }
                break;
            }

            case 0xEB375E3:     // Set Loop
                loopIterations = int.Parse(cmd.Parameters[0] + "") - 1;
                loopStart      = scriptCommandIndex;
                break;

            case 0x38A3EC78:     // goto
                if (loopIterations > 0)
                {
                    scriptCommandIndex = loopStart;
                    loopIterations    -= 1;
                }
                break;

            case 0x7B48FE1C:     //Extended Grabbox
            case 0x1EAF840C:     //Grabbox 2 (most command grabs)
            case 0x548F2D4C:     //Grabbox (used in tether grabs)
            case 0xEF787D43:     //Extended Grabbox 2 (Mega Man's grab)
            case 0x323FB9D4:     //Special Grabbox (Pikmin's grab)
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type = Hitbox.GRABBOX;
                newHitbox.Bone = int.Parse(cmd.Parameters[1] + "");
                newHitbox.Size = (float)cmd.Parameters[2];
                newHitbox.X    = (float)cmd.Parameters[3];
                newHitbox.Y    = (float)cmd.Parameters[4];
                newHitbox.Z    = (float)cmd.Parameters[5];

                if (cmd.Parameters.Count > 10)
                {
                    newHitbox.X2       = float.Parse(cmd.Parameters[8] + "");
                    newHitbox.Y2       = float.Parse(cmd.Parameters[9] + "");
                    newHitbox.Z2       = float.Parse(cmd.Parameters[10] + "");
                    newHitbox.Extended = true;
                }

                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0xF3A464AC:     // Terminate_Grab_Collisions
            {
                List <int> toDelete = new List <int>();
                foreach (KeyValuePair <int, Hitbox> kvp in Hitboxes)
                {
                    if (kvp.Value.Type == Hitbox.GRABBOX)
                    {
                        toDelete.Add(kvp.Key);
                    }
                }
                foreach (int index in toDelete)
                {
                    Hitboxes.Remove(index);
                }
                break;
            }

            case 0x2F08F54F:     // Delete_Catch_Collision by ID
                int idToDelete = (int)cmd.Parameters[0];
                if (Hitboxes[idToDelete].Type == Hitbox.GRABBOX)
                {
                    Hitboxes.Remove(idToDelete);
                }
                break;

            case 0x44081C21:     //SEARCH
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                if (Hitboxes.ContainsKey(id))
                {
                    Hitboxes.Remove(id);
                }
                newHitbox.Type = Hitbox.SEARCHBOX;
                newHitbox.Bone = (int)cmd.Parameters[2];

                newHitbox.Size = (float)cmd.Parameters[3];
                newHitbox.X    = (float)cmd.Parameters[4];
                newHitbox.Y    = (float)cmd.Parameters[5];
                newHitbox.Z    = (float)cmd.Parameters[6];
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0xCD0C1CC9:     //Bat Within (it clears WT SEARCH event)
            case 0x98203AF6:     //SRH_CLEAR_ALL
            {
                List <int> toDelete = new List <int>();
                foreach (KeyValuePair <int, Hitbox> kvp in Hitboxes)
                {
                    if (kvp.Value.Type == Hitbox.SEARCHBOX)
                    {
                        toDelete.Add(kvp.Key);
                    }
                }
                foreach (int index in toDelete)
                {
                    Hitboxes.Remove(index);
                }
                break;
            }

            case 0xFAA85333:
                break;

            case 0x321297B0:
                break;

            case 0x7640AEEB:
                break;

            case 0xF13BFE8D:     //Bone collision state (intangibility/invincibility)
            {
                int bone  = (int)cmd.Parameters[0];
                int state = (int)cmd.Parameters[1];
                switch (state)
                {
                case 2:
                    IntangibleBones.Remove(bone);
                    InvincibleBones.Remove(bone);
                    IntangibleBones.Add(bone);
                    break;

                case 1:
                    IntangibleBones.Remove(bone);
                    InvincibleBones.Remove(bone);
                    InvincibleBones.Add(bone);
                    break;

                default:
                    IntangibleBones.Remove(bone);
                    InvincibleBones.Remove(bone);
                    break;
                }
                break;
            }

            case 0xCEDC237E:     //Undo Bone collision state
            {
                int state = (int)cmd.Parameters[0];
                IntangibleBones.Clear();
                InvincibleBones.Clear();
                break;
            }

            case 0xF0D25BDA:     //Body_Collision (Full intangibility/invincibility)
            {
                int state = (int)cmd.Parameters[0];
                switch (state)
                {
                case 2:
                    BodyInvincible = false;
                    BodyIntangible = true;
                    break;

                case 1:
                    BodyInvincible = true;
                    BodyIntangible = false;
                    break;

                default:
                    BodyInvincible = false;
                    BodyIntangible = false;
                    break;
                }
                break;
            }

            case 0x2A25155D:     // Set_armor - super armor
            {
                int state = (int)cmd.Parameters[0];
                if (state == 1)
                {
                    SuperArmor = true;
                }
                else
                {
                    SuperArmor = false;
                }
                break;
            }

            case 0x661B30DA:     // Bit_Variable_Set
            {
                uint flag = (uint)((int)cmd.Parameters[0]);
                if (!ActiveFlags.Contains(flag))
                {
                    ActiveFlags.Add(flag);
                }
                break;
            }

            case 0x17232732:     // Bit_Variable_Clear
            {
                uint flag = (uint)((int)cmd.Parameters[0]);
                ActiveFlags.Remove(flag);
                break;
            }

            case 0xA21BC6EA:     //If_Bit_Is_Set
            case 0x34BCD3F7:     //If_Compare
            {
                if (IfVariableList.ContainsKey((uint)(int)cmd.Parameters[0]))
                {
                    readTrue = IfVariableList[(uint)(int)cmd.Parameters[0]];
                }
                break;
            }

            case 0x477705C2:     //unk_477705C2 If_Compare2?
            {
                if (IfVariableValueList.ContainsKey((uint)(int)cmd.Parameters[0]))
                {
                    readTrue = IfVariableValueList[(uint)(int)cmd.Parameters[0]] == (int)cmd.Parameters[2];
                }
                break;
            }

            case 0xA5BD4F32:     // TRUE
            {
                if (!readTrue)
                {
                    TrueFalseSkipLength = (int)cmd.Parameters[0] - 4;
                    if (TrueFalseSkipLength == 0)
                    {
                        TrueFalseSkipLength = 1;
                    }
                }
                break;
            }

            case 0x895B9275:     // FALSE
            {
                if (readTrue)
                {
                    TrueFalseSkipLength = (int)cmd.Parameters[0] - 2;
                    if (TrueFalseSkipLength == 0)
                    {
                        TrueFalseSkipLength = 1;
                    }
                }
                break;
            }

            case 0x0F39EC70:     // Allow/Disallow Ledgegrab
            {
                int type = (int)cmd.Parameters[0];
                switch (type)
                {
                case 0:
                    LedgeGrabDisallowed     = true;
                    FrontLedgeGrabAllowed   = false;
                    ReverseLedgeGrabAllowed = false;
                    break;

                case 1:
                    LedgeGrabDisallowed   = false;
                    FrontLedgeGrabAllowed = true;
                    break;

                case 2:
                    LedgeGrabDisallowed     = false;
                    ReverseLedgeGrabAllowed = true;
                    break;
                }
                break;
            }
            }
            return(true);
        }
예제 #2
0
        public int processScriptCommandsAtCurrentFrame(ICommand cmd, int halt, ref int scriptCommandIndex)
        {
            Hitbox newHitbox = null;

            switch (cmd.Ident)
            {
            case 0x42ACFE7D:     // Asynchronous Timer (specific frame start for next commands)
            {
                int frame = (int)(float)cmd.Parameters[0];
                halt = frame >= halt + 2 ? frame - 2 : halt;
                break;
            }

            case 0x4B7B6E51:     // Synchronous Timer (relative frame start for next commands)
            {
                halt += (int)(float)cmd.Parameters[0];
                break;
            }

            case 0xB738EABD:     // hitbox
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type            = Hitbox.HITBOX;
                newHitbox.Bone            = (int)cmd.Parameters[2];
                newHitbox.Damage          = (float)cmd.Parameters[3];
                newHitbox.Angle           = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth = (int)cmd.Parameters[5];
                //FKB = (float)cmd.Parameters[6]
                newHitbox.KnockbackBase = (int)cmd.Parameters[7];
                newHitbox.Size          = (float)cmd.Parameters[8];
                newHitbox.X             = (float)cmd.Parameters[9];
                newHitbox.Y             = (float)cmd.Parameters[10];
                newHitbox.Z             = (float)cmd.Parameters[11];
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0x2988D50F:     // Extended hitbox
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type            = Hitbox.HITBOX;
                newHitbox.Extended        = true;
                newHitbox.Bone            = (int)cmd.Parameters[2];
                newHitbox.Damage          = (float)cmd.Parameters[3];
                newHitbox.Angle           = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth = (int)cmd.Parameters[5];
                //FKB = (float)cmd.Parameters[6]
                newHitbox.KnockbackBase = (int)cmd.Parameters[7];
                newHitbox.Size          = (float)cmd.Parameters[8];
                newHitbox.X             = (float)cmd.Parameters[9];
                newHitbox.Y             = (float)cmd.Parameters[10];
                newHitbox.Z             = (float)cmd.Parameters[11];
                newHitbox.X2            = (float)cmd.Parameters[24];
                newHitbox.Y2            = (float)cmd.Parameters[25];
                newHitbox.Z2            = (float)cmd.Parameters[26];
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0x14FCC7E4:     // special hitbox
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type            = Hitbox.HITBOX;
                newHitbox.Bone            = (int)cmd.Parameters[2];
                newHitbox.Damage          = (float)cmd.Parameters[3];
                newHitbox.Angle           = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth = (int)cmd.Parameters[5];
                //FKB = (float)cmd.Parameters[6]
                newHitbox.KnockbackBase = (int)cmd.Parameters[7];
                newHitbox.Size          = (float)cmd.Parameters[8];
                newHitbox.X             = (float)cmd.Parameters[9];
                newHitbox.Y             = (float)cmd.Parameters[10];
                newHitbox.Z             = (float)cmd.Parameters[11];
                if (cmd.Parameters.Count > 39)
                {
                    if ((int)cmd.Parameters[39] == 1)
                    {
                        newHitbox.Type = Hitbox.WINDBOX;
                    }
                }
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0x7075DC5A:     // Extended special hitbox
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type            = Hitbox.HITBOX;
                newHitbox.Extended        = true;
                newHitbox.Bone            = (int)cmd.Parameters[2];
                newHitbox.Damage          = (float)cmd.Parameters[3];
                newHitbox.Angle           = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth = (int)cmd.Parameters[5];
                //FKB = (float)cmd.Parameters[6]
                newHitbox.KnockbackBase = (int)cmd.Parameters[7];
                newHitbox.Size          = (float)cmd.Parameters[8];
                newHitbox.X             = (float)cmd.Parameters[9];
                newHitbox.Y             = (float)cmd.Parameters[10];
                newHitbox.Z             = (float)cmd.Parameters[11];
                if ((int)cmd.Parameters[39] == 1)
                {
                    newHitbox.Type = Hitbox.WINDBOX;
                }
                newHitbox.X2 = (float)cmd.Parameters[40];
                newHitbox.Y2 = (float)cmd.Parameters[41];
                newHitbox.Z2 = (float)cmd.Parameters[42];
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0xCC7CC705:     // collateral hitbox (ignored by character being thrown)
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type            = Hitbox.HITBOX;
                newHitbox.Bone            = (int)cmd.Parameters[2];
                newHitbox.Damage          = (float)cmd.Parameters[3];
                newHitbox.Angle           = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth = (int)cmd.Parameters[5];
                //FKB = (float)cmd.Parameters[6]
                newHitbox.KnockbackBase = (int)cmd.Parameters[7];
                newHitbox.Size          = (float)cmd.Parameters[8];
                newHitbox.X             = (float)cmd.Parameters[9];
                newHitbox.Y             = (float)cmd.Parameters[10];
                newHitbox.Z             = (float)cmd.Parameters[11];

                newHitbox.Ignore_Throw = true;

                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0xED67D5DA:     // Extended collateral hitbox (ignored by character being thrown)
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type            = Hitbox.HITBOX;
                newHitbox.Extended        = true;
                newHitbox.Bone            = (int)cmd.Parameters[2];
                newHitbox.Damage          = (float)cmd.Parameters[3];
                newHitbox.Angle           = (int)cmd.Parameters[4];
                newHitbox.KnockbackGrowth = (int)cmd.Parameters[5];
                //FKB = (float)cmd.Parameters[6]
                newHitbox.KnockbackBase = (int)cmd.Parameters[7];
                newHitbox.Size          = (float)cmd.Parameters[8];
                newHitbox.X             = (float)cmd.Parameters[9];
                newHitbox.Y             = (float)cmd.Parameters[10];
                newHitbox.Z             = (float)cmd.Parameters[11];
                newHitbox.X2            = (float)cmd.Parameters[24];
                newHitbox.Y2            = (float)cmd.Parameters[25];
                newHitbox.Z2            = (float)cmd.Parameters[26];

                newHitbox.Ignore_Throw = true;

                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0x9245E1A8:     // clear all hitboxes
                Hitboxes.Clear();
                break;

            case 0xFF379EB6:     // delete hitbox
                if (Hitboxes.ContainsKey((int)cmd.Parameters[0]))
                {
                    Hitboxes.Remove((int)cmd.Parameters[0]);
                }
                break;

            case 0x7698BB42:     // deactivate previous hitbox
                Hitboxes.Remove(Hitboxes.Keys.Max());
                break;

            case 0xEB375E3:     // Set Loop
                iterations = int.Parse(cmd.Parameters[0] + "") - 1;
                setLoop    = scriptCommandIndex;
                break;

            case 0x38A3EC78:     // goto
                if (iterations > 0)
                {
                    // Can fail if a subscript has a goto with no loop starter
                    scriptCommandIndex = setLoop;
                    iterations        -= 1;
                }
                break;

            case 0x7B48FE1C:     //Extended Grabbox
            case 0x1EAF840C:     //Grabbox 2 (most command grabs)
            case 0x548F2D4C:     //Grabbox (used in tether grabs)
            case 0xEF787D43:     //Extended Grabbox 2 (Mega Man's grab)
            case 0x323FB9D4:     //Special Grabbox (Pikmin's grab)
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                newHitbox.Type = Hitbox.GRABBOX;
                newHitbox.Bone = int.Parse(cmd.Parameters[1] + "");
                newHitbox.Size = (float)cmd.Parameters[2];
                newHitbox.X    = (float)cmd.Parameters[3];
                newHitbox.Y    = (float)cmd.Parameters[4];
                newHitbox.Z    = (float)cmd.Parameters[5];

                if (cmd.Parameters.Count > 10)
                {
                    newHitbox.X2       = float.Parse(cmd.Parameters[8] + "");
                    newHitbox.Y2       = float.Parse(cmd.Parameters[9] + "");
                    newHitbox.Z2       = float.Parse(cmd.Parameters[10] + "");
                    newHitbox.Extended = true;
                }

                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0xF3A464AC:     // Terminate_Grab_Collisions
            {
                List <int> toDelete = new List <int>();
                foreach (KeyValuePair <int, Hitbox> kvp in Hitboxes)
                {
                    if (kvp.Value.Type == Hitbox.GRABBOX)
                    {
                        toDelete.Add(kvp.Key);
                    }
                }
                foreach (int index in toDelete)
                {
                    Hitboxes.Remove(index);
                }
                break;
            }

            case 0x2F08F54F:     // Delete_Catch_Collision by ID
                int idToDelete = (int)cmd.Parameters[0];
                if (Hitboxes[idToDelete].Type == Hitbox.GRABBOX)
                {
                    Hitboxes.Remove(idToDelete);
                }
                break;

            case 0x44081C21:     //SEARCH
            {
                newHitbox = new Hitbox();
                int id = (int)cmd.Parameters[0];
                if (Hitboxes.ContainsKey(id))
                {
                    Hitboxes.Remove(id);
                }
                newHitbox.Type = Hitbox.SEARCHBOX;
                newHitbox.Bone = (int)cmd.Parameters[2];

                newHitbox.Size = (float)cmd.Parameters[3];
                newHitbox.X    = (float)cmd.Parameters[4];
                newHitbox.Y    = (float)cmd.Parameters[5];
                newHitbox.Z    = (float)cmd.Parameters[6];
                addOrOverwriteHitbox(id, newHitbox);
                break;
            }

            case 0xCD0C1CC9:     //Bat Within (it clears WT SEARCH event)
            case 0x98203AF6:     //SRH_CLEAR_ALL
            {
                List <int> toDelete = new List <int>();
                foreach (KeyValuePair <int, Hitbox> kvp in Hitboxes)
                {
                    if (kvp.Value.Type == Hitbox.SEARCHBOX)
                    {
                        toDelete.Add(kvp.Key);
                    }
                }
                foreach (int index in toDelete)
                {
                    Hitboxes.Remove(index);
                }
                break;
            }

            case 0xFA1BC28A:     //Subroutine1: call another script
                halt = processSubscriptCommandsAtCurrentFrame((uint)int.Parse(cmd.Parameters[0] + ""), halt, scriptCommandIndex);
                break;

            case 0xFAA85333:
                break;

            case 0x321297B0:
                break;

            case 0x7640AEEB:
                break;

            case 0xA5BD4F32:     // TRUE
                break;

            case 0x895B9275:     // FALSE
                break;

            case 0xF13BFE8D:     //Bone collision state (intangibility/invincibility)
            {
                int bone  = VBN.applyBoneThunk((int)cmd.Parameters[0]);
                int state = (int)cmd.Parameters[1];
                switch (state)
                {
                case 2:
                    IntangibleBones.Remove(bone);
                    InvincibleBones.Remove(bone);
                    IntangibleBones.Add(bone);
                    break;

                case 1:
                    IntangibleBones.Remove(bone);
                    InvincibleBones.Remove(bone);
                    InvincibleBones.Add(bone);
                    break;

                default:
                    IntangibleBones.Remove(bone);
                    InvincibleBones.Remove(bone);
                    break;
                }
                break;
            }

            case 0xCEDC237E:     //Undo Bone collision state
            {
                int state = (int)cmd.Parameters[0];
                IntangibleBones.Clear();
                InvincibleBones.Clear();
                break;
            }

            case 0xF0D25BDA:     //Body_Collision (Full intangibility/invincibility)
            {
                int state = (int)cmd.Parameters[0];
                switch (state)
                {
                case 2:
                    BodyInvincible = false;
                    BodyIntangible = true;
                    break;

                case 1:
                    BodyInvincible = true;
                    BodyIntangible = false;
                    break;

                default:
                    BodyInvincible = false;
                    BodyIntangible = false;
                    break;
                }
                break;
            }
            }

            if (newHitbox != null)
            {
                newHitbox.Bone = VBN.applyBoneThunk(newHitbox.Bone);
            }
            return(halt);
        }