예제 #1
0
        public void RunEvent(int eventIndex)
        {
            //Get the current event and its id
            Event e = this[eventIndex];
            if (e == null)
                return;

            uint eventId = e.EventID;
            byte eNameSpace = e.NameSpace;
            byte eID = e.ID;
            byte eCount = (byte)e.Count;
            byte eUnk = e.Unknown;

            //Get raw parameter list
            int[] p = e.Select(x => x.Data).ToArray();

            //Run event only if allowed or if an exception
            if (!_runEvents && !_runExceptions.Contains((eNameSpace << 8) | eID))
                return;

            //Variables that are used often
            int id;
            Script script;
            Event ev;
            int index;
            ArticleInfo articleInfo;
            HitBox hitbox;
            RequirementInfo reqInfo;
            ActionChangeInfo aChangeInfo;
            SubActionChangeInfo sChangeInfo;

            //Code what to do for each event here!
            switch (eventId)
            {
                case 0x01000000: //Loop Rest 1 for Goto
                    Application.DoEvents();
                    break;
                case 0x00010100: //Synchronous Timer
                    _waitFrames = (int)(e[0].RealValue + 0.5f);
                    break;
                case 0x00020000: //No Operation
                    break;
                case 0x00020100: //Asynchronous Timer
                    _waitFrames = Math.Max((int)(e[0].RealValue + 0.5f) - _frameIndex, 0);
                    break;
                case 0x00040100: //Set loop data
                    _loopCount = p[0];
                    _loopStartIndex = e.Index + 1;
                    _runEvents = false;
                    break;
                case 0x00050000: //Start looping
                    _looping = true;
                    _loopEndIndex = e.Index;
                    _eventIndex = _loopStartIndex;
                    _runEvents = true;
                    break;
                case 0x000A0100: //If
                case 0x000A0200: //If Value
                case 0x000A0300: //If Unk
                case 0x000A0400: //If Comparison
                    if (_runEvents)
                    {
                        _currentIf = _ifIndex++;
                        _runEvents = false;
                        _ifInfo = new IfInfo();

                        index = eventIndex + 1;
                        while (true)
                        {
                            if (index < Count)
                            {
                                ev = this[index];
                                id = (int)ev.EventID;
                                if (id == 0x000B0100 ||
                                    id == 0x000B0200 ||
                                    id == 0x000B0300 ||
                                    id == 0x000B0400)
                                    index++;
                                else
                                    break;
                            }
                            else
                                break;
                        }
                        _ifInfo._reqIndices = new List<int>();
                        _ifInfo._reqIndices.Add(index);

                        _ifEndIndices.Add(0);
                        reqInfo = new RequirementInfo(p[0]);
                        for (int i = 1; i < ((eventId >> 8) & 0xFF); i++)
                            reqInfo._values.Add(e[i]);
                        _ifInfo._requirements = new List<List<RequirementInfo>>();
                        _ifInfo._requirements.Add(new List<RequirementInfo>());
                        _ifInfo._requirements[0].Add(reqInfo);
                    }
                    else
                    {
                        _ifIndex++;
                    }
                    break;
                case 0x000E0000: //Else
                    if (!_runEvents)
                    {
                        if (_ifIndex == _currentIf)
                        {
                            _ifInfo._elseIndex = eventIndex;
                        }
                    }
                    else
                    {
                        if (_ifIndex == _currentIf + 1)
                            _eventIndex = _ifInfo._endIndex;
                    }
                    break;
                case 0x000D0100: //Else If (req)
                case 0x000D0200: //Else If Value (req val)
                case 0x000D0300: //Else If Unk (req val unk)
                case 0x000D0400: //Else If Comparison (req var val var)

                    if (!_runEvents)
                    {
                        if (_ifIndex == _currentIf)
                        {
                            index = eventIndex + 1;
                            while (true)
                            {
                                if (index < Count)
                                {
                                    ev = this[index];
                                    id = (int)ev.EventID;
                                    if (id == 0x000B0100 ||
                                        id == 0x000B0200 ||
                                        id == 0x000B0300 ||
                                        id == 0x000B0400)
                                        index++;
                                    else
                                        break;
                                }
                                else
                                    break;
                            }
                            _ifInfo._reqIndices.Add(index);
                        }
                    }
                    else
                    {
                        if (_ifIndex == _currentIf + 1)
                            _eventIndex = _ifInfo._endIndex;
                    }

                    if (!_runEvents && _ifIndex == _currentIf + 1)
                    {
                        reqInfo = new RequirementInfo(p[0]);
                        for (int i = 1; i < eCount; i++)
                            reqInfo._values.Add(e[i]);
                        _ifInfo._requirements.Add(new List<RequirementInfo>());
                        _ifInfo._requirements[0].Add(reqInfo);
                    }
                    break;
                case 0x000B0100: //And If
                case 0x000B0200: //And If Value
                case 0x000B0300: //And If Unk
                case 0x000B0400: //And If Comparison
                    if (!_runEvents && _ifIndex == _currentIf + 1)
                    {
                        reqInfo = new RequirementInfo(p[0]);
                        for (int i = 1; i < eCount; i++)
                            reqInfo._values.Add(e[i]);
                        _ifInfo._requirements.Add(new List<RequirementInfo>());
                        _ifInfo._requirements[0].Add(reqInfo);
                    }
                    break;
                case 0x000F0000: //End if
                    _ifIndex--;
                    if (!_runEvents)
                    {
                        if (_ifIndex == _currentIf)
                        {
                            _ifInfo._endIndex = _ifEndIndices[_currentIf] = eventIndex + 1;
                            _eventIndex = _ifInfo.Run();
                            _runEvents = true;
                        }
                    }
                    break;
                case 0x00100200: //Switch
                    _cases = new List<Parameter>();
                    _caseIndices = new List<int>();

                    //Turn off events to examine them until end switch
                    //Then the examined data will be evaluated
                    _runEvents = false;

                    _switchStartIndex = eventIndex;
                    break;
                case 0x00110100: //Case
                    if (!_runEvents)
                    {
                        if (_cases != null && _caseIndices != null)
                        {
                            _cases.Add(e[0]);
                            _caseIndices.Add(e.Index);
                        }
                    }
                    else
                    {
                        _eventIndex = _switchEndIndex + 1;
                        _switchEndIndex = -1;
                    }
                    break;
                case 0x00120000: //Default Case
                    _defaultCaseIndex = e.Index;
                    break;
                case 0x00130000: //End Switch
                    _runEvents = true;
                    _switchEndIndex = e.Index;

                    //Apply cases
                    index = 0;
                    if (_switchStartIndex >= 0 && _switchStartIndex < Count)
                    {
                        Parameter Switch = this[_switchStartIndex][1];
                        foreach (Parameter param in _cases)
                        {
                            if (Switch.Compare(param, 2))
                            {
                                _eventIndex = _caseIndices[index] + 1;
                                break;
                            }
                            index++;
                        }
                    }

                    if (_cases != null && index == _cases.Count && _defaultCaseIndex != -1)
                        _eventIndex = _defaultCaseIndex + 1;

                    _defaultCaseIndex = -1;
                    _switchStartIndex = -1;
                    _cases = null;

                    break;
                case 0x00180000: //Break
                    _eventIndex = _switchEndIndex + 1;
                    _switchEndIndex = -1;
                    break;
                case 0x10050200: //Article Visiblity
                    id = p[0];
                    if (id < 0 || id >= RunTime._articles.Length)
                        break;
                    articleInfo = RunTime._articles[id];
                    if (articleInfo != null && articleInfo._model != null)
                        articleInfo._model._visible = p[1] != 0;
                    break;
                case 0x01010000: //Loop Rest
                    _waitFrames = 1;
                    break;
                case 0x06000D00: //Offensive Collison
                case 0x062B0D00: //Thrown Collision
                    hitbox = new HitBox(e, Article != null ? Article.Index : -1);
                    hitbox.HitboxID = (int)(p[0] & 0xFFFF);
                    hitbox.HitboxSize = p[5];
                    RunTime._hitBoxes.Add(hitbox);
                    break;
                case 0x06050100: //Body Collision
                    _hurtBoxType = p[0];
                    break;
                case 0x06080200: //Bone Collision
                    id = p[0];
                    if (Root.Model != null && Root.Model._linker.BoneCache.Length > id && id >= 0)
                    {
                        MDL0BoneNode bone = Root.Model._linker.BoneCache[id] as MDL0BoneNode;
                        switch ((int)p[1])
                        {
                            case 0:
                                bone._nodeColor = Color.Transparent;
                                bone._boneColor = Color.Transparent;
                                break;
                            case 1:
                                bone._nodeColor = bone._boneColor = Color.FromArgb(255, 255, 0);
                                break;
                            default:
                                bone._nodeColor = bone._boneColor = Color.FromArgb(0, 0, 255);
                                break;
                        }
                        _boneCollisions.Add(bone);
                    }
                    break;
                case 0x06060100: //Undo Bone Collision
                    foreach (MDL0BoneNode bone in _boneCollisions)
                        bone._nodeColor = bone._boneColor = Color.Transparent;
                    _boneCollisions = new List<MDL0BoneNode>();
                    break;
                case 0x060A0800: //Catch Collision 1
                case 0x060A0900: //Catch Collision 2
                case 0x060A0A00: //Catch Collision 3
                    hitbox = new HitBox(e, Article != null ? Article.Index : -1);
                    hitbox.HitboxID = p[0];
                    hitbox.HitboxSize = p[2];
                    RunTime._hitBoxes.Add(hitbox);
                    break;
                case 0x060D0000: //Terminate Catch Collisions
                    for (int i = 0; i < RunTime._hitBoxes.Count; i++)
                        if (RunTime._hitBoxes[i].IsCatch())
                            RunTime._hitBoxes.RemoveAt(i--);
                    break;
                case 0x00060000: //Loop break
                    _looping = false;
                    _eventIndex = _loopEndIndex + 1;
                    _loopTime = 0;
                    break;
                case 0x06150F00: //Special Offensive Collison
                    hitbox = new HitBox(e, Article != null ? Article.Index : -1);
                    hitbox.HitboxID = (int)(p[0] & 0xFFFF);
                    hitbox.HitboxSize = p[5];
                    RunTime._hitBoxes.Add(hitbox);
                    break;
                case 0x06040000: //Terminate Collisions
                    for (int i = 0; i < RunTime._hitBoxes.Count; i++)
                        if (RunTime._hitBoxes[i].IsOffensive(true))
                            RunTime._hitBoxes.RemoveAt(i--);
                    break;
                case 0x06030100: //Delete hitbox
                    for (int i = 0; i < RunTime._hitBoxes.Count; i++)
                    {
                        HitBox hbox = RunTime._hitBoxes[i];
                        if (hbox.HitboxID == p[0] && hbox.IsOffensive(true))
                        {
                            RunTime._hitBoxes.RemoveAt(i--);
                            break;
                        }
                    }
                    break;
                case 0x060C0100: //Delete Catch Collision
                    for (int i = 0; i < RunTime._hitBoxes.Count; i++)
                    {
                        HitBox hbox = RunTime._hitBoxes[i];
                        if (hbox.HitboxID == p[0] && hbox.IsCatch())
                        {
                            RunTime._hitBoxes.RemoveAt(i--);
                            break;
                        }
                    }
                    break;
                case 0x061B0500: //Move hitbox
                    foreach (HitBox hbox in RunTime._hitBoxes)
                        if (hbox.HitboxID == p[0] && hbox.IsOffensive(true))
                        {
                            hbox._parameters[1] = p[1];
                            hbox._parameters[6] = p[2];
                            hbox._parameters[7] = p[3];
                            hbox._parameters[8] = p[4];
                            break;
                        }
                    break;
                case 0x04060100: //Set animation frame
                    //if (Article == null)
                    //    RunTime.SetFrame((int)(e[0].RealValue + 0.05f));
                    //else
                    //    RunTime._articles[Article.Index].SetFrame((int)(e[0].RealValue + 0.05f));
                    break;
                case 0x00070100: //Subroutine
                    script = (e[0] as EventOffset)._script;
                    if (script != null && script != _script)
                    {
                        script.Reset();
                        RunTime._runningScripts.Add(script);
                        script.SetFrame(0);
                    }
                    break;
                case 0x00080000: //Return
                    _return = true;
                    _eventIndex = Count;
                    if (RunTime._runningScripts.Contains(_script))
                        RunTime._runningScripts.Remove(_script);
                    break;
                case 0x00090100: //Go to
                    script = (e[0] as EventOffset)._script;
                    if (script != null && script != _script)
                    {
                        RunTime._runningScripts.Remove(_script);
                        script.Reset();
                        RunTime._runningScripts.Add(script);
                        script.SetFrame(0);
                    }
                    break;
                case 0x0A030100: //Stop sound
                    id = p[0];
                    if (RunTime._playingSounds.ContainsKey(id))
                    {
                        List<AudioInfo> aList = RunTime._playingSounds[id];
                        foreach (AudioInfo aInfo in aList)
                            if (aInfo._buffer != null)
                            {
                                aInfo._buffer.Stop();
                                aInfo._buffer.Dispose();
                                aInfo._stream.Dispose();

                            }
                        RunTime._playingSounds.Remove(id);
                    }
                    break;
                case 0x0A000100: //Play sound
                case 0x0A010100:
                case 0x0A020100:
                case 0x0A040100:
                case 0x0A050100:
                case 0x0A060100:
                case 0x0A070100:
                case 0x0A080100:
                case 0x0A090100:
                case 0x0A0A0100:
                case 0x0A0B0100:
                case 0x0A0C0100:
                case 0x0A0D0100:
                case 0x0A0E0100:
                case 0x0A0F0100:

                    if (RunTime._muteSFX)
                        break;

                    id = p[0];
                    if (Manager.SoundArchive != null)
                    {
                        RSARNode node = Manager.SoundArchive;
                        List<RSAREntryNode> sounds = node._infoCache[0];
                        if (id >= 0 && id < sounds.Count)
                        {
                            RSARSoundNode s = sounds[id] as RSARSoundNode;
                            if (s != null)
                            {
                                IAudioStream stream = s.CreateStreams()[0];
                                AudioBuffer b = Manager._audioProvider.CreateBuffer(stream);
                                AudioInfo info = new AudioInfo(b, stream);

                                if (RunTime._playingSounds.ContainsKey(id))
                                    RunTime._playingSounds[id].Add(info);
                                else
                                    RunTime._playingSounds[id] = new List<AudioInfo>() { info };

                                b.Reset();
                                b.Seek(0);
                                b.Play();
                            }
                        }
                    }
                    break;
                case 0x0B000200: //Model Changer 1
                case 0x0B010200: //Model Changer 2

                    ModelVisibility visNode = null;
                    if (Article != null)
                    {
                        //Check if we have data to work with
                        articleInfo = RunTime._articles[Article.Index];

                        if (articleInfo == null ||
                            articleInfo._model == null ||
                            articleInfo._model._objList == null ||
                            articleInfo._article._mdlVis == null ||
                            articleInfo._article._mdlVis.Count == 0) break;

                        visNode = articleInfo._article._mdlVis;
                    }
                    else
                    {
                        //Check if we have data to work with
                        if (Root.Model._objList == null ||
                            Root.Data._modelVis.Count == 0) break;

                        visNode = Root.Data._modelVis;
                    }

                    //Get the target reference
                    ModelVisReference refEntry = Root.Data._modelVis[((int)(eventId >> 16 & 1))];

                    //Check if the reference and switch id is usable
                    if (refEntry.Count == 0 || p[0] < 0 || p[0] >= refEntry.Count) break;

                    //Turn off objects
                    ModelVisBoneSwitch SwitchNode = refEntry[p[0]];
                    foreach (ModelVisGroup grp in SwitchNode)
                        foreach (BoneIndexValue b in grp._bones)
                            if (b.BoneNode != null)
                                foreach (MDL0ObjectNode obj in b.BoneNode._manPolys)
                                    obj._render = false;

                    //Check if the group id is usable
                    if (p[1] > SwitchNode.Count || p[1] < 0) break;

                    //Turn on objects
                    ModelVisGroup group = SwitchNode[p[1]];
                    if (group != null)
                        foreach (BoneIndexValue b in group._bones)
                            if (b.BoneNode != null)
                                foreach (MDL0ObjectNode obj in b.BoneNode._manPolys)
                                    obj._render = true;

                    break;
                case 0x0B020100: //Model visibility
                    if (Article == null)
                        Root.Model._visible = p[0] != 0;
                    else if (Article.Index < RunTime._articles.Length && RunTime._articles[Article.Index]._model != null)
                        RunTime._articles[Article.Index]._model._visible = p[0] != 0;
                    break;
                case 0x0D000200: //Concurrent Infinite Loop
                    index = p[0];
                    EventOffset off = (e[1] as EventOffset);
                    if (off._script != null)
                    {
                        if (RunTime._concurrentLoopScripts.ContainsKey(index))
                            RunTime._concurrentLoopScripts.Remove(index);
                        RunTime._concurrentLoopScripts.Add(index, off._script);
                    }
                    break;
                case 0x0D010100: //Terminate Concurrent Infinite Loop
                    index = p[0];
                    if (RunTime._concurrentLoopScripts.ContainsKey(index))
                        RunTime._concurrentLoopScripts.Remove(index);
                    break;
                case 0x0E000100: //Set Air/Ground
                    RunTime._location = (RunTime.Location)(p[0]);
                    break;
                case 0x10000100: //Generate Article
                case 0x10000200: //Generate Article
                case 0x10030100: //Remove Article

                    //These events do a similar job!
                    bool removeArticle = eID == 3;

                    //Make sure we have all the data we need available
                    MainControl main = MainForm.Instance._mainControl;
                    MovesetFile mNode = Manager.Moveset;
                    if (mNode == null)
                        break;
                    DataSection d = mNode.Data;
                    if (d == null)
                        break;

                    //Get the id of the article to be called and check it
                    int aId2 = p[0];
                    if (aId2 < 0 || aId2 >= RunTime._articles.Length)
                        break;

                    //Get the called article from the article list
                    articleInfo = RunTime._articles[aId2];

                    if (articleInfo == null)
                        return;

                    //Remove or add the article
                    if (removeArticle)
                    {
                        if (!articleInfo.Running)
                            return;

                        //Remove the article's model from the scene
                        if (articleInfo._model != null)
                        {
                            main.RemoveTarget(articleInfo._model);
                            articleInfo._model._visible = false;
                        }

                        //This article is no longer available for use
                        articleInfo.Running = false;
                    }
                    else
                    {
                        if (articleInfo.Running)
                            return;

                        //Add the article's model to the scene
                        if (articleInfo._model != null)
                        {
                            main.AddTarget(articleInfo._model);
                            articleInfo._model._visible = true;
                        }

                        //This article is now available for use
                        articleInfo.Running = true;
                    }
                    break;
                case 0x10040200: //Set Anchored Article SubAction
                case 0x10070200: //Set Remote Article SubAction
                    id = p[0];
                    int sId = p[1];
                    if (id < 0 || id >= RunTime._articles.Length)
                        break;

                    //Get the called article from the article list
                    articleInfo = RunTime._articles[id];
                    if (articleInfo != null)
                    {
                        articleInfo.SubactionIndex = sId;
                        articleInfo._setAt = _frameIndex;
                    }
                    break;
                case 0x10010200: //Set Ex-Anchored Article Action
                    break;
                case 0x12000200: //Basic Var Set
                case 0x12060200: //Float Var Set
                    e[1].RealValue = e[0].RealValue;
                    break;
                case 0x12010200: //Basic Var Add
                case 0x12070200: //Float Var Add
                    e[1].RealValue = e[1].RealValue + e[0].RealValue;
                    break;
                case 0x12020200: //Basic Var Sub
                case 0x12080200: //Float Var Sub
                    e[1].RealValue = e[1].RealValue - e[0].RealValue;
                    break;
                case 0x12030100: //Basic Var Inc
                    e[0].RealValue = e[0].RealValue + 1.0f;
                    break;
                case 0x12040100: //Basic Var Dec
                    e[0].RealValue = e[0].RealValue - 1.0f;
                    break;
                case 0x120A0100: //Bit Variable Set
                    e[0].RealValue = 1.0f;
                    break;
                case 0x120B0100: //Bit Variable Clear
                    e[0].RealValue = 0.0f;
                    break;
                case 0x120F0200: //Float Variable Multiply
                    e[1].RealValue = e[1].RealValue * e[0].RealValue;
                    break;
                case 0x12100200: //Float Variable Divide
                    if (e[0].RealValue != 0)
                        e[1].RealValue = e[1].RealValue / e[0].RealValue;
                    break;
                case 0x64000000: //Allow Interrupt
                    RunTime._allowInterrupt = true;
                    break;
                case 0x02000300: //Change Action Status
                case 0x02000400:
                case 0x02000500:
                case 0x02000600:

                    break;
                case 0x02010200: //Change Action
                case 0x02010300:
                case 0x02010400:
                case 0x02010500:
                    aChangeInfo = new ActionChangeInfo(p[0]);
                    reqInfo = new RequirementInfo(p[1]);
                    for (int i = 2; i < Count; i++)
                        reqInfo._values.Add(e[i]);
                    aChangeInfo._requirements.Add(reqInfo);
                    RunTime.AddActionChangeInfo(aChangeInfo);
                    break;
                case 0x02040100: //Additional Change Action Requirement
                case 0x02040200:
                case 0x02040300:
                case 0x02040400:

                    break;
                case 0x02060100: //Enable Action Status ID
                    break;
                case 0x02080100: //Disable Action Status ID
                    break;
                case 0x02090200: //Invert Action Status ID
                    break;
                case 0x020A0100: //Allow Specific Interrupt
                    break;
                case 0x020B0100: //Disallow Specific Interrupt
                    break;
                case 0x020C0100: //Unregister Interrupt
                    break;
                case 0x04000100: //Change Subaction
                case 0x04000200:
                    sChangeInfo = new SubActionChangeInfo(p[0], eCount == 2 && p[1] != 0);
                    RunTime.AddSubActionChangeInfo(sChangeInfo);
                    break;
                case 0x04010200: //Change Subaction
                    sChangeInfo = new SubActionChangeInfo(p[0], false);
                    sChangeInfo._requirements.Add(new RequirementInfo(p[1]));
                    RunTime.AddSubActionChangeInfo(sChangeInfo);
                    break;
            }
        }
예제 #2
0
        /// <summary>
        /// Evaluates a requirement using the info given.
        /// </summary>
        /// <returns>Whether the requirement returned true or false</returns>
        public static bool ApplyRequirement(RequirementInfo info)
        {
            bool not = ((info._requirement >> 31) & 1) == 1;
            long req = info._requirement & 0x7FFFFFFF;
            bool v = false;

            switch (req)
            {
                case 0x03: //Is On Ground
                    v = RunTime._location == RunTime.Location.Ground;
                    break;

                case 0x04: //Is In Air
                    v = RunTime._location == RunTime.Location.Air;
                    break;

                case 0x06: //On a pass-through floor
                    v = false;
                    break;

                case 0x07: //Compare
                    if (info._values.Count == 3)
                        v = info._values[0].Compare(info._values[2], info._values[1].Data);
                    break;

                case 0x08: //Bit is set
                    v = info._values[0].RealValue != 0.0f;
                    break;

                case 0x0C: //Touching something
                    switch (info._values[0].Data)
                    {
                        case 1: //Floor

                            break;
                        case 2: //Left Wall

                            break;
                        case 3: //Ceiling

                            break;
                        case 4: //Right Wall

                            break;
                    }
                    break;

                case 0x15: //Article Exists
                    int aId = (int)info._values[0].RealValue;
                    if (aId < 0 || aId >= RunTime._articles.Length)
                        break;
                    v = RunTime._articles[aId].Running;
                    break;

                case 0x17: //Within distance from floor
                    if (Manager.Moveset != null &&
                        Manager.Moveset.Data != null &&
                        Manager.Moveset.Data._misc != null)
                    {
                        Vector3 p = Manager.Moveset.Data._misc._boneRefs[4].BoneNode._frameMatrix.GetPoint();
                        v = p._y < info._values[0].RealValue;
                    }
                    break;

                case 0x2A: //In Water
                    return false;

                case 0x2B: //Roll a die
                    //int sides = (int)info._values[0].RealValue;

                    break;

                case 0x2C: //Subaction exists

                    break;
                case 0x30: //Button Press

                    break;
                case 0x31: //Button Release

                    break;
                case 0x32: //Button Pressed

                    break;
                case 0x33: //Button Not Pressed

                    break;
                case 0x34: //Stick Dir Pressed

                    break;
                case 0x35: //Stick Dir Not Pressed

                    break;
            }

            return not ? !v : v;
        }