public override bool OnInitialize() { //Start initializing. //This enables some functions for use. _initializing = true; //Get structs MovesetHeader *hdr = (MovesetHeader *)WorkingUncompressed.Address; sStringTable * stringTable = hdr->StringTable; _dataSize = hdr->_fileSize; //Create lists _subRoutines = new BindingList <Script>(); _commonSubRoutines = new BindingList <Script>(); _referenceList = new BindingList <ExternalEntry>(); _sectionList = new BindingList <ExternalEntry>(); _lookupSizes = new SortedList <int, int>(); _actions = new BindingList <ActionEntry>(); _entryCache = new SortedDictionary <int, MovesetEntry>(); _postProcessEntries = new List <MovesetEntry>(); _scriptOffsets = new List <List <int> > [5]; for (int i = 0; i < 5; i++) { _scriptOffsets[i] = new List <List <int> >(); for (int x = 0; x < (i == 0 ? 2 : i == 1 ? 4 : 1); x++) { _scriptOffsets[i].Add(new List <int>()); } } //Read lookup offsets first and use them to get entry sizes at each offset. bint *lookup = hdr->LookupEntries; //First add each offset to the dictionary with size of 0. //The dictionary will sort the offsets automatically, in case they aren't already. for (int i = 0; i < hdr->_lookupEntryCount; i++) { int w = *(bint *)Address(lookup[i]); if (!_lookupSizes.ContainsKey(w)) { _lookupSizes.Add(w, 0); } } //Now go through each offset and calculate the size with the offset difference. int prev = 0; bool first = true; int[] t = _lookupSizes.Keys.ToArray(); for (int i = 0; i < t.Length; i++) { int off = t[i]; if (first) { first = false; } else { _lookupSizes[prev] = off - prev; } prev = off; } //The last entry in the moveset file goes right up to the lookup offsets. _lookupSizes[prev] = Offset(lookup) - prev; //Parse references int numRefs = hdr->_externalSubRoutineCount; if (numRefs > 0) { sStringEntry *entries = (sStringEntry *)hdr->ExternalSubRoutines; for (int i = 0; i < numRefs; i++) { ExternalEntry e = Parse <ExternalEntry>(entries[i]._dataOffset); e._name = stringTable->GetString(entries[i]._stringOffset); _referenceList.Add(e); } } //Parse sections int numSections = hdr->_dataTableEntryCount; if (numSections > 0) { int dataIndex = -1; sStringEntry *entries = (sStringEntry *)hdr->DataTable; for (int i = 0; i < numSections; i++) { ExternalEntry e = null; int off = entries[i]._dataOffset; string name = stringTable->GetString(entries[i]._stringOffset); switch (name) { //Don't parse data sections until the very end case "data": case "dataCommon": dataIndex = i; _sectionList.Add(null); continue; //case "animParam": // e = _animParam = Parse<AnimParamSection>(off); // break; //case "subParam": // e = _subParam = Parse<SubParamSection>(off); // break; default: if (name.Contains("AnimCmd")) { e = Parse <Script>(off); _commonSubRoutines.Add(e as Script); } else { e = Parse <RawData>(off); } break; } e.DataOffsets.Add(off); e._name = name; _sectionList.Add(e); } if (dataIndex >= 0) { int off = entries[dataIndex]._dataOffset; string name = stringTable->GetString(entries[dataIndex]._stringOffset); switch (name) { case "data": _data = Parse <DataSection>(off); _data.DataOffsets.Add(off); _data._name = name; _sectionList[dataIndex] = _data; break; case "dataCommon": _dataCommon = Parse <DataCommonSection>(off); _dataCommon.DataOffsets.Add(off); _dataCommon._name = name; _sectionList[dataIndex] = _dataCommon; break; } } } while (_postProcessEntries.Count > 0) { //Make a copy of the post process nodes MovesetEntry[] arr = _postProcessEntries.ToArray(); //Clear the original array so it can be repopulated _postProcessEntries.Clear(); //Parse subroutines - may add more entries to post process foreach (MovesetEntry e in arr) { if (e is EventOffset) { ((EventOffset)e).LinkScript(); } } } //Sort subroutines by offset _subRoutines = new BindingList <Script>(_subRoutines.OrderBy(x => x._offset).ToList()); //Add the proper information to the sorted subroutines int q = 0; foreach (Script s in _subRoutines) { s._name = String.Format("[{0}] SubRoutine", s._index = q++); foreach (EventOffset e in s.ActionRefs) { e._offsetInfo = new ScriptOffsetInfo(ListValue.SubRoutines, TypeValue.None, s.Index); } } return(_initializing = false); }
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; } }