//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
#define forPC
namespace DarkWynter.Engine.ObjectLib
{
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.Xml;
using System.Diagnostics;
using System.Threading;
#endregion
using Audio;
using Physics;
using Globals;
using GameObjects;
using EventControl;
using DarkWynter.Engine.Utilities;
using DarkWynter.Stream.PhysicsGpu;
using DarkWynter.Stream;
using System.Reflection;
using System.ComponentModel;
using DarkWynter.Stream.UIInterfacing;
using System.Windows.Forms;
///
/// Container and Manager class for GameObjects
///
public class ObjectLibrary
{
#region Attributes
// STANDARD OBJECTS =================================================
///
/// Terrain object.
///
[EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public Terrain terrain { get { return _terrain; } set { _terrain = value; } }
public Terrain _terrain;
///
/// A list of all Human Players
///
[EditorAttribute(typeof(ListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List humans { get { return _humans; } set { _humans = value; } }
public List _humans;
///
/// A list of opponent AI Players
///
[EditorAttribute(typeof(ListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List bots { get { return _bots; } set { _bots = value; } }
public List _bots;
// GENERIC OBJECTS =================================================
///
/// Billboards requested by GameObjects
///
[EditorAttribute(typeof(ListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List billboards { get { return _billboards; } set { _billboards = value; } }
public List _billboards;
///
/// User Supplied GameObjects
///
[EditorAttribute(typeof(ListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List gameObjectList { get { return _gameObjectList; } set { _gameObjectList = value; } }
public List _gameObjectList;
///
/// Cpu-based Props Loaded from XML
///
[EditorAttribute(typeof(ListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List propLists { get { return _propLists; } set { _propLists = value; } }
public List _propLists;
///
/// Gpu-based Props Loaded from XML
///
[EditorAttribute(typeof(ListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List gpuObjectLists { get { return _gpuObjectLists; } set { _gpuObjectLists = value; } }
public List _gpuObjectLists;
///
/// 3D Visualization of Game Events
/// Mostly for debugging...
///
[EditorAttribute(typeof(ListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List gameEvents { get { return _gameEvents; } set { _gameEvents = value; } }
public List _gameEvents;
[EditorAttribute(typeof(ListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List _types { get { return types; } set { types = value; } }
public static List types;
///
/// Drawn on HUD to identify AI at a distance.
///
private Texture2D enemyTargetReticle;
#endregion
///
/// All nodes contained in the currently loaded level xml file
///
public static XmlNode levelXmlNode;
public static string levelName;
public static float vertMapToLocMapRelate;
public static float terrainModWidth;
private List _objectNames;
public List objectNames
{
get
{
List names = new List();
if (terrain != null)
{
names.Add(terrain.name);
}
for (int i = 0; i < humans.Count; i++)
{
names.Add(humans[i].name);
}
for (int i = 0; i < bots.Count; i++)
{
names.Add(bots[i].name);
}
for (int i = 0; i < gameObjectList.Count; i++)
{
names.Add(gameObjectList[i].name);
}
for (int i = 0; i < propLists.Count; i++)
{
names.Add(propLists[i].name);
}
for (int i = 0; i < gpuObjectLists.Count; i++)
{
names.Add(gpuObjectLists[i].name);
}
return names;
}
}
///
/// CONSTRUCTOR:
///
public ObjectLibrary()
{
bots = new List();
billboards = new List();
gameObjectList = new List();
propLists = new List();
gpuObjectLists = new List();
gameEvents = new List();
humans = new List();
humans.Add(new Player());
humans[0].playerIndex = 0;
ObjectLibrary.LoadAssemblyTypes("DWEngine.dll");
ObjectLibrary.LoadAssemblyTypes("DWStream.dll");
}
public static void LoadAssemblyTypes(string assemblyName)
{
if (types == null)
types = new List();
try
{
string path = System.IO.Directory.GetCurrentDirectory() + "\\";
types.AddRange(Assembly.LoadFile(path + assemblyName).GetTypes());
}
// Catch all loading exceptions and print message to user.
catch (Exception e)
{
MessageBox.Show(e.Message);
DarkWynterEngine.ContentInstall_WarningMessage();
throw new Exception("Error Loading GameObject");
}
}
#region Load Methods
///
/// Creates an instance of a GameObject using GameObject constructor parameters.
///
/// The string-literal class name of the GameObject. EG- "Terrain"
/// Constructor parameters, usually empty or using the Load object.
///
public static GameObject CreateGameObject(string objectName, object[] parameters)
{
GameObject gameObject = new GameObject();
for (int i = 0; i < types.Count; i++)
{
if (types[i].Name == objectName)
{
try
{
gameObject = (GameObject)Activator.CreateInstance(types[i], parameters);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
DarkWynterEngine.ContentInstall_WarningMessage();
}
}
}
return gameObject;
}
///
/// Load the Terrain and Skysphere for the Terrain Demo
///
public void LoadLevel(string levelXML)
{
// Reset load level flag
Statics_Engine.GameSettings.LoadLevel = false;
humans = new List();
bots = new List();
billboards = new List();
gameObjectList = new List();
propLists = new List();
gpuObjectLists = new List();
// Read the Level File
try
{
XmlDocument reader = new XmlDocument();
String fileLocation = levelXML;
reader.Load(fileLocation);
// Get all outer nodes (incl xml version info and level)
XmlNodeList allNodes = reader.ChildNodes;
foreach (XmlNode levelNode in allNodes)
{
// If level definition
if (levelNode.Name == "level")
{
levelXmlNode = levelNode;
// Parse Level
Load_Environment(levelNode);
// Load Solo Objects
Load_SoloObjects(levelNode);
// Load Location Map Objects
Load_LocationMap(levelNode);
// Load Level Events
Load_Events(levelNode);
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
DarkWynterEngine.ContentInstall_WarningMessage();
throw new Exception("Error Loading Level");
}
foreach (PropList propList in propLists)
{
propList.Load(this);
}
foreach (GpuObjectList gpuList in gpuObjectLists)
{
gpuList.Load(this);
}
#region Old GameObject Creation
//// Terrain
//if (XML.gameObjectInfo.terrainNode != null)
//{
// terrain = new Terrain();
// terrain.Load(XML.gameObjectInfo.terrainNode, this);
//}
//// Load Audio
//if (XML.gameObjectInfo.musicNode != null)
//{
// Audio.LoadXML(XML.gameObjectInfo.musicNode);
//}
//// Game Objects - Single Depth List
//gameObjectList = new List();
//if (XML.gameObjectInfo.gameObjectNodes != null)
//{
// for(int i=0; i< XML.gameObjectInfo.gameObjectNodes.Count; i++)
// {
// XmlNode objectNode = XML.gameObjectInfo.gameObjectNodes[i];
// GameObject gameObject = new GameObject();
// if (CreateGameObjectType(objectNode, ref gameObject))
// {
// if (gameObject.Load(objectNode, this))
// {
// gameObjectList.Add(gameObject);
// }
// }
// }
//}
//// Props - List of Lists
//propLists = new List();
//if (XML.gameObjectInfo.propNode != null)
//{
// for (int i = 0; i < XML.gameObjectInfo.propNode.Count; i++)
// {
// PropList propList = new PropList();
// if (propList.Load(XML.gameObjectInfo.propNode[i], this))
// {
// propLists.Add(propList);
// }
// }
//}
//// GpuObjects - List of Lists
//gpuObjectLists = new List();
//if (XML.gameObjectInfo.gpuObjectNodes != null)
//{
// for(int i=0; i< XML.gameObjectInfo.gpuObjectNodes.Count; i++)
// {
// XmlNode objectNode = XML.gameObjectInfo.gpuObjectNodes[i];
// GpuObjectList gpuObjectList = new GpuObjectList();
// gpuObjectList.Load(objectNode, this);
// gpuObjectLists.Add(gpuObjectList);
// }
//}
//// Props Billboards - ( Dynamic GameObject Billboards handled in Draw_Billboards)
//billboards = new List();
//if (XML.gameObjectInfo.billboardNode != null)
//{
// foreach (XmlNode objectNode in XML.gameObjectInfo.billboardNode.ChildNodes)
// {
// BillboardList billboardList = new BillboardList();
// billboardList.Load(objectNode, this);
// billboards.Add(billboardList);
// }
//}
//// Humans
//humans = new List();
//if (XML.gameObjectInfo.humanNodes != null)
//{
// for (int i = 0; i < Statics_Engine.SystemSettings.TOTAL_PLAYERS; i++)
// {
// XmlNode objectNode = XML.gameObjectInfo.humanNodes[i];
// GameObject gameObject = new GameObject();
// if (CreateGameObjectType(objectNode, ref gameObject))
// {
// if (gameObject.Load(objectNode, this))
// {
// humans.Add((Player)gameObject);
// }
// }
// }
//}
//// Bots
//bots = new List();
//if (XML.gameObjectInfo.botNodes != null)
//{
// for (int i = 0; i < Statics_Engine.GameSettings.botCount; i++)
// {
// XmlNode objectNode = XML.gameObjectInfo.botNodes[i];
// GameObject gameObject = new GameObject();
// if (CreateGameObjectType(objectNode, ref gameObject))
// {
// if (gameObject.Load(objectNode, this))
// {
// bots.Add((Player)gameObject);
// }
// }
// }
//}
#endregion
// Give life to the humans based on the number of active players selected in Game Setup
for (int i = 0; i < humans.Count; i++)
{
humans[i].health = 100.0f;
humans[i].manna = 100.0f;
}
// Mark each AI with a targeting icons
enemyTargetReticle = Statics_Engine.SystemSettings.content.Load("Content/_textures/TargetMarker");
// Start Game Timer
Statics_Engine.LevelSettings.gameTimer = new Stopwatch();
Statics_Engine.LevelSettings.gameTimer.Start();
Statics_Engine.LevelSettings.ViewportSize = new Vector2(
Statics_Stream.RenderSettings.cameraList[0].viewport.Width,
Statics_Stream.RenderSettings.cameraList[0].viewport.Height);
// Switch into Game Mode processing
Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.GAME_MODE;
}
private void Load_Environment(XmlNode levelNode)
{
// Get Level and LocationMap names
levelName = levelNode.Attributes["name"].Value;
// Cycle through XmlNodes
for (int loadCount = 0; loadCount < levelNode.ChildNodes.Count; loadCount++)
{
XmlNode node = levelNode.ChildNodes[loadCount];
// Terrain Size
if (node.Name == "Terrain")
{
Texture2D terrain = Statics_Engine.SystemSettings.content.Load(node.Attributes["heightmap"].Value);
Statics_Engine.TerrainSettings.vertexMapSize = terrain.Width;
// Calculate the vertexmap/locationmap ratio for use in the for loop below
vertMapToLocMapRelate = Statics_Engine.TerrainSettings.vertexMapSize /
float.Parse(levelNode.Attributes["locationMapSize"].Value);
// Create a ruler 1 terrain mod long (distance between verticies
terrainModWidth = Statics_Engine.TerrainSettings.terrainScaleFactor * vertMapToLocMapRelate;
}
// Audio
if (node.Name == "Music")
{
Audio.LoadXML(node);
}
// Dimensions
else if (node.Name == "Dimensions")
{
Statics_Engine.TerrainSettings.terrainScaleFactor = int.Parse(node.Attributes["scale"].Value);
}
// Physics
else if (node.Name == "Physics")
{
Statics_Engine.GameSettings.accelDueToGravity = new Vector3(0.0f, Statics_Engine.GameSettings.gravityForce, 0.0f);
Statics_Engine.GameSettings.gravityForce = float.Parse(node.Attributes["gravity"].Value);
Statics_Engine.LevelSettings.TERRAIN_FRICTION = float.Parse(node.Attributes["friction"].Value);
}
// Fog
else if (node.Name == "Fog")
{
Statics_Engine.LevelSettings.fogDensity = float.Parse(node.Attributes["density"].Value);
Statics_Engine.LevelSettings.fogStart = float.Parse(node.Attributes["startfog"].Value);
Statics_Engine.LevelSettings.fogEnd = float.Parse(node.Attributes["endfog"].Value);
Statics_Engine.LevelSettings.fogColor[0] = float.Parse(node.Attributes["red"].Value);
Statics_Engine.LevelSettings.fogColor[1] = float.Parse(node.Attributes["green"].Value);
Statics_Engine.LevelSettings.fogColor[2] = float.Parse(node.Attributes["blue"].Value);
Statics_Engine.LevelSettings.fogColor[3] = float.Parse(node.Attributes["alpha"].Value);
}
}
}
private void Load_SoloObjects(XmlNode levelNode)
{
List soloObjects = new List();
// Check each Object Node for a match
for (int nodeCount = 0; nodeCount < levelNode.ChildNodes.Count; nodeCount++)
{
XmlNode node = levelNode.ChildNodes[nodeCount];
// If Node contains x,y,z coordinates
if (node.Attributes != null &&
node.Attributes["x"] != null && node.Attributes["z"] != null)
{
// Get the Node's location value
float x = float.Parse(node.Attributes["x"].Value);
float y = 255.0f;
float z = float.Parse(node.Attributes["z"].Value);
// Create Object or continue
GameObject gameObject = ObjectLibrary.CreateGameObject(node.LocalName, new object[] { node, new Vector3(x, y, z) });
// Read by ObjectLibrary::Load
soloObjects.Add(gameObject);
}
}
// Load Terrain First
for (int i = 0; i < soloObjects.Count; i++)
{
// Load GameObject
GameObject gameObject = soloObjects[i];
if (gameObject is Terrain)
{
gameObject.Load(this);
terrain = gameObject as Terrain;
}
}
// Load Solo Objects
for (int i = 0; i < soloObjects.Count; i++)
{
// Load GameObject
GameObject gameObject = soloObjects[i];
// Generic object
if (!(gameObject is Terrain))
{
// Players
gameObject.Load(this);
if (gameObject.node.Name == "Human")
humans.Add(gameObject as Player);
else if (gameObject.node.Name == "Bot")
bots.Add(gameObject as Player);
else
{
gameObjectList.Add(gameObject);
}
}
}
}
private void Load_LocationMap(XmlNode levelNode)
{
List locationMapObjects = new List();
Random rand = new Random();
// Check each Object Node for a match
for (int nodeCount = 0; nodeCount < levelNode.ChildNodes.Count; nodeCount++)
{
XmlNode node = levelNode.ChildNodes[nodeCount];
// Only get Nodes that contain x,y,z coordinates
if (node.Attributes != null &&
node.Attributes["red"] != null &&
node.Attributes["green"] != null &&
node.Attributes["blue"] != null)
{
// Open Location Map
if (node.Attributes["locationMap"] != null)
{
// Linearize pixels in location map
Texture2D locationMap = Statics_Engine.SystemSettings.content.Load(node.Attributes["locationMap"].Value);
Color[] pixels = new Color[locationMap.Width * locationMap.Width];
locationMap.GetData(pixels);
// Process Pixels from LocationMap
for (int pixelCount = 0; pixelCount < pixels.Length; pixelCount++)
{
Color currentPixel = pixels[pixelCount];
// Skip this pixel if blank, or empty
if (currentPixel == Color.Black || currentPixel == Color.White)
continue;
// Get 2D Position from 1D array
// Y is set during GameObject.Load()
Vector3 startPosition = new Vector3(((int)pixelCount / locationMap.Width) * Statics_Engine.TerrainSettings.terrainScaleFactor,
0.0f,
(pixelCount % locationMap.Width) * Statics_Engine.TerrainSettings.terrainScaleFactor);
// Create Object or continue
GameObject gameObject = ObjectLibrary.CreateGameObject(node.LocalName, new object[] { node, startPosition });
// Read by ObjectLibrary::Load
locationMapObjects.Add(gameObject);
}
}
}
}
for (int i = 0; i < locationMapObjects.Count; i++)
{
// Load GameObject
GameObject gameObject = locationMapObjects[i];
// Generic Lists
if (gameObject is IBillboard)
{
gameObject.Load(this);
//billboards.Add(gameObject as BillboardList);
}
else if (gameObject is IProp)
{
gameObject.Load(this);
// Randomly orient object (better asthetics)
gameObject.mass.Rotate(0, (float)(rand.NextDouble() * Math.PI * 2));
// Check existing prop lists
bool found = false;
for (int j = 0; j < propLists.Count; j++)
{
// Add GameObject to existing propList
if (gameObject.objectModelName == propLists[j].objectModelName)
{
propLists[j].AddNewObject(gameObject);
found = true;
break;
}
}
if (!found)
{
// Create new prop list for this type
PropList propList = new PropList(gameObject.node, gameObject.startPosition);
propList.AddNewObject(gameObject);
propList.objectModelName = gameObject.objectModelName;
propLists.Add(propList);
}
}
else if (gameObject is IGpuObject)
{
gameObject.Load(this);
// Check existing lists
bool found = false;
for (int j = 0; j < gpuObjectLists.Count; j++)
{
if (gameObject.objectModelName == gpuObjectLists[j].objectModelName)
{
gpuObjectLists[j].AddNewObject(gameObject, false);
found = true;
break;
}
}
if (!found)
{
GpuObjectList gpuObjectList = new GpuObjectList(gameObject.node, gameObject.startPosition);
gpuObjectList.AddNewObject(gameObject, false);
gpuObjectList.objectModelName = gameObject.objectModelName;
gpuObjectLists.Add(gpuObjectList);
}
}
else if (gameObject is GameObject && !(gameObject is Terrain))
{
gameObject.Load(this);
gameObjectList.Add(gameObject);
}
}
}
private void Load_Events(XmlNode levelNode)
{
// Cycle through XmlNodes
for (int loadCount = 0; loadCount < levelNode.ChildNodes.Count; loadCount++)
{
XmlNode node = levelNode.ChildNodes[loadCount];
// Terrain Size
if (node.Name == "events")
{
// Load Event System XML
GameEventHandler.LoadEventsXml(node.Attributes["xmlFile"].Value);
}
}
}
#endregion
public GameObject GetGameObject(string name)
{
GameObject gameObject = new GameObject();
if (terrain.name == name)
return terrain;
for (int i = 0; i < humans.Count; i++)
{
if (humans[i].name == name)
{
return humans[i];
}
}
for (int i = 0; i < bots.Count; i++)
{
if (bots[i].name == name)
{
return bots[i];
}
}
for (int i = 0; i < gameObjectList.Count; i++)
{
if (gameObjectList[i].name == name)
{
return gameObjectList[i];
}
}
for (int i = 0; i < propLists.Count; i++)
{
if (propLists[i].name == name)
{
return propLists[i];
}
}
for (int i = 0; i < gpuObjectLists.Count; i++)
{
if (gpuObjectLists[i].name == name)
{
return gpuObjectLists[i];
}
}
return gameObject;
}
#region Save Methods
///
/// Save the Level.
///
///
public XmlDocument ToXml()
{
// Clear Dirty level node
levelXmlNode.RemoveAll();
// Write out Level
//levelXmlNode.AppendChild(terrain.ToXml());
for (int i = 0; i < humans.Count; i++)
{
levelXmlNode.AppendChild(humans[i].ToXml());
}
for (int i = 0; i < bots.Count; i++)
{
levelXmlNode.AppendChild(bots[i].ToXml());
}
for (int i = 0; i < gameObjectList.Count; i++)
{
levelXmlNode.AppendChild(gameObjectList[i].ToXml());
}
for (int i = 0; i < propLists.Count; i++)
{
levelXmlNode.AppendChild(propLists[i].ToXml());
}
for (int i = 0; i < gpuObjectLists.Count; i++)
{
levelXmlNode.AppendChild(gpuObjectLists[i].ToXml());
}
// Create Writer
XmlDocument xmlDoc = new XmlDocument();
// Append XML declaration to Doc
xmlDoc.AppendChild(xmlDoc.CreateNode(XmlNodeType.XmlDeclaration, "", ""));
// Create root level element
XmlElement xmlRootElement = xmlDoc.CreateElement("", "level", "");
// Append Level GameObjects to root
xmlRootElement.AppendChild(levelXmlNode);
// Append Root to Doc
xmlDoc.AppendChild(xmlRootElement);
return xmlDoc;
}
#endregion
#region Update Methods
///
/// Call all GameObject Updates to handle gravity and motion
///
/// ObjectLibrary
/// Collision
public void Update(ObjectLibrary objectLibrary, Collision collision)
{
// TEMP: ============================
// Remove when Scenegraph reinstalled
List collisionList = new List();
for (int i = 0; i < gameObjectList.Count; i++)
{
collisionList.Add(gameObjectList[i].mass);
}
for (int i = 0; i < humans.Count; i++)
{
collisionList.Add(humans[i].mass);
}
for (int i = 0; i < bots.Count; i++)
{
collisionList.Add(bots[i].mass);
}
// END TEMP ============================
// Collision Main Entry Point
collision.UpdateCollision(ref objectLibrary, collisionList);
// GameObject Update (incl Physics) Main Entry
terrain.Update(ref objectLibrary);
if (Statics_Engine.SystemSettings.WINDOW_IN_FOCUS)
{
for (int i = 0; i < humans.Count; i++)
{
humans[i].Update(ref objectLibrary);
}
}
for (int i = 0; i < bots.Count; i++)
{
bots[i].Update(ref objectLibrary);
}
for (int i = 0; i < gameObjectList.Count; i++)
{
gameObjectList[i].Update(ref objectLibrary);
}
for (int i = 0; i < propLists.Count; i++)
{
propLists[i].Update(ref objectLibrary);
}
for (int i = 0; i < gpuObjectLists.Count; i++)
{
gpuObjectLists[i].Update(this);
}
DarkWynterEngine._HUD.Update();
}
///
/// Remove a Game Object from our list of gameobjects
///
/// Game object to be removed
public void RemoveGameObject(GameObject gameObject)
{
gameObjectList.Remove(gameObject);
}
#endregion
#region Attack Methods
///
/// Player uses Attack Method to shoot Grenade-like objects onto the board
///
/// ID of the player who fired the grenade
/// Type of grenade
/// Starting position of the grenade
/// Normal direction of the grenade
/// Mass of grenade
/// Thermal value of grenade
public void Attack_Grenade(int playerID,
Enums_Engine.ParticleType type,
Vector3 initialPosition,
Vector3 direction)
{
for (int i = 0; i < levelXmlNode.ChildNodes.Count; i++)
{
if (levelXmlNode.ChildNodes[i].Name == "Grenade")
{
GameObject particle = new GameObject(levelXmlNode.ChildNodes[i], Vector3.Zero);
particle.Load(this);
particle.PrepAttack(playerID, initialPosition, direction);
gameObjectList.Add(particle);
}
}
}
///
/// Player uses Attack Method to shoot Bullet-like objects onto the board
///
/// ID of the player who fired the Bullet
/// Type of Bullet
/// Starting position of the Bullet
/// Normal direction of the Bullet
/// Mass of Bullet
/// Thermal value of Bullet
public void Attack_Bullet(int playerID,
Enums_Engine.BulletType type,
Vector3 initialPosition,
Vector3 direction,
int bulletMassValue,
int bulletThermalValue)
{
for (int i = 0; i < levelXmlNode.ChildNodes.Count; i++)
{
if (levelXmlNode.ChildNodes[i].Name == "Bullet")
{
GameObject bullet = new GameObject(levelXmlNode.ChildNodes[i], Vector3.Zero);
bullet.Load(this);
bullet.PrepAttack(playerID, initialPosition, direction);
gameObjectList.Add(bullet);
}
}
}
///
/// Player uses Attack Method to shoot gpu-based objects onto the board
///
/// ID of the player who fired the Swarm
/// Starting position of the Swarm
/// Normal direction of the Swarm
/// Mass of Swarm
/// Thermal value of Swarm
public void Attack_GpuParticle(int playerID, Vector3 initialPosition, Vector3 direction, int swarmMassValue, int swarmThermalValue)
{
for (int i = 0; i < levelXmlNode.ChildNodes.Count; i++)
{
if (levelXmlNode.ChildNodes[i].Name == "GpuObject")
{
XmlNode node = levelXmlNode.ChildNodes[i];
List burst = new List();
int GPU_BURST_RATE = swarmMassValue;
float GPU_BURST_RADIUS = 10.0f;
for (int j = 0; j < GPU_BURST_RATE; j++)
{
GameObject gameObject = ObjectLibrary.CreateGameObject(node.LocalName, new object[] { node, initialPosition });
Random rand = new Random();
Vector3 randomOffset = new Vector3((float)rand.NextDouble() * GPU_BURST_RADIUS,
(float)rand.NextDouble() * GPU_BURST_RADIUS,
(float)rand.NextDouble() * GPU_BURST_RADIUS);
initialPosition += randomOffset;
gameObject.Load(this);
// Set up Model Manager
string type = node.Attributes["name"].Value;
// Start Type properties
gameObject.mass.gameObjectPointer = gameObject;
gameObject.objectModelName = type;
// Set Position
gameObject.mass.SetPosition(initialPosition + (Statics_Engine.PlayerSettings.PARTICLE_START_DISTANCE * direction),
initialPosition + ((Statics_Engine.PlayerSettings.PARTICLE_START_DISTANCE - 10) * direction));
// Init Physics
gameObject.mass.boundingVolume = new BoundingVolume(new BoundingSphere(gameObject.mass.currentPosition, 2.0f));
gameObject.mass.velocity = Vector3.Zero;
gameObject.mass.acceleration = Vector3.Zero;
gameObject.mass.scale = new Vector3((int)(float.Parse(node.Attributes["maxScale"].Value)));
gameObject.mass.mass = float.Parse(node.Attributes["mass"].Value);
// Add Force
gameObject.mass.AddForce(direction * 10000.0f);
// Add mass(es)
burst.Add(gameObject.mass);
}
// Add mass(es)
if (burst.Count != 0)
{
// Check existing gpu lists
bool found = false;
for (int j = 0; j < gpuObjectLists.Count; j++)
{
if (burst[0].gameObjectPointer.objectModelName == gpuObjectLists[j].objectModelName)
{
gpuObjectLists[j].AddMass(burst);
found = true;
break;
}
}
if (!found)
{
// GPU lists do not contain this object type... so create a new list
GpuObjectList gpuObjectList = new GpuObjectList(burst[0].gameObjectPointer.node, burst[0].gameObjectPointer.startPosition);
gpuObjectList.AddMass(burst);
gpuObjectList.objectModelName = burst[0].gameObjectPointer.objectModelName;
gpuObjectLists.Add(gpuObjectList);
}
}
}
}
}
#endregion
#region Draw Methods
///
/// Draw and Postdrawing
///
/// Player for which draw perspective is associated.
public List Draw(int playerIndex)
{
if(Statics_Stream.RenderSettings.cameraList[playerIndex].mode == Camera.CameraMode.FirstPerson)
{
// Calculate the player's ModelView Matrix
Statics_Stream.RenderSettings.matrixView =
Statics_Stream.RenderSettings.cameraList[playerIndex].GetViewMatrix(humans[playerIndex].mass.currentPosition,
humans[playerIndex].mass.normalVector,
humans[playerIndex].mass.upVector,
humans[playerIndex].fpvEnabled);
}
else if (Statics_Stream.RenderSettings.cameraList[playerIndex].mode == Camera.CameraMode.FixedPosition)
{
Vector3 position = Statics_Stream.RenderSettings.cameraList[playerIndex].fixedPosition;
Vector3 normal = new Vector3(Statics_Engine.TerrainSettings.collisionMapSize/2, 0.0f,Statics_Engine.TerrainSettings.collisionMapSize/2) - position;
normal.Normalize();
Vector3 perpVec = new Vector3(-normal.Z, 0.0f, normal.X);
perpVec.Normalize();
Vector3 upVector = Vector3.Cross(perpVec, normal);
upVector.Normalize();
// Calculate the player's ModelView Matrix
Statics_Stream.RenderSettings.matrixView =
Statics_Stream.RenderSettings.cameraList[playerIndex].GetViewMatrix(
position,normal,upVector,humans[playerIndex].fpvEnabled);
}
// Calculate the player's Projection Matrix
Statics_Stream.RenderSettings.matrixProjection = Statics_Stream.RenderSettings.cameraList[playerIndex].GetProjectionMatrix();
// Pass Matricies to Shader
ShaderParameters.DrawFX.ViewProj.SetValue(Statics_Stream.RenderSettings.matrixView * Statics_Stream.RenderSettings.matrixProjection);
ShaderParameters.DrawFX.EyePostion.SetValue(Matrix.Invert(Statics_Stream.RenderSettings.matrixView));
// Send Lighting to the Shader
ShaderParameters.DrawFX.lightPosition0.SetValue(Statics_Engine.LevelSettings.lightPosition1);
ShaderParameters.DrawFX.lightAmbient0.SetValue(Statics_Engine.LevelSettings.lightAmbient1);
ShaderParameters.DrawFX.lightDiffuse0.SetValue(Statics_Engine.LevelSettings.lightDiffuse1);
ShaderParameters.DrawFX.lightSpecular0.SetValue(Statics_Engine.LevelSettings.lightSpecular1);
if (Statics_Engine.SystemSettings.singleLightSource)
{
ShaderParameters.DrawFX.lightPosition1.SetValue(Statics_Engine.LevelSettings.lightPosition1);
ShaderParameters.DrawFX.lightAmbient1.SetValue(Statics_Engine.LevelSettings.lightAmbient1);
ShaderParameters.DrawFX.lightDiffuse1.SetValue(Statics_Engine.LevelSettings.lightDiffuse1);
ShaderParameters.DrawFX.lightSpecular1.SetValue(Statics_Engine.LevelSettings.lightSpecular1);
}
else
{
ShaderParameters.DrawFX.lightPosition1.SetValue(Statics_Engine.LevelSettings.lightPosition2);
ShaderParameters.DrawFX.lightAmbient1.SetValue(Statics_Engine.LevelSettings.lightAmbient2);
ShaderParameters.DrawFX.lightDiffuse1.SetValue(Statics_Engine.LevelSettings.lightDiffuse2);
ShaderParameters.DrawFX.lightSpecular1.SetValue(Statics_Engine.LevelSettings.lightSpecular2);
}
ShaderParameters.DrawFX.fogEnd.SetValue(Statics_Engine.LevelSettings.fogEnd);
ShaderParameters.DrawFX.fogStart.SetValue(Statics_Engine.LevelSettings.fogStart);
// TerrainLOD and TerrainMod Shader Requisits
Statics_Engine.PlayerSettings.playerPosition = humans[playerIndex].mass.currentPosition;
Statics_Engine.PlayerSettings.playerLookVector = new Vector2(humans[playerIndex].mass.normalVector.X,
humans[playerIndex].mass.normalVector.Z);
Statics_Engine.PlayerSettings.playerRotation = humans[playerIndex].mass.currentRotation;
Statics_Engine.TerrainSettings.terrainLookAtPoint = humans[playerIndex].lookAtPoint;
Statics_Engine.TerrainSettings.terrainModRange = (int)(humans[playerIndex].attackMagnitude / 25);
Statics_Engine.TerrainSettings.terrainModEnabled = humans[playerIndex].terrainModEnabled;
List drawList = new List();
// Draw the terrain
drawList.Add(terrain.Draw());
// Draw Cpu Based Object Lists
for (int i = 0; i < propLists.Count; i++)
{
drawList.Add(propLists[i].Draw());
}
// Draw Gpu Based Object Lists
for (int i = 0; i < gpuObjectLists.Count; i++)
{
drawList.Add(gpuObjectLists[i].Draw());
}
// Draw AI
foreach (Player player in bots)
{
drawList.Add(player.Draw());
}
//// Draw Humans
//foreach (Player human in humans)
//{
// if (human.fpvEnabled && human == humans[playerIndex] && Camera.offset == Vector3.Zero)
// {
// continue;
// }
// drawList.Add(human.Draw());
//}
// Draw User Defined Game Objects
for (int i = 0; i < gameObjectList.Count; i++)
{
drawList.Add(gameObjectList[i].Draw());
}
// Draw Events
for (int i = 0; i < gameEvents.Count; i++)
{
List draw = gameEvents[i].Draw();
if (draw != null)
{
drawList.AddRange(draw);
}
}
// Draw AI Shields (NOTE: draw 2nd to last for transparency reasons)
foreach (Player player in bots)
{
if (player.IsAlive())
{
drawList.Add(player.DrawShield());
}
}
// Draw Human Shields (NOTE: draw last for transparency reasons)
foreach (Player player in humans)
{
if (player.IsAlive())
{
drawList.Add(player.DrawShield());
}
}
return drawList;
}
///
/// Pass a Billboard List to GameObjects so they can add GameObject-relative Billboards.
/// This does not effect the Prop Billboards.
///
/// Billboards are oriented towards the Player we are drawing them for.
public List Draw_Billboards(int playerIndex)
{
// Calculate the player's ModelView Matrix
Statics_Stream.RenderSettings.matrixView = Matrix.CreateLookAt(humans[playerIndex].mass.currentPosition,
humans[playerIndex].mass.currentPosition +
humans[playerIndex].mass.normalVector,
humans[playerIndex].mass.upVector);
// Calculate the player's Projection Matrix
Statics_Stream.RenderSettings.matrixProjection =
Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4,
Statics_Stream.RenderSettings.cameraList[playerIndex].viewport.Width / Statics_Stream.RenderSettings.cameraList[playerIndex].viewport.Height,
0.3f, 100000f);
// Create Empty List
BillboardList dynamicBillboards = new BillboardList();
// Draw the terrain
terrain.Draw_Billboards(this, dynamicBillboards);
//// Draw Cpu Based Object Lists
//for (int i = 0; i < propLists.Count; i++)
//{
// propLists[i].Draw_Billboards(this, ref gameObjectBillboards);
//}
//// Draw Gpu Based Object Lists
//for (int i = 0; i < gpuObjectLists.Count; i++)
//{
// gpuObjectLists[i].Draw_Billboards(this, ref gameObjectBillboards);
//}
// Draw User Defined Game Objects
for (int i = 0; i < gameObjectList.Count; i++)
{
// gameObjectList[i].Draw_Billboards(this, dynamicBillboards);
}
// Draw Humans
foreach (Player human in humans)
{
human.Draw_Billboards(this, dynamicBillboards);
}
// Draw AI
foreach (Player player in bots)
{
player.Draw_Billboards(this, dynamicBillboards);
}
// Draw all GameObject Billboards
return dynamicBillboards.Draw_Billboards(this, playerIndex);
}
///
/// Draw AI vision
///
/// AI's index
public void DrawAIVision(Vector3 aiCurrentPosition)
{
for (int i = 0; i < humans.Count; i++)
{
if (humans[i].IsAlive())
{
ShaderParameters.DrawFX.playerIndex.SetValue((i + 1) / 14.0f);
humans[i].DrawAIVision();
}
}
terrain.DrawAIVision(aiCurrentPosition);
}
///
/// Let each GameObject draw it's own Sprites
///
/// Current player's index
/// SpriteBatch used to draw
public void PostDraw_HUD(int currentPlayerIndex, SpriteBatch spriteBatch)
{
// Calculate the player's ModelView Matrix
Statics_Stream.RenderSettings.matrixView =
Statics_Stream.RenderSettings.cameraList[currentPlayerIndex].GetViewMatrix(humans[currentPlayerIndex].mass.currentPosition,
humans[currentPlayerIndex].mass.normalVector,
humans[currentPlayerIndex].mass.upVector,
humans[currentPlayerIndex].fpvEnabled);
Statics_Stream.RenderSettings.matrixProjection = Statics_Stream.RenderSettings.cameraList[currentPlayerIndex].GetProjectionMatrix();
// Post Draw HUD
DarkWynterEngine._HUD.Draw(spriteBatch);
// Mark Other Players
// -The further away the enemy is, the smaller and fainter the icon
// -scale range: 0.25-1.0, alpha range: 50-200
float distance = 0.0f; float distRatio = 0.0f; float totalScale = 0.25f;
Vector3 position = new Vector3();
// Draw AI bots
foreach (Player bot in bots)
{
if (bot.IsAlive())
{
// DrawEnemyTargets(currentPlayerIndex, spriteBatch, ref position, ref distance, ref distRatio, totalScale, bot);
}
}
// Draw Humans
foreach (Player player in humans)
{
if (player.IsAlive() && player != humans[currentPlayerIndex])
{
//DrawEnemyTargets(currentPlayerIndex, spriteBatch, ref position, ref distance, ref distRatio, totalScale, player);
}
}
}
private void DrawEnemyTargets(int currentPlayerIndex,
SpriteBatch spriteBatch,
ref Vector3 position,
ref float distance,
ref float distRatio,
float totalScale,
Player player)
{
distance = Vector3.Distance(player.mass.currentPosition, humans[currentPlayerIndex].mass.currentPosition);
if (distance > Statics_Engine.PlayerSettings.ENEMY_MARKER_MIN_DISTANCE)
{
position = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.Project(player.mass.currentPosition,
Statics_Stream.RenderSettings.matrixProjection,
Statics_Stream.RenderSettings.matrixView,
Matrix.Identity);
if (position.Z < 1)
{
position.X -= Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.X;
position.Y -= Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.Y;
if (position.X >= 0 && position.X < Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.Width &&
position.Y >= 0 && position.Y < Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.Height)
{
distRatio = 1.0f - (distance / Statics_Engine.PlayerSettings.ENEMY_MARKER_MAX_DISTANCE);
//if negative they are too far away
if (distRatio < 0)
{
distRatio = 0;
}
spriteBatch.Draw(enemyTargetReticle, new Rectangle((int)(position.X - (enemyTargetReticle.Width * distRatio * totalScale) / 2),
(int)(position.Y - (enemyTargetReticle.Height * distRatio * totalScale)),
(int)(enemyTargetReticle.Width * distRatio * totalScale),
(int)(enemyTargetReticle.Height * distRatio * totalScale)),
new Color(255, 255, 255, (byte)(200 * distRatio)));
}
}
}
}
#endregion
}
}
#region Legacy Code
/*
///
/// Function to reset our list of human players
///
public void DeinitializeHumans()
{
//be warned.. MUST call Statics.CheckForControllers after this!!
foreach (Human human in humans)
{
human.playerController.playerControllerType = Enums_Engine.ControllerType.NONE;
human.health = 0;
human.manna = 0;
}
}
public void GetDrawObjects()
{
for (int i = 0; i < humans.Count; i++)
{
if (humans[i].IsAlive())
{
lookupMap.GetDrawObjects(humans[i].mass, drawList[i]);
}
}
}
// 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;
}
}
public void UpdateLightPosition()
{
// Light goes 180 degrees back and forth (never below)
//if (Math.Abs(lightMoveAngle1) > Math.PI / 2.0f)
//{
// LIGHT_MOVE_SPEED1 = -LIGHT_MOVE_SPEED1;
//}
// Light goes full 360 degrees
// Update light source position
if (lightMoveAngle1 < 0)
{
//reset to 2PI
lightMoveAngle1 = Math.PI * 2.0f;
}
else if (lightMoveAngle1 > Math.PI * 2.0f)
{
//reset to zero
lightMoveAngle1 = 0.0f;
}
// Update the angle of the light
lightMoveAngle1 += LIGHT_MOVE_SPEED1;
//Calculate the X and Y based on the angle
float dx = (float)(lightDistance1 * Math.Sin(lightMoveAngle1));
float dz = (float)(lightDistance1 * Math.Cos(lightMoveAngle1));
lightInfo1.M11 = dx + (Statics.TerrainSettings.collisionMapSize / 2.0f);
lightInfo1.M13 = dz +(Statics.TerrainSettings.collisionMapSize / 2.0f);
}
*/
#endregion