//--------------------------------------------------------------------------------------------------------------------------------------------------- // // Copyright (C)2007 DarkWynter Studios. All rights reserved. // //--------------------------------------------------------------------------------------------------------------------------------------------------- // {Contact : darkwynter.com for licensing information //--------------------------------------------------------------------------------------------------------------------------------------------------- namespace DarkWynter.Engine.GameObjects { #region Using Statements using System; using System.Collections.Generic; using System.ComponentModel; using System.Xml; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Xclna.Xna.Animation.Content; using Xclna.Xna.Animation; using Physics; using Globals; using ObjectLib; using DarkWynter.Engine.Init; using DarkWynter.Stream; using DarkWynter.Engine.Audio; using DarkWynter.Stream.UIInterfacing; #endregion /// /// Methods of GameObject follow the GameFlow pattern to ensure quick and efficient loading and unloading procedures. /// Additional properties are included in GameObject and are used by Renderer and Update to manipulate the GameObject. /// Each object specifies its draw and update procedures internally and is passed to Physics for in game motion and rotation. /// public class GameObject { #region GameObject Interface Properties private Mass _mass; //private XmlNode _xml; //private Load _load; private string _objectModelName; private bool _isCollectable; private bool _isKey; private Draw _draw; private Draw _drawBoundingVolume; private Draw _drawAIVision; /// /// Draw object /// [Category("_GameObject"), EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public Draw draw { get { return _draw; } set { _draw = value; } } /// /// Draw object's bounding volume /// [Category("_GameObject"), EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public Draw drawBoundingVolume { get { return _drawBoundingVolume; } set { _drawBoundingVolume = value; } } /// /// AI Vision Draw object /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public Draw drawAIVision { get { return _drawAIVision; } set { _drawAIVision = value; } } /// /// Mass object, handles physics of GameObject. /// [Category("_GameObject"), EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public Mass mass { get { return _mass; } set { _mass = value; } } /// /// Text identifier for model name. /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public string objectModelName { get { return _objectModelName; } set { _objectModelName = value; } } /// /// Defines if this object is collectable by players. /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public bool isCollectable { get { return _isCollectable; } set { _isCollectable = value; } } /// /// Defines if this object is a Key object collected to pass the level. /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public bool isKey { get { return _isKey; } set { _isKey = value; } } /// /// Difference between object height and terrain at it's x/z location. /// HeightDifference is positive when object is below the terrain. /// [Category("_GameObject")] public float heightDifference { get { return _heightDifference; } set { _heightDifference = value; } } public float _heightDifference; /// /// Terrain height at object's x/z location. /// [Category("_GameObject")] public float localTerrainHeight { get { return _localTerrainHeight; } set { _localTerrainHeight = value; } } public float _localTerrainHeight; /// /// Defines what kind of collision response this GameObject should have. /// public Enums_Engine.CollisionResponses collisionWithPlayerResponse { get { return _collisionWithPlayerResponse; } set { _collisionWithPlayerResponse = value; } } public Enums_Engine.CollisionResponses _collisionWithPlayerResponse = Enums_Engine.CollisionResponses.NONE; /// /// Defines the scale of damage or health an object bestows. /// public float collisionMultiplier = 0.001f; /// /// Game Object animated or not /// public bool modelAnimated; // Animation /// /// Model animator /// /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public ModelAnimator animator; /// /// Idle animation /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public AnimationController idle; /// /// Walk animation /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public AnimationController walk; /// /// Die animation /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public AnimationController die; /// /// Animation currently running /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public AnimationController currentAnimation; /// /// 3D Cue used with jump sound. /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public Cue3D jump; public bool destinationReached = false; public Vector3 _destination = new Vector3(); [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public Vector3 destination { get { return _destination; } set { _destination = value; } } /// /// Index to the game controller associated with this object /// public int controllerIndex; #endregion #region Physics Properties /// /// Used to pass static instance data to shader (for static objects) /// public VertexFogBinormalTangentDepth staticObjectValues; /// /// Tangential component of force calculations. /// public Vector3 tangentialComponent = new Vector3(); /// /// Normal component of force calculations. /// public Vector3 normalComponent = new Vector3(); /// /// Used in collision; surface normal calculation. /// public Vector3 surfaceNormal; /// /// Used in collision; gravity normal calculation. /// public Vector3 gravityNormalComponent; /// /// Used in collision; tangential gravity-force calculation. /// public Vector3 gravityTangentialComponent; /// /// Used in collision; normal velocity-force calculation. /// public Vector3 velocityNormalComponent; /// /// Used in collision; tangential velocity-force calculation. /// public Vector3 velocityTangentialComponent; /// /// Used in collision; normal totalForce calculation. /// public Vector3 totalForceNormalComponent; /// /// Used in collision; tangential totalForce calculation. /// public Vector3 totalForceTangentialComponent; /// /// Used in collision; combined velocity and totalForce normal calculation. /// public Vector3 combinedNormalForce; /// /// Used in collision; combined velocity and totalForce tangential calculation. /// public Vector3 combinedTangentialForce; #endregion #region Xml Interface private string _type; [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public string type { get { return _type; } set { _type = value; } } private string _id; [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public string id { get { return _id; } set { _id = value; } } private string _typeID; [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public string typeID { get { return _typeID; } set { _typeID = value; } } private string _name; [Category("_GameObject"), EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public string name { get { return _name; } set { _name = value; } } /// /// Defines the coordinate system the object is working in. /// public enum GridType { unit, coord, tile }; private GridType _grid; [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public GridType grid { get { return _grid; } set { _grid = value; } } private string _x; [Category("_GameObject")] public string x { get { return mass.currentPosition.X.ToString(); } set { _x = value; float Y_height = DarkWynterEngine.engine.objectLibrary.terrain.GetTerrainHeight( float.Parse(value) / Statics_Engine.TerrainSettings.terrainScaleFactor, mass.currentPosition.Z / Statics_Engine.TerrainSettings.terrainScaleFactor); mass.SetPosition( new Vector3(float.Parse(value), Y_height, mass.currentPosition.Z), new Vector3(float.Parse(value), Y_height, mass.currentPosition.Z - 1.0f)); } } [Category("_GameObject")] private string _z; public string z { get { return mass.currentPosition.Z.ToString(); } set { _z = value; float Y_height = DarkWynterEngine.engine.objectLibrary.terrain.GetTerrainHeight( mass.currentPosition.X / Statics_Engine.TerrainSettings.terrainScaleFactor, float.Parse(value) / Statics_Engine.TerrainSettings.terrainScaleFactor); mass.SetPosition( new Vector3(mass.currentPosition.X, Y_height, float.Parse(value)), new Vector3(mass.currentPosition.X, Y_height, float.Parse(value) - 1.0f)); } } private string _maxScale; [Category("_GameObject")] public string maxScale { get { return mass.scale.X.ToString(); } set { mass.scale = new Vector3(float.Parse(value)); } } private string _animated; [Category("_GameObject")] public string animated { get { if (_animated == "Yes") {return "Yes";} else {return "No";} } set { if (_animated == "Yes"){modelAnimated = true;} else{modelAnimated = false;} } } private string _model; [Category("_GameObject"), EditorAttribute(typeof(FileLocationEditor), typeof(System.Drawing.Design.UITypeEditor))] public string model { get { return _model; } set { _model = value; draw.model = Statics_Engine.SystemSettings.content.Load(this.model); foreach (ModelMesh mesh in draw.model.Meshes) { for (int i = 0; i < mesh.MeshParts.Count; i++) { ModelMeshPart part = mesh.MeshParts[i]; part.Effect = ShaderParameters.DrawFX.effect;//ShaderParameters.DrawFX.effect.Clone(Statics.SystemSettings.graphics.GraphicsDevice); } } } } private string _texture; [Category("_GameObject"), EditorAttribute(typeof(FileLocationEditor), typeof(System.Drawing.Design.UITypeEditor))] public string texture { get { if(_texture != null) return _texture; else return "Content\\_textures\\"; } set { _texture = value; if (draw.textureList.Count > 0) draw.textureList[0] = Statics_Engine.SystemSettings.content.Load(value); else draw.textureList.Add(Statics_Engine.SystemSettings.content.Load(value)); } } private string _bumpTexture; [Category("_GameObject"), EditorAttribute(typeof(FileLocationEditor), typeof(System.Drawing.Design.UITypeEditor))] public string bumpTexture { get { if (_bumpTexture != null) return _bumpTexture; else return "Content\\_textures\\"; } set { _bumpTexture = value; if (draw.textureList.Count > 1) draw.textureList[1] = Statics_Engine.SystemSettings.content.Load(value); else draw.textureList.Add(Statics_Engine.SystemSettings.content.Load(value)); } } /// /// Contains properties of the object that this Load belongs to. /// [EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] public XmlNode node { get { return _node; } set { _node = value; } } private XmlNode _node; /// /// Postion of this object, cooresponding to its pixel stored in the LocationMap. /// [Category("_GameObject")] public Vector3 startPosition { get { return _startPosition; } set { _startPosition = value; } } private Vector3 _startPosition; #endregion #region Methods public GameObject() { mass = new Mass(); mass.gameObjectPointer = this; } /// /// Game object constructor. /// Gets a pre-initialized mass object from the Statics.LevelSettings.darkMatter list. /// public GameObject(XmlNode objectNode, Vector3 startingLocation) { // Clone node to get a new pointer this.node = objectNode.Clone(); // Add Zero to get new pointer this.startPosition = startingLocation + Vector3.Zero; this.mass = new Mass(); this.mass.gameObjectPointer = this; //drawAIVision = new Draw(); } /// /// Load object data from Xml. /// /// ObjectLibrary that this object belongs to. public virtual bool Load(ObjectLibrary objectLibrary) { // Start Type properties this.mass.gameObjectPointer = this; this.objectModelName = this.node.Attributes["name"].Value; // Load model file if (!LoadModel(this.node)) { return false; } // Get terrain height at position float yPosition = objectLibrary.terrain.GetTerrainHeight(startPosition.X / Statics_Engine.TerrainSettings.terrainScaleFactor, startPosition.Z / Statics_Engine.TerrainSettings.terrainScaleFactor); // Set position and reference Vector3 locpos = new Vector3(this.startPosition.X, yPosition, this.startPosition.Z); Vector3 refpos = new Vector3(this.startPosition.X, yPosition, this.startPosition.Z - 1); mass.SetPosition(locpos, refpos); // Random Rotation bool randomRotation = false; if (randomRotation) { Random rand = new Random(); this.mass.Rotate(0.0f, (float)(2 * Math.PI * rand.NextDouble())); } else { this.mass.Rotate(0.0f, 0.0f); } // Scaling and weight this.mass.scale = new Vector3((int)(float.Parse(this.node.Attributes["maxScale"].Value))); this.mass.mass = float.Parse(this.node.Attributes["mass"].Value); this.mass.isMoving = false; // Set GameObject properties this.isCollectable = bool.Parse(this.node.Attributes["isCollectable"].Value); this.isKey = bool.Parse(this.node.Attributes["isKey"].Value); // Is a level keys if (this.isKey) { this.collisionWithPlayerResponse = Enums_Engine.CollisionResponses.HEALTHBONUS; } return true; #region Old Code //// Set up Model Manager //if (!LoadModel(load.node)) //{ // return false; //} //// Get the Location Map //Texture2D locationMap = Statics_Engine.SystemSettings.content.Load(node.Attributes["locationMap"].Value); //int length = locationMap.Width * locationMap.Width; //Color[] locationColorValues = new Color[length]; //locationMap.GetData(locationColorValues); //Random rand = new Random(); //// Precalculate the vertexmap/locationmap ratio for use in the for loop below //float vertexmapToObjectmapRelationship = Statics_Engine.TerrainSettings.vertexMapSize / locationMap.Width; //// Create a ruler 1 terrain mod long (distance between verticies //float terrainModWidth = Statics_Engine.TerrainSettings.terrainScaleFactor * vertexmapToObjectmapRelationship; //// Get the color value of the node //int mapColorR = int.Parse(node.Attributes["red"].Value); //int mapColorG = int.Parse(node.Attributes["green"].Value); //int mapColorB = int.Parse(node.Attributes["blue"].Value); //Vector3 scale = new Vector3((int)(float.Parse(node.Attributes["maxScale"].Value))); //float massValue = float.Parse(node.Attributes["mass"].Value); //isCollectable = bool.Parse(node.Attributes["isCollectable"].Value); //isKey = bool.Parse(node.Attributes["isKey"].Value); //// For each pixel of the treeMap //for (int l = 0; l < length; l++) //{ // // If the color matches create a prop // if (locationColorValues[l].R == mapColorR && locationColorValues[l].G == mapColorG && locationColorValues[l].B == mapColorB) // { // // Get the 2D location from 1D array // int h = l % locationMap.Width; // int w = (int)l / locationMap.Width; // // Start Type properties // //gameObject.mass.objectType = objectType; // mass.gameObjectPointer = this; // objectModelName = node.Attributes["name"].Value; // // Get terrain height at position // float yPosition = objectLibrary.terrain.GetTerrainHeight(w * vertexmapToObjectmapRelationship, // h * vertexmapToObjectmapRelationship); // // Set the object world properties // Vector3 locpos = new Vector3(w * terrainModWidth, yPosition, h * terrainModWidth); // Vector3 refpos = new Vector3(w * terrainModWidth, yPosition, h * terrainModWidth - 1); // mass.SetPosition(locpos, refpos); // mass.Rotate(0.0f, 0.0f); // mass.scale = scale; // mass.mass = massValue; // mass.isMoving = false; // if (isKey) // { // collisionWithPlayerResponse = Enums_Engine.CollisionResponses.HEALTHBONUS; // } // } //} //return true; #endregion } /// /// Load model data from XML /// /// The model xml node corresponding to this object /// public bool LoadModel(XmlNode node) { try { this.name = node.Attributes["name"].Value; this.maxScale = node.Attributes["maxScale"].Value; this.animated = node.Attributes["animated"].Value; grid = GridType.unit; if (node.Attributes["grid"] != null) { switch (node.Attributes["grid"].Value) { case "unit": grid = GridType.unit; break; case "tile": grid = GridType.tile; break; case "coord": grid = GridType.coord; break; default: grid = GridType.unit; break; } } // Load Textures and Model draw = new Draw(); draw.textureList.Clear(); this.texture = node.Attributes["texture"].Value; this.bumpTexture = node.Attributes["bumpTexture"].Value; this.model = node.Attributes["model"].Value; // Create Animation Transforms if (this.name == "ss3" || this.name == "dojogirl") { draw.initialTransform = Matrix.CreateRotationY((float)(-Math.PI / 2.0f)) * Matrix.CreateTranslation(new Vector3(0, -Statics_Engine.PlayerSettings.DEFAULT_PLAYER_HEIGHT / 2.0f, 0)); } else if (this.name == "bunny") { draw.initialTransform = Matrix.CreateTranslation(new Vector3(0, Statics_Engine.PlayerSettings.DEFAULT_PLAYER_HEIGHT, 0)); } else if (this.name == "fish") { draw.initialTransform = Matrix.CreateRotationY((float)(-Math.PI)) * Matrix.CreateTranslation(new Vector3(0, -Statics_Engine.PlayerSettings.DEFAULT_PLAYER_HEIGHT / 2.0f + 5, 0)); } else { draw.initialTransform = Matrix.Identity; } return true; } catch { return false; } } /// /// Runs the appropriate animation on the model /// /// The animation to run public void RunController(AnimationController controller) { foreach (BonePose p in animator.BonePoses) { p.CurrentController = (IAnimationController)controller; p.CurrentBlendController = null; } currentAnimation = controller; } /// /// Update this object /// /// ObjectLibrary public virtual void Update(ref ObjectLibrary objectLibrary) { mass.Update(); mass.boundingVolume.UpdateSphere(mass.currentPosition); } /// /// Method called when the motion buttons have been pressed /// /// Vector 2 amount of translation to induce public virtual void Translate(Vector2 value) { mass.MoveObject(value.Y, value.X); } /// /// Method called when the rotation buttons have been pressed /// /// Vector 2 amount of rotation public virtual void Rotate(Vector2 value) { mass.Rotate(value.Y, value.X); } /// /// Prepare to fire the particle /// /// ID of player who fired this particle /// Type of particle /// Starting position /// Normal direction of particle /// Mass of particle /// Themal value of particle public void PrepAttack(int playerID, Vector3 initialPosition, Vector3 direction) { //particleType = type; mass.AddForce(direction * Statics_Engine.PlayerSettings.DIRECT_ATTACK_FORCE); mass.SetPosition(initialPosition + (Statics_Engine.PlayerSettings.PARTICLE_START_DISTANCE * direction), initialPosition + ((Statics_Engine.PlayerSettings.PARTICLE_START_DISTANCE + 10) * direction)); mass.lastPosition = Vector3.Zero + initialPosition; //ownerID = playerID; direction.Normalize(); mass.normalVector = Vector3.Zero + direction; // Scale size of particle; Apply DPad Values between 1 and 75 mass.scale = new Vector3(75 / 2250.0f + 3); mass.boundingVolume.radius = mass.scale.Y; mass.boundingVolume.UpdateSphere(mass.currentPosition); // Change Engergy of particle; Shift from 0 to 100 to -1 to 1 mass.energy = ((float)100 * 2 - 75) / 75; if (mass.energy != 0.0f) { mass.isChanging = true; } } /// /// Default behavior applies force based physics for rebound. /// Override to supplement behavior. /// Return true if collidedObject is absorbed or destroyed, else false. /// /// GameObject that collided with this GameObject. /// The force applied by the colliding GameObject to this GameObject /// ObjectLibrary that this object belongs to. /// True = this object has to be recycled public virtual bool ObjectCollisionResponse(GameObject collidedObject, Vector3 resultantForce, ObjectLibrary objectLibrary) { mass.numberOfCollision++; mass.isMoving = true; return false; } /// /// Default behavior applies force based physics for rebound. /// Override to supplement or replace behavior. /// /// A copy of the terrain, provided for overrides public virtual void TerrainCollisionResponse(Terrain terrain) { CalculateVectorComponents(surfaceNormal, Statics_Engine.GameSettings.accelDueToGravity); gravityNormalComponent = normalComponent + Vector3.Zero; gravityTangentialComponent = tangentialComponent + Vector3.Zero; // Calculate the components of velocity with reference to the surface normal CalculateVectorComponents(surfaceNormal, mass.velocity); velocityNormalComponent = normalComponent + Vector3.Zero; velocityTangentialComponent = tangentialComponent + Vector3.Zero; // Calculate the components of totalForce with reference to the surface normal CalculateVectorComponents(surfaceNormal, mass.totalForce); totalForceNormalComponent = normalComponent + Vector3.Zero; totalForceTangentialComponent = tangentialComponent + Vector3.Zero; // Calculate normal and tangential forces with reference to the their components combinedNormalForce = (mass.mass * velocityNormalComponent / Statics_Engine.SystemSettings.dt) + totalForceNormalComponent; combinedTangentialForce = (mass.mass * velocityTangentialComponent / Statics_Engine.SystemSettings.dt) + totalForceTangentialComponent + (mass.mass * gravityTangentialComponent); mass.numberOfCollision++; } /// /// Calculate components of collision. /// /// Normal of surface that is being collided against. /// Velocity of this GameObject. private void CalculateVectorComponents(Vector3 surfaceNormal, Vector3 objectVelocity) { if (objectVelocity.Length() >= 0.01f || !float.IsInfinity(objectVelocity.Length())) { normalComponent = Vector3.Dot(objectVelocity, surfaceNormal) * surfaceNormal; tangentialComponent = objectVelocity - normalComponent; } else { // Object velocity is equal to zero so set both components to zero normalComponent = Vector3.Zero; tangentialComponent = Vector3.Zero; } } /// /// Sets the heightDifference parameter for this GameObject. /// HeightDifference is positive when object is below the terrain. /// /// Terrain object to determine height difference with. public void GetObjectHeight(Terrain terrain) { // Used to calculate the average terrain height around the player localTerrainHeight = 0; // Error check mass.EnforceLevelBoundary(); // Get X and Z positions int posX = (int)mass.currentPosition.X; int posZ = (int)mass.currentPosition.Z; // Add up all neighboring terrain points localTerrainHeight = terrain.GetTerrainHeight(posX / Statics_Engine.TerrainSettings.terrainScaleFactor, posZ / Statics_Engine.TerrainSettings.terrainScaleFactor); surfaceNormal = terrain.GetTerrainNormal(posX / Statics_Engine.TerrainSettings.terrainScaleFactor, posZ / Statics_Engine.TerrainSettings.terrainScaleFactor, mass.velocity); // Average all the neighboring terrain points float newHeight = localTerrainHeight + (mass.objectHeight / 2); // Get difference between average and player heightDifference = newHeight - mass.currentPosition.Y; } /// /// Draws a stand alone model with no instancing or triangle stripping. /// public virtual Draw Draw() { return this.draw; } /// /// Draws the model for ai vision /// public virtual void DrawAIVision() { } /// /// Called after Draw method. /// Allows GameObjects to add Billboards to be drawn. /// List is cleared each pass, or frame. /// /// ObjectLibrary that this object belongs to. /// Dynamic Billboard list. public virtual void Draw_Billboards(ObjectLibrary objectLibrary, BillboardList gameObjectBillboards) { } public virtual XmlNode ToXml() { // Update Xml Node and Return it //this.node.Name = this.type; this._node.Attributes["name"].Value = this._name; if (this._node.Attributes["typeID"] != null) { this._node.Attributes["typeID"].Value = this._typeID; } this._node.Attributes["id"].Value = this._id; this._node.Attributes["x"].Value = this._x; this._node.Attributes["z"].Value = this._z; this._node.Attributes["grid"].Value = this._grid.ToString(); this._node.Attributes["model"].Value = this._model; this._node.Attributes["texture"].Value = this._texture; this._node.Attributes["bumpTexture"].Value = this._bumpTexture; this._node.Attributes["maxScale"].Value = this._maxScale; this._node.Attributes["animated"].Value = this._animated; return this.node; //string xml = // "\n" + // "<" + this.type + " " + // " typeID=\"" + this.typeID + "\"" + // " id=\"" + this.id + "\"" + // " name=\"" + this.name + "\"" + // " x=\"" + this.x + "\"" + // " z=\"" + this.z + "\"" + // " grid=\"" + this.grid.ToString() + "\"" + // " model=\"" + this.model + "\"" + // " texture=\"" + this.texture + "\"" + // " bumpTexture=\"" + this.bumpTexture + "\"" + // " maxScale=\"" + this.maxScale + "\"" + // " animated=\"" + this.animated + "\"" + // "/>" + // "\n"; //return xml; //switch (_grid) //{ // case GridType.unit: // return "unit"; // break; // case GridType.tile: // return "tile"; // break; // case GridType.coord: // return "coord"; // break; // default: // return "unit"; // break; //} } #endregion } } #region Legacy Code - Heat dissipation and State Change /* Legacy Code // Test Function to update energy distribution public void UpdateHeatDissipation(ObjectLibrary objectLibrary, float dt) { List newParticlesToAddToList = new List(); foreach (Particle particle in particles) { particle.mass.UpdatePosition(dt); } // Iterate through dynamic particles for (int i = 0; i < particles.Count; i++) { Particle particle = particles[i]; // List to store the pointers to neighboring particles List neighboringParticleList = new List(); // Used to calculate the average value of all neighboring particles float averageEnergy = particle.mass.energy; // Get the list of neighboring particle pointers neighboringParticleList = GetSurroundingParticles(particle.mass.currentPosition, objectLibrary); // Calculate their total energy foreach (Particle neigborParticle in neighboringParticleList) { averageEnergy += neigborParticle.mass.energy; } // Find the average averageEnergy /= neighboringParticleList.Count + 1; // If the average value is not equal to zero then we have some heat dissipation to do if (averageEnergy != particle.mass.energy && neighboringParticleList.Count != 0) { // Iterate through neighboring particles foreach (Particle neigborParticle in neighboringParticleList) { // If their value is not equal to the average set it and set the flag if (neigborParticle.mass.energy != averageEnergy) { neigborParticle.mass.SetEnergy(averageEnergy); if (!neigborParticle.mass.isChanging) { neigborParticle.mass.isChanging = true; newParticlesToAddToList.Add(neigborParticle); } } } // Set the starting particle's energy to average value as well particle.mass.SetEnergy(averageEnergy); } else if (particle.mass.energy != 0.0f) { DissipateHeat(particle); } else { // The particle and it's neighbors are in equilibrium so remove it from the list particle.mass.isChanging = false; if (!particle.mass.isMoving) { // Particle needs to be put back into the static list MoveParticle(particles, particles, particle); } else { particles.Remove(particle); } i--; } } foreach (Particle newParticle in newParticlesToAddToList) { if (particles.Contains(newParticle)) { continue; } if (newParticle.mass.isMoving) { CopyParticle(particles, particles, newParticle); } else { MoveParticle(particles, particles, newParticle); } } } public void StateChange(ObjectLibrary objectLibrary, float elementUse, GameObject gameObject) { Particle particle = (Particle)gameObject; gameObject.mass.ChangeEnergy(elementUse / 2.0f); if (gameObject.mass.isChanging) { return; } else if (gameObject.mass.isMoving) { // Particle is in the dynamic list so we need to copy it to the Thermal list switch (particle.particleType) { case Particle.ParticleType.Air: { objectLibrary.particleManager.air.CopyParticle(objectLibrary.particleManager.air.dynamicParticles, objectLibrary.particleManager.air.thermalParticles, particle); break; } case Particle.ParticleType.Water: { objectLibrary.particleManager.water.CopyParticle(objectLibrary.particleManager.water.dynamicParticles, objectLibrary.particleManager.water.thermalParticles, particle); break; } case Particle.ParticleType.Earth: { objectLibrary.particleManager.earth.CopyParticle(objectLibrary.particleManager.earth.dynamicParticles, objectLibrary.particleManager.earth.thermalParticles, particle); break; } } gameObject.mass.isChanging = true; } else { // It's in the static list, so move the particle to the dynamic list switch (particle.particleType) { case Particle.ParticleType.Air: { objectLibrary.particleManager.air.MoveParticle(objectLibrary.particleManager.air.staticParticles, objectLibrary.particleManager.air.thermalParticles, particle); break; } case Particle.ParticleType.Water: { objectLibrary.particleManager.water.MoveParticle(objectLibrary.particleManager.water.staticParticles, objectLibrary.particleManager.water.thermalParticles, particle); break; } case Particle.ParticleType.Earth: { objectLibrary.particleManager.earth.MoveParticle(objectLibrary.particleManager.earth.staticParticles, objectLibrary.particleManager.earth.thermalParticles, particle); break; } } gameObject.mass.isChanging = true; } } */ #endregion