/// <summary> /// Loads the next node in the given binary reader and returns it. /// </summary> /// <param name="reader">Binary reader to read node from.</param> /// <param name="getProgress">If set to true this node is used to judge the current progress.</param> /// <returns>Scene node that was loaded from the binary reader.</returns> private SceneNode LoadNode(BinaryReader reader, bool getProgress) { // Read in the name of this node's class. string name = reader.ReadString(); //HighPreformanceTimer timer = new HighPreformanceTimer(); // Create a new instance of this entity and tell it to load itself. // (See if its a known object first as its quicker to get it without reflection) SceneNode node = null; if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.entitynode")) node = new EntityNode(); else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.scriptedentitynode")) node = new ScriptedEntityNode(); else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.scenenode")) node = new SceneNode(); else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.groupnode")) node = new GroupNode(); else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.emitternode")) node = new EmitterNode(); else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.tilemapsegmentnode")) node = new TilemapSegmentNode(); else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.pathmarkernode")) node = new PathMarkerNode(); else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.tilenode")) node = new TileNode(); else node = (SceneNode)ReflectionMethods.CreateObject(name); //DebugLogger.WriteLog("Created scene graph node " + name + " in " + timer.DurationMillisecond + ".\n"); //timer.Restart(); // Load in this nodes details. node.UniqueID = (_uniqueIDTracker++); node.Load(reader); //DebugLogger.WriteLog("Loaded scene graph node " + name + " in " + timer.DurationMillisecond + ".\n"); // Read in all the children of this node, and attach // them to this node. DebugLogger.IncreaseIndent(); int childCount = reader.ReadInt32(); for (int i = 0; i < childCount; i++) { SceneNode childNode = LoadNode(reader); node.AddChild(childNode); if (getProgress == true) _loadingProgress = (int)(((float)(i + 1) / (float)childCount) * 100.0f); } DebugLogger.DecreaseIndent(); return node; }
/// <summary> /// Disposes of an instance of this class. /// </summary> public void Dispose() { _deadParticles.Clear(); ArrayList removeList = new ArrayList(); foreach (ParticleNode particle in _particles) { _emitter.Particles.Remove(particle); removeList.Add(particle); } foreach (ParticleNode particle in removeList) _particles.Remove(particle); foreach (ParticleModifier modifier in _modifiers) modifier.ParticleType = null; _modifiers.Clear(); _emitter = null; }
/// <summary> /// Inserts the current object into the map at the cursors position (or center-screen - /// - if this is not the active window) at the highest level on the scene graph /// </summary> private void InsertCurrentObject(bool inCenter, string overrideObjectURL) { string objectURL = overrideObjectURL != "" ? overrideObjectURL : _assetManagerWindow.SelectedObjectURL; EntityNode entity = null; // Keep a log of this insertion. DebugLogger.WriteLog("Inserting object of type '" + objectURL + "' into map"); // Check the extension to see if this is a built-in object or not. if (objectURL.IndexOf(".fso") >= 0) { // Compile the script. ScriptCompiler compiler = new ScriptCompiler(); bool errorOccured = false; string errorDescription = "\t"; if (compiler.Compile(objectURL) > 0) foreach (CompileError error in compiler.ErrorList) if (error.AlertLevel == ErrorAlertLevel.Error || error.AlertLevel == ErrorAlertLevel.FatalError) { errorDescription += (errorDescription == "" ? "" : "\n\t") + error.ToString(); errorOccured = true; } // If an error occured notify the user if not then // insert a new scripted entity into the map. if (errorOccured == true) { MessageBox.Show("Unable to insert object into map, the following error(s) occured while attempt to compile this objects script.\n\n"+errorDescription,"Compile Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); DebugLogger.WriteLog("Object insertion aborted. The following error(s) occured while attempting to compile this objects script.\n\n" + errorDescription, LogAlertLevel.Warning); } else { // Dump the compiled code into a memory stream. MemoryStream memStream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(memStream); BinaryReader reader = new BinaryReader(memStream); compiler.DumpExecutableFile(writer); memStream.Position = 0; // Create a new scripted entity with the given script attached to it. ScriptedEntityNode scriptedEntity = new ScriptedEntityNode(); entity = scriptedEntity; entity.RenderMode = EntityRenderMode.Rectangle; entity.BoundingRectangle = new Rectangle(0, 0, 16, 16); entity.Width = 16; entity.Height = 16; entity.Name = Path.GetFileNameWithoutExtension(objectURL); ScriptProcess process = new ScriptProcess(VirtualMachine.GlobalInstance, reader); process.Url = objectURL; if (process.DefaultEditorState != null) process.ChangeState(process.DefaultEditorState.Identifier); else process.State = null; scriptedEntity.ScriptProcess = process; // Are we allowed to place the entity? bool canPlace = true; string placeError = "This entity has been flagged as unplaceable. Please choose another or check this objects script."; foreach (Define define in process.Defines) { switch (define.Ident.ToUpper()) { case "UNPLACEABLE": canPlace = false; break; case "UNPLACEABLE_ERROR": placeError = define.Value; break; } } if (canPlace == false) { MessageBox.Show(placeError, "Unplaceable", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(entity); // Invoke OnCreate event. scriptedEntity.ScriptProcess[0].InvokeFunction("OnCreate", true, false); // Free up the streams. memStream.Close(); reader.Close(); writer.Close(); } } // Its built in so create the object requested. else { switch (objectURL.ToLower()) { case "tilemap segment": TilemapSegmentNode segment = new TilemapSegmentNode(8, 8, 16, 16); Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(segment); segment.IsGridVisible = true; entity = segment; break; case "emitter": entity = new EmitterNode(); Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(entity); entity.BoundingRectangle = new Rectangle(0, 0, 16, 16); entity.Width = 16; entity.Height = 16; break; case "entity": entity = new EntityNode(); Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(entity); entity.BoundingRectangle = new Rectangle(0, 0, 16, 16); entity.Width = 16; entity.Height = 16; break; case "path marker": entity = new PathMarkerNode(); Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(entity); entity.BoundingRectangle = new Rectangle(0, 0, 16, 16); entity.Width = 16; entity.Height = 16; entity.Image = _pathMarkerImage; entity.RenderMode = EntityRenderMode.Image; entity.Name = "Path Marker " + MathMethods.Random(MathMethods.Random(0, 10000), MathMethods.Random(10000, 10000000)); foreach (EntityNode selEntity in _selectedEntityList) if (selEntity is PathMarkerNode && ((PathMarkerNode)selEntity).NextNodeName == "") { ((PathMarkerNode)selEntity).NextNode = (PathMarkerNode)entity; ((PathMarkerNode)selEntity).NextNodeName = entity.Name; } break; } } if (entity == null) return; // Find the correct position for our new entity. int mapX, mapY; if (inCenter == false) { mapX = (int)Editor.GlobalInstance.CameraNode.Transformation.X + (int)((mousePositionBeforeRightClick[0] / Editor.GlobalInstance.CameraNode.Zoom)); mapY = (int)Editor.GlobalInstance.CameraNode.Transformation.Y + (int)((mousePositionBeforeRightClick[1] / Editor.GlobalInstance.CameraNode.Zoom)); } else { mapX = (int)Editor.GlobalInstance.CameraNode.Transformation.X + (int)(((mapPanel.ClientSize.Width - entity.BoundingRectangle.Width) / 2) / Editor.GlobalInstance.CameraNode.Zoom); mapY = (int)Editor.GlobalInstance.CameraNode.Transformation.Y + (int)(((mapPanel.ClientSize.Height - entity.BoundingRectangle.Height) / 2) / Editor.GlobalInstance.CameraNode.Zoom); } if (_snapToGrid == true) { mapX = (mapX / _gridWidth) * _gridWidth; mapY = (mapY / _gridHeight) * _gridHeight; } entity.Position(mapX, mapY, 0.0f); entity.IsBoundingBoxVisible = _viewBoundingBoxs; entity.IsEventLinesVisible = _viewEventLines; entity.IsCollisionBoxVisible = _viewCollisionBoxs; entity.ForceVisibility = true; ClearSelection(); AddEntityToSelection(entity); // Update the scene graph window if it exists. if (_sceneGraphWindow != null) _sceneGraphWindow.SyncronizeData(); // Update this entitys event nodes and the event nodes of others. foreach (SceneNode node in Engine.Engine.GlobalInstance.Map.SceneGraph.EnumerateNodes()) { EntityNode subNode = node as EntityNode; if (subNode == null) continue; if (subNode.Event.ToLower() == entity.Name.ToString().ToLower()) subNode.EventNodes.Add(entity); } PushUndoOperation(new InsertNodesUndoOperation(new SceneNode[] { entity })); SyncronizeWindow(); _mapChangedSinceSave = true; }
/// <summary> /// Called when the new effect button is clicked. /// </summary> /// <param name="sender">Object that caused this event to be triggered.</param> /// <param name="e">Arguments explaining why this event occured.</param> private void newEffectToolStripMenuItem_Click(object sender, EventArgs e) { _emitterNode = new EmitterNode(); SyncronizeTypes(); }
/// <summary> /// Called when the import effect menu item is clicked. /// </summary> /// <param name="sender">Object that caused this event to be triggered.</param> /// <param name="e">Arguments explaining why this event occured.</param> private void importEffectToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); dialog.InitialDirectory = Editor.GlobalInstance.EffectPath; dialog.Filter = "Effects files|*.fef"; dialog.Title = "Import effect"; dialog.RestoreDirectory = true; if (dialog.ShowDialog() == DialogResult.OK) { string file = dialog.FileName; if (file.ToLower().StartsWith(Editor.GlobalInstance.GamePath.ToLower() + "\\") == true) file = file.Substring(Editor.GlobalInstance.GamePath.Length + 1); if (file.ToLower().StartsWith(Editor.GlobalInstance.EffectPath.ToLower()) == false) { MessageBox.Show("Effect file must be within the effect directory or a sub directory of it.", "Relative Path Error", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } Stream stream = StreamFactory.RequestStream(file, StreamMode.Open); BinaryReader reader = new BinaryReader(stream); if (reader.ReadByte() != 'F' || reader.ReadByte() != 'E' || reader.ReadByte() != 'F') { MessageBox.Show("Effect file has been corrupted, it could not be loaded.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } _emitterNode = new EmitterNode(); _emitterProperties.Emitter = _emitterNode; _emitterNode.Load(reader); reader.Close(); stream.Close(); SyncronizeTypes(); } }
public void CreateEmitter(ScriptThread thread) { EntityNode node = new EmitterNode(); thread.SetReturnValue(new SceneNodeScriptObject(node)); }