/// <summary> /// Initializes a new instance of this class. /// </summary> /// <param name="startNode">Starting node of the path to follow.</param> /// <param name="entity">Entity to follow the path.</param> public PathFollowProcess(PathMarkerNode startNode, EntityNode entity) { _entity = entity; _startNode = startNode; _currentNode = startNode; AdvanceOneNode(); }
/// <summary> /// Copys all the data contained in this scene node to another scene node. /// </summary> /// <param name="node">Scene node to copy data into.</param> public override void CopyTo(SceneNode node) { PathMarkerNode markerNode = node as PathMarkerNode; if (markerNode == null) { return; } base.CopyTo(node); // Copy emitter stuff markerNode._speed = new StartFinishF(_speed.Start, _speed.Finish); markerNode._delay = _delay; markerNode._nextNodeName = _nextNodeName; }
/// <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> /// Advances the entity by one node of the path. /// </summary> public void AdvanceOneNode() { // Is it a delay node? if (_previousNode != null && _previousNode.Delay != 0) { if (_delayProcess == null) { _delayProcess = new DelayProcess(_previousNode.Delay); ProcessManager.AttachProcess(_delayProcess); WaitForProcess(_delayProcess, ProcessResult.Success); return; } else _delayProcess = null; } // Trigger the events of the previous node. if (_previousNode != null) _previousNode.TriggerEvents(); // Are we finished? if (_currentNode == null) { Finish(ProcessResult.Success); return; } // Move to the node! Transformation nodeTransform = _currentNode.CalculateTransformation(); _moveToProcess = new EntityMoveToProcess(_entity, nodeTransform.X + (_currentNode.Width / 2), nodeTransform.Y + (_currentNode.Height / 2), _currentNode.Speed); ProcessManager.AttachProcess(_moveToProcess); WaitForProcess(_moveToProcess, ProcessResult.Success); // Get the next node. _previousNode = _currentNode; _currentNode = _currentNode.NextNode; }
/// <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; }