//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// 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