/// <summary> /// Adds a list of events to the current items collection. /// </summary> /// <param name="items">The list of items being added.</param> private void AddEvents(IList items) { double?offset = this.configurationService.GetParameterValueAsDouble("GSISOffsetSeconds"); foreach (XElement element in items) { EventOffset eventOffset = this.eventOffsetParser.ParseEventData(element); if (eventOffset == null) { EventData eventData = this.eventDataParser.ParseEventData(element); if (eventData != null) { eventData.Time = eventData.Time.Add(TimeSpan.FromSeconds(offset.GetValueOrDefault())).Add(this.currentEventOffset); this.availableMetadata.Add(eventData); this.ShowEvent(eventData); } } else { this.currentEventOffset = TimeSpan.FromSeconds(eventOffset.Offset); foreach (EventData eventData in this.availableMetadata) { eventData.Time = eventData.Time.Add(this.currentEventOffset); } } } }
/// <summary> /// Removes the list of items from the current event collection. /// </summary> /// <param name="items">The items being removed.</param> private void RemoveEvents(IList items) { foreach (XElement element in items) { EventOffset eventOffset = this.eventOffsetParser.ParseEventData(element); if (eventOffset == null) { EventData eventData = this.eventDataParser.ParseEventData(element); if (eventData != null) { EventData currentEventData = this.availableMetadata.Where(x => x.Id == eventData.Id).FirstOrDefault(); if (currentEventData != null) { this.availableMetadata.Remove(currentEventData); this.Metadata.Remove(currentEventData); this.HideEvent(); } } } else { foreach (EventData eventData in this.availableMetadata) { eventData.Time = eventData.Time.Subtract(this.currentEventOffset); } this.currentEventOffset = TimeSpan.Zero; } } }
//Display the parameter's value according to its type. public void DisplayInType(Parameter value) { if (value is EventOffset) { requirementPanel.Visible = false; valueGrid.Visible = false; offsetPanel.Visible = true; EventOffset offset = value as EventOffset; _updating = true; comboBox1.SelectedIndex = (int)offset._offsetInfo._list; if (offset._offsetInfo._type != TypeValue.None) { comboBox3.SelectedIndex = (int)offset._offsetInfo._type; } if (offset._offsetInfo._index != -1) { comboBox2.SelectedIndex = offset._offsetInfo._index; } _updating = false; } else { requirementPanel.Visible = false; valueGrid.Visible = true; offsetPanel.Visible = false; valueGrid.SelectedObject = value; } }
public void ShouldApplyOffsetToExistingEventsWhenOffsetIsBeingAdded() { var presentationModel = this.CreatePresentationModel(); EventData eventData = new EventData(Guid.NewGuid().ToString(), TimeSpan.FromSeconds(0), "Test"); var actualTime = eventData.Time; XElement element = new XElement("TestElement"); this.eventDataParser.ParseEventDataReturn = eventData; InStreamCollection collection = new InStreamCollection { element }; presentationModel.SetInStreamData(collection); this.eventDataParser.ParseEventDataReturn = null; EventOffset eventOffset = new EventOffset(10); XElement offsetElement = new XElement("TestElement"); this.eventOffsetParser.ParseEventDataReturn = eventOffset; collection.Add(offsetElement); Assert.AreEqual(actualTime.Add(TimeSpan.FromSeconds(eventOffset.Offset)), eventData.Time); }
//Return the name of the external pointer corresponding to the address if //one is available, otherwise return the string of the value passed. public string ResolvePointer(EventOffset node) { if (node._externalEntry != null) { return("External: " + node._externalEntry.Name); } if (node._offsetInfo._list == ListValue.Null) { return("0x" + Util.Hex(node.Data)); } else { string name = "", t = "", grp = ""; switch (node._offsetInfo._list) { case ListValue.Actions: grp = "Action "; switch (node._offsetInfo._type) { case TypeValue.Entry: t = "Entry"; break; case TypeValue.Exit: t = "Exit"; break; } break; case ListValue.SubActions: grp = "SubAction "; switch (node._offsetInfo._type) { case TypeValue.Main: t = "Main"; break; case TypeValue.GFX: t = "GFX"; break; case TypeValue.SFX: t = "SFX"; break; case TypeValue.Other: t = "Other"; break; } break; case ListValue.SubRoutines: grp = "SubRoutine "; name = node.Index.ToString(); break; case ListValue.ScreenTints: grp = "Screen Tint "; break; case ListValue.FlashOverlays: grp = "Flash Overlay "; break; } return(grp + node._offsetInfo._index.ToString() + ((int)node._offsetInfo._list >= 2 ? "" : " " + t)); } }
private void offsetOkay_Click(object sender, EventArgs e) { EventOffset _targetNode = param as EventOffset; if (_targetNode._script != null) { _targetNode.Data = -1; _targetNode._script._actionRefs.Remove(param); } if (comboBox1.SelectedIndex >= 3) { if (comboBox1.SelectedIndex == 3 && comboBox2.SelectedIndex >= 0 && comboBox2.SelectedIndex < param._root.ReferenceList.Count) { if (_targetNode._externalEntry != null) { _targetNode._externalEntry.References.Remove(_targetNode); _targetNode._externalEntry = null; } (param._externalEntry = param._root.ReferenceList[comboBox2.SelectedIndex] as TableEntryNode).References.Add(param); } } else { if (param._externalEntry != null) { param._externalEntry.References.Remove(param); param._externalEntry = null; } } _targetNode._offsetInfo = new ScriptOffsetInfo( (ListValue)comboBox1.SelectedIndex, (TypeValue)(comboBox1.SelectedIndex >= 2 ? -1 : comboBox3.SelectedIndex), (comboBox1.SelectedIndex == 4 ? -1 : comboBox2.SelectedIndex)); _targetNode._script = ((MovesetNode)param._root).GetScript(_targetNode._offsetInfo); if (_targetNode._script != null) { _targetNode._script._actionRefs.Add(param); } else { param.Data = -1; } }
/// <summary> /// If the entry isn't null, /// adds the size of the entry to the current part length /// and adds the entry's lookup count to the main lookup count. /// </summary> protected bool GetScriptSize(Script script, bool incrementLookup = false) { //Build if it has data, if it's referenced, or if forced if (script.Count > 0 || script._actionRefs.Count > 0 || script._forceBuild) { //Collect script size GetSize(script); //Add lookup offset to the offset to this script if (incrementLookup) { _currentLookupCount++; } foreach (Event e in script) { foreach (Parameter p in e) { if (p is EventOffset) { EventOffset o = (EventOffset)p; bool useOffset = o._offsetInfo._list != ListValue.Null && o._offsetInfo._list != ListValue.References; if (useOffset) { //Add offset to the script to lookup IncLookup(); if (o._offsetInfo._list == ListValue.SubRoutines) { int index = Subroutines.IndexOf(o._script); if (!_builtSubroutines.Contains(index)) { GetScriptSize(o._script); _builtSubroutines.Add(index); } } } } } } return(true); } return(false); }
protected int WriteScript(Script script) { //Build if it has data, if it's referenced, or if forced if (script.Count > 0 || script._actionRefs.Count > 0 || script._forceBuild) { //Order: all parameters (of every event, in order) then event array int offset = Write(script); foreach (Event e in script) { foreach (Parameter p in e) { if (p is EventOffset) { EventOffset o = (EventOffset)p; bool useOffset = o._offsetInfo._list != ListValue.Null && o._offsetInfo._list != ListValue.References; //Action, subaction, flash overlay and screen tint scripts have already been written //Null and reference/external event offsets don't actually use the offset or have a physical script //That leaves only subroutines to write here if (useOffset) { if (o._offsetInfo._list == ListValue.SubRoutines) { int index = Subroutines.IndexOf(o._script); if (!_builtSubroutines.Contains(index)) { //Write subroutine directly after first reference by another script WriteScript(o._script); _builtSubroutines.Add(index); } } } } } } return(offset); } return(0); }
public void RunEvent(int eventIndex) { //Get the current event and its id e = this[eventIndex]; //Run event only if allowed or if an exception if (e == null || !_runEvents && !_runExceptions.Contains(eventId >> 16)) { return; } uint eventIdTemp = eventId & 0xFFFFFF00; //Cut out unk value //if (_events.ContainsKey(eventIdTemp)) // _events[eventIdTemp].Invoke(this, null); //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 (eventIdTemp) { 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 = e[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(e[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(e[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(e[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 = e[0]; if (id < 0 || id >= RunTime._articles.Length) { break; } articleInfo = RunTime._articles[id]; if (articleInfo != null && articleInfo._model != null) { articleInfo._model.IsRendering = e[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)(e[0] & 0xFFFF); hitbox.HitboxSize = e[5]; RunTime._hitBoxes.Add(hitbox); break; case 0x06050100: //Body Collision _hurtBoxType = e[0]; break; case 0x06080200: //Bone Collision id = e[0]; if (Root.Model != null && Root.Model._linker.BoneCache.Length > id && id >= 0) { MDL0BoneNode bone = Root.Model._linker.BoneCache[id] as MDL0BoneNode; switch ((int)e[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 = e[0]; hitbox.HitboxSize = e[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)(e[0] & 0xFFFF); hitbox.HitboxSize = e[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 == e[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 == e[0] && hbox.IsCatch()) { RunTime._hitBoxes.RemoveAt(i--); break; } } break; case 0x061B0500: //Move hitbox foreach (HitBox hbox in RunTime._hitBoxes) { if (hbox.HitboxID == e[0] && hbox.IsOffensive(true)) { hbox._parameters[1] = e[1]; hbox._parameters[6] = e[2]; hbox._parameters[7] = e[3]; hbox._parameters[8] = e[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 = e[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; } if (Manager.SoundArchive != null) { RSARNode node = Manager.SoundArchive; List <RSAREntryNode> sounds = node._infoCache[0]; id = e[0]; if (sounds != null && 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 == null || Root.Model._objList == null || Root.Data._modelVis.Count == 0) { break; } visNode = Root.Data._modelVis; } if (visNode != null) { int refId = ((int)((eventId >> 16) & 0xFF)); int switchId = e[0]; int groupId = e[1]; visNode.ApplyVisibility(refId, switchId, groupId); } break; case 0x0B020100: //Model visibility if (Article == null) { Root.Model.IsRendering = e[0] != 0; } else if (Article.Index < RunTime._articles.Length && RunTime._articles[Article.Index]._model != null) { RunTime._articles[Article.Index]._model.IsRendering = e[0] != 0; } break; case 0x0D000200: //Concurrent Infinite Loop index = e[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 = e[0]; if (RunTime._concurrentLoopScripts.ContainsKey(index)) { RunTime._concurrentLoopScripts.Remove(index); } break; case 0x0E000100: //Set Air/Ground RunTime._location = (RunTime.Location)((int)e[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; MovesetNode 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 = e[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; } articleInfo.Running = !removeArticle; break; case 0x10040200: //Set Anchored Article SubAction case 0x10070200: //Set Remote Article SubAction id = e[0]; int sId = e[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(e[0]); reqInfo = new RequirementInfo(e[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(e[0], eCount == 2 && e[1] != 0); RunTime.AddSubActionChangeInfo(sChangeInfo); break; case 0x04010200: //Change Subaction sChangeInfo = new SubActionChangeInfo(e[0], false); sChangeInfo._requirements.Add(new RequirementInfo(e[1])); RunTime.AddSubActionChangeInfo(sChangeInfo); break; case 0x11010A00: //External Graphic Effect case 0x11001000: //Same as prev but with random offset and rotation bool random = ((eventId >> 16) & 0xFF) == 0; break; case 0x111A1000: //Graphic Effect; no file break; } }