//--------------------------------------------------------------------------------------------------------------------------------------------------- // <copyright file="Portal.cs" company="DarkWynter Studios"> // Copyright (C)2007 DarkWynter Studios. All rights reserved. // </copyright> //--------------------------------------------------------------------------------------------------------------------------------------------------- // {Contact : darkwynter.com for licensing information //--------------------------------------------------------------------------------------------------------------------------------------------------- namespace DarkWynter.Game.GameObjects { #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; #endregion using DarkWynter.Engine.Globals; using DarkWynter.Engine.Physics; using DarkWynter.Engine.ObjectLib; using DarkWynter.Engine.GameObjects; using DarkWynter.Engine.Init; using DarkWynter.Stream; /// <summary> /// An abstract door with locking mechanics. /// </summary> public class Portal : GameObject { private int portalID; private int health; private bool isLocked = true; private int fireIterator = 0; /// <summary> /// Portal constructor /// </summary> public Portal(Load gameObjectLoader) : base(gameObjectLoader) { mass.objectType = Enums_Engine.ObjectType.PORTAL; mass.dynamicFrictionCoefficient = 0.0f; mass.isMoving = true; } /// <summary> /// Override and supplament base loading in GameObject. /// </summary> /// <param name="node">XML node containing load data.</param> /// <param name="objectLibrary">ObjectLibrary that portal belongs to.</param> /// <returns>True if it was able to load, else false</returns> public override bool Load(ObjectLibrary objectLibrary) { // Call before user code is executed if (!base.Load(objectLibrary)) { return false; } draw.drawMethod = Enums_Stream.DrawMethod.BasicGameObject_Draw; draw.technique = "BasicLightingShaderMain"; //mass.boundingVolume = new BoundingVolume(new BoundingBox(mass.currentPosition - mass.scale, mass.currentPosition + mass.scale)); mass.boundingVolume = new BoundingVolume(new BoundingSphere(mass.currentPosition, 100.0f)); draw.textureList.Add(Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/FireRed")); //draw.textureList.Add(Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/FireDesert")); draw.textureList.Add(Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/FireBlue")); draw.textureList.Add(Statics_Engine.SystemSettings.content.Load<Texture2D>("Content/_textures/FireAir")); // Xml Parameters specific to object health = int.Parse(load.node.Attributes["portalHealth"].Value); return true; } /// <summary> /// Override and supplement base Update in GameObject. /// </summary> /// <param name="objectLibrary">ObjectLibrary that portal belongs to.</param> public override void Update(ref ObjectLibrary objectLibrary) { // Call before user code is executed base.Update(ref objectLibrary); // Update Collision Box : CLEAN : SCALE SHOULD BE 3 VALUES IN XML //mass.boundingVolume.UpdateBox(mass.currentPosition, mass.currentRotation, mass.scale * new Vector3(20.0f, 1000.0f, 1000.0f)); mass.boundingVolume.UpdateSphere(mass.currentPosition); // Fun with doors... //mass.Rotate(0.0f, 0.01f); //mass.AddForce(new Vector3(-10.0f, 0.0f, 0.0f)); } /// <summary> /// Override and supplement response to colliding GameObjects /// </summary> /// <param name="collidedObject">Object that hit the Portal.</param> /// <param name="resultantForce">Force that Portal was hit with.</param> /// <param name="objectLibrary">ObjectLibrary that portal belongs to.</param> /// <returns>True if collidedObject needs to be recycled</returns> public override bool ObjectCollisionResponse(GameObject collidedObject, Vector3 resultantForce, ObjectLibrary objectLibrary) { if (collidedObject.mass.objectType != Enums_Engine.ObjectType.PLAYER) { // Non-playerObject - Non-playerObject collision response if (health == 0) { mass.AddForce(new Vector3(0.0f, -1000.0f, 0.0f)); } else { health--; } } if (collidedObject.mass.objectType == Enums_Engine.ObjectType.PLAYER) { // if human, load next room // if islocked = true, rotate door model open // else, remain shut // HACK: BreakPoint for dev... health--; health++; } switch (portalID) { case 1: // Call the method for the door //if (collidedObject.mass.objectType == Mass.ElementType.EARTH) //Door can take damage //portalHealth = portalHealth - totalDamage(); //} if (health <= 0) { // Call the doop open method //Drop the collision detection mass.boundingVolume.UpdateBox(mass.currentPosition, mass.currentRotation, Vector3.Zero); } break; case 2: // Call the method for the door break; } if (isLocked == false) { //Rotate door model open } return false; } /// <summary> /// Overrides and supplements response to this object hitting the ground. /// </summary> /// <param name="terrain">The terrain object which this Portal hit.</param> public override void TerrainCollisionResponse(Terrain terrain) { base.GetObjectHeight(terrain); // Add Gravity if terrain and player are touching if (heightDifference < 0.0f) { mass.AddForce(mass.mass * Statics_Engine.GameSettings.accelDueToGravity); } else if (heightDifference > 0.0f) { base.TerrainCollisionResponse(terrain); if (mass.totalForce.Y > 0.0f) { mass.totalForce.Y = 0.0f; } if (mass.velocity.Y > 0.0f) { mass.velocity.Y = 0.0f; } if (heightDifference < 0.0f) { mass.AddForce(mass.mass * Statics_Engine.GameSettings.accelDueToGravity); } else if (heightDifference > 0.0f) { if (mass.totalForce.Y > 0.0f) { mass.totalForce.Y = 0.0f; } if (mass.velocity.Y > 0.0f) { mass.velocity.Y = 0.0f; } // Ground pushing up to negate gravity mass.AddForce(new Vector3(0.0f, heightDifference * terrain.propSurfaceTension, 0.0f) - (new Vector3(0.0f, mass.totalForce.Y, 0.0f) + new Vector3(0.0f, mass.velocity.Y * mass.mass / Statics_Engine.SystemSettings.dt, 0.0f))); } } } /// <summary> /// Override draw for portal /// </summary> public override Draw Draw() { // Calculate ObjectSpace(Rotation) and WorldSpace(Translation) Transformation Matrix draw.matrix = draw.initialTransform * Matrix.CreateScale(mass.scale) * Matrix.CreateFromQuaternion(mass.currentRotation) * Matrix.CreateTranslation(mass.currentPosition); return draw; } /// <summary> /// Override and supplement base Billboard drawing specific to this Portal. /// </summary> /// <param name="objectLibrary">ObjectLibrary that portal belongs to.</param> /// <param name="gameObjectBillboards">Dynamic list of billboards to be drawn this frame.</param> public override void Draw_Billboards(ObjectLibrary objectLibrary, BillboardList gameObjectBillboards) { fireIterator++; if (fireIterator > 2) fireIterator = 0; Random random = new Random(); // Shift Random number between -0.5 and 0.5 to modulate height float randOffsetY = (float)random.NextDouble(); randOffsetY -= 0.5f; Vector3 offset = new Vector3(80.0f, 10.0f * randOffsetY + 150.0f, 250.0f * randOffsetY); // Random number between 0-3, excluding 4.. int randTexture = (int)(random.NextDouble() * draw.textureList.Count - .01); Billboard billboard = new Billboard(null); billboard.Load(mass.currentPosition, offset, 600.0f, 800.0f, draw.textureList[randTexture]); gameObjectBillboards.Add(billboard); } } }