//--------------------------------------------------------------------------------------------------------------------------------------------------- // // Copyright (C)2007 DarkWynter Studios. All rights reserved. // //--------------------------------------------------------------------------------------------------------------------------------------------------- // {License Information: Creative Commons} //--------------------------------------------------------------------------------------------------------------------------------------------------- namespace ElementalGame { #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 Xclna.Xna.Animation; #endregion public struct Hit { //Point of impact storage public Vector3 POI; //Type of hit public int type; //Pitch and Yaw public Quaternion pitchyaw; //Steps in the animation public float step; } public class Player : GameObject { //=============================================================================================================== // Sensor for detecting upcoming collisions public Sensor collisionSensor; protected Stopwatch mannaIncrement = new Stopwatch(); protected bool fireElementSelected; // Player is using fire protected bool waterElementSelected; // Player is using water protected bool earthElementSelected; // Player is using earth protected bool airElementSelected; // Player is using wind public bool terrainModEnabled; public Hit[] myHits; protected Stopwatch RateOfFire; // Timer to control AOE rate of fire protected Stopwatch energyStabalizeTimer; protected Model eyesModel; // Extra model for the eyes of the septasoul protected Model shieldModel; public enum PlayerState { ATTACK, SHIELD, NORMAL }; public PlayerState currentState = PlayerState.NORMAL; // Look-At algorithm (terrainMod, particle energy) Mass.ObjectType targetObject; //private Human metaHuman; public enum HitWhere { LEFT, RIGHT, UP, DOWN }; public List hitWhere = new List(); GameObject gameObject; public PlayerSounds pSounds = new PlayerSounds(); public Vector3 lookAtPoint = new Vector3(); //public bool terrainModEnabled = false; public ModelAnimator septaSoulAnimator; private AnimationController idle; private AnimationController walk; private AnimationController die; private AnimationController currentAnimation; // For defenses public enum ShieldType { EARTH_SHIELD, FIRE_SHIELD, WATER_SHIELD, WIND_SHIELD, NO_SHIELD }; public ShieldType activeShield; //*add the mod terrain here remove none? // Chooses Weapon and Defense public enum ElementalMode { FIRE_MODE, WATER_MODE, EARTH_MODE, WIND_MODE, TERRAIN_MODE, NONE }; public ElementalMode lastModeSelected = ElementalMode.NONE; // Character Model Type public enum CharacterType { SEPTASOUL, EVIL_BUNNY_DUDE, FISH, HUMAN }; public CharacterType characterType; // This struct holds the controller updates for the player. It can be accessed from main and overriden and used as a controller harness for // testing public struct ControllerInput { public Vector2 playerRotation; public Vector2 playerMotion; public float elementUse; public float attackAmount; public float defendAmount; public bool terrainModToggle; public bool movementTypeToggle; public bool jump; public GameController.ElementalMode modeSwitch; public GameController.AttackMode attackMode; public bool manualOverride; public int massChangeDelta; public int thermalChangeDelta; public void init() { playerRotation = Vector2.Zero; playerMotion = Vector2.Zero; elementUse = 0; attackAmount = 0; defendAmount = 0; terrainModToggle = false; movementTypeToggle = false; jump = false; modeSwitch = GameController.ElementalMode.NONE; manualOverride = false; massChangeDelta = 0; thermalChangeDelta = 0; } } public ControllerInput controllerInput = new ControllerInput(); public bool controlsInverted = false; // Invert controller public int playerIndex; // Player ID number public float health; // Player health public float manna; // Player manna public int killedBy = -1; public int kills; //Used to respawn the player public Stopwatch respawnTimer = new Stopwatch(); //Used to make player invunerable for a few seconds after spawning public Stopwatch spawnDoneTimer = new Stopwatch(); public int particleMassValue = 30; public int particleThermalValue = 30; public int numberOfKeysFound = 0; public Vector3 spawnPosition = new Vector3(); public float spawnHeight = 0; public Vector3 terrainModTarget = Vector3.Zero; public bool firingEnergyBeam = false; new public float[] materialDiffuse = { 1.0f, 1.0f, 1.0f, 1.0f }; protected Matrix initialTransform = new Matrix(); public Player() { } public Player(int playerNumber, Mass darkMass) { mass = darkMass; playerIndex = playerNumber; this.myHits = new Hit[4]; mass.velocity = new Vector3(0, 0, 0); mass.mass = 10.0f; mass.scale = 1.0f; mass.energy = 0.0f; mass.staticFrictionCoefficient = 0.25f; mass.dynamicFrictionCoefficient = 0.35f; mass.COR = 0.6f; mass.objectHeight = XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT; mass.lastMaxHeight = 0; _boundingSphere.Center = new Vector3(10, 20, 10); _boundingSphere.Radius = 10.0f; activeShield = ShieldType.NO_SHIELD; characterType = CharacterType.SEPTASOUL; // Don't override the controller by default controllerInput.manualOverride = false; RateOfFire = new Stopwatch(); energyStabalizeTimer = new Stopwatch(); //All player variables need to be reset health = 0; manna = 0; terrainModEnabled = false; collisionSensor = new Sensor(ObjectLibrary.darkMatter[ObjectLibrary.darkMatterIterator++]); collisionSensor.ownerPointer = this; } //public void LoadXML(ModelManager modelManager, XmlNode node) //{ // XML.LoadPlayer(); // metaHuman.effect = ElementalGame.content.Load("Shaders/ElementalGPU"); // modelManager.AddNewModel("Player", // ElementalGame.content.Load("_models/adams"), // ElementalGame.content.Load("_textures/adams"), // ElementalGame.content.Load("_textures/adams"), // metaHuman.effect, // materialDiffuse, // materialSpecular); //} public override void Load(XmlNode node) { base.Load( node); //Load Effect effect = ElementalGame.content.Load("Shaders/ElementalGPU"); XML.PlayerInfo playerInfo; playerInfo.name = "septasoul"; playerInfo.modelPath = "_models/ss3"; playerInfo.texPath = "_textures/septasoulTexture"; playerInfo.bumpPath = "_textures/septasoulTexture"; playerInfo.scale = 1.0f; // Load Model textureList.Clear(); textureList.Add(ElementalGame.content.Load("_textures/septasoulTexture")); textureList.Add(ElementalGame.content.Load("_textures/septasoulTexture")); LoadPlayer(playerInfo); //model = ElementalGame.content.Load("_models/dwarfmodel"); // Apply our own advanced Effect to the Model foreach (ModelMesh mesh in model.Meshes) { for (int i = 0; i < mesh.MeshParts.Count; i++) { ModelMeshPart part = mesh.MeshParts[i]; part.Effect = effect.Clone(ElementalGame.graphics.GraphicsDevice); } } septaSoulAnimator = new ModelAnimator(model); //idle = new AnimationController(septaSoulAnimator.Animations["AnimationSet0"]); idle = new AnimationController(septaSoulAnimator.Animations["idle"]); walk = new AnimationController(septaSoulAnimator.Animations["walk"]); die = new AnimationController(septaSoulAnimator.Animations["die"]); RunController(septaSoulAnimator, idle); shieldModel = ElementalGame.content.Load("_models/Shield"); textureList.Add(ElementalGame.content.Load("_textures/RockQuartz")); textureList.Add(ElementalGame.content.Load("_textures/EarthParticleLava")); textureList.Add(ElementalGame.content.Load("_textures/Water")); textureList.Add(ElementalGame.content.Load("_textures/AirParticleCold")); // Apply our own advanced Effect to the Model foreach (ModelMesh mesh in shieldModel.Meshes) { for (int i = 0; i < mesh.MeshParts.Count; i++) { // Add effect to mesh mesh.MeshParts[i].Effect = effect; } } // Reset the Rate of Fire limiter RateOfFire.Reset(); RateOfFire.Start(); energyStabalizeTimer.Reset(); energyStabalizeTimer.Start(); mannaIncrement = new Stopwatch(); mannaIncrement.Start(); kills = 0; killedBy = -1; if (health > 0.0f) { // Add Object to the lookup map ObjectLibrary.lookupMap.SetPosition(this.mass); } terrainModEnabled = false; earthElementSelected = true; fireElementSelected = false; waterElementSelected = false; airElementSelected = false; lastModeSelected = ElementalMode.EARTH_MODE; } public void LoadPlayer(XML.PlayerInfo playerInfo) { model = ElementalGame.content.Load(playerInfo.modelPath); mass.scale = playerInfo.scale; LoadPlayer(playerInfo.texPath, playerInfo.bumpPath); foreach (ModelMesh mesh in model.Meshes) { for (int i = 0; i < mesh.MeshParts.Count; i++) { ModelMeshPart part = mesh.MeshParts[i]; part.Effect = effect.Clone(ElementalGame.graphics.GraphicsDevice); } } septaSoulAnimator = new ModelAnimator(model); idle = new AnimationController(septaSoulAnimator.Animations["idle"]); walk = new AnimationController(septaSoulAnimator.Animations["walk"]); die = new AnimationController(septaSoulAnimator.Animations["die"]); RunController(septaSoulAnimator, idle); if (playerInfo.name == "dojoboy" || playerInfo.name == "dojogirl") { initialTransform = Matrix.CreateRotationY((float)(-Math.PI / 2.0f)) * Matrix.CreateTranslation(new Vector3(0, -XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT / 2.0f, 0)); } else if (playerInfo.name == "bunny" || playerInfo.name == "septasoul") { initialTransform = Matrix.CreateTranslation(new Vector3(0, -XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT / 4.0f, 0)); } else if (playerInfo.name == "fish") { initialTransform = Matrix.CreateRotationY((float)(-Math.PI)) * Matrix.CreateTranslation(new Vector3(0, -XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT / 2.0f + 5, 0)); } else { initialTransform = Matrix.Identity; } } public void LoadPlayer(string texFile, string bumpFile) { textureList[0] = ElementalGame.content.Load(texFile); textureList[1] = ElementalGame.content.Load(bumpFile); } // Add this as a new method private void RunController(ModelAnimator animator, AnimationController controller) { foreach (BonePose p in animator.BonePoses) { p.CurrentController = (IAnimationController)controller; p.CurrentBlendController = null; } currentAnimation = controller; } protected bool CheckPlayerOnTerrain(ObjectLibrary objectLibrary) { // Get X and Z positions int posX = (int)mass.currentPosition.X; int posZ = (int)mass.currentPosition.Z; // Make sure we don't go out of bounds if (posX <= 0) { posX = 1; } if (posZ <= 0) { posZ = 1; } if (posX >= Terrain.collisionMapSize) { posX = Terrain.collisionMapSize - 1; } if (posZ >= Terrain.collisionMapSize) { posZ = Terrain.collisionMapSize - 1; } // Add up all neighboring terrain points float totalHeight = objectLibrary.terrain.GetTerrainHeight(posX / Terrain.terrainScaleFactor, posZ / Terrain.terrainScaleFactor); // Average all the neighboring terrain points float newHeight = totalHeight + (XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT / 2); // Get difference between average and player if (newHeight - mass.currentPosition.Y < 0.0f) { // In the Air return false; } else { // On the Ground return true; } } public void UpdateController(ObjectLibrary objectLibrary) { lookAtPoint = new Vector3(); //currentAnimation.Update(ElementalGame.elementalGameTime); if (currentAnimation != idle) { RunController(septaSoulAnimator, idle); } // Rotation Controls if (controllerInput.playerRotation != Vector2.Zero) { if (controlsInverted) { mass.Rotate(-controllerInput.playerRotation.Y, controllerInput.playerRotation.X); } else { mass.Rotate(controllerInput.playerRotation.Y, controllerInput.playerRotation.X); } if (terrainModEnabled) { terrainModTarget = Vector3.Zero; } } // Translation Controls if (controllerInput.playerMotion != Vector2.Zero) { if (CheckPlayerOnTerrain(objectLibrary)) { mass.MovePlayer(controllerInput.playerMotion.Y * XML.PlayerSettings.PLAYER_SPEED_ON_THE_GROUND, controllerInput.playerMotion.X * XML.PlayerSettings.PLAYER_SPEED_ON_THE_GROUND); } else { mass.MovePlayer(controllerInput.playerMotion.Y * XML.PlayerSettings.PLAYER_SPEED_IN_THE_AIR, controllerInput.playerMotion.X * XML.PlayerSettings.PLAYER_SPEED_IN_THE_AIR); } if (terrainModEnabled) { terrainModTarget = Vector3.Zero; } RunController(septaSoulAnimator, walk); } /////////////////////////////////////////////////////////////////////////// // this is the cutoff point for what the player can do while dead....... /////////////////////////////////////////////////////////////////////////// if (IsAlive() == false) { RunController(septaSoulAnimator, die); return; } //Now we can assume he is alive! // Increment players manna over time if (mannaIncrement.ElapsedMilliseconds >= XML.PlayerSettings.MANNA_INCREMENT_RATE) { mannaIncrement.Reset(); mannaIncrement.Start(); ChangeManna(+2); } if (mass.fallingDamageMultiplier != 0.0f) { ChangeHealth(-mass.fallingDamageMultiplier * XML.PlayerSettings.FALLING_HEALTH_LOSS, objectLibrary); SetHitShader(Vector3.Zero, 3); mass.fallingDamageMultiplier = 0.0f; if (IsAlive() == false) { Kill(playerIndex, objectLibrary); // Killed himself if (playerIndex < 4) { ((Human)this).SetKilledByInfo("SPLAT!!!"); } } } //toggle the movement type if (controllerInput.movementTypeToggle) { if (mass.movementType == Mass.MovementType.WALK) { mass.movementType = Mass.MovementType.HOVER; } else { mass.movementType = Mass.MovementType.WALK; mass.totalForce = Vector3.Zero; mass.velocity = Vector3.Zero; } } particleMassValue += controllerInput.massChangeDelta; particleThermalValue += controllerInput.thermalChangeDelta; if (particleMassValue < 1) { particleMassValue = 1; } else if (particleMassValue > 100) { particleMassValue = 100; } if (particleThermalValue < 0) { particleThermalValue = 0; } else if (particleThermalValue > 100) { particleThermalValue = 100; } if (controllerInput.terrainModToggle) { terrainModEnabled = !terrainModEnabled; } if (terrainModEnabled && controllerInput.elementUse != 0) { controllerInput.attackMode = GameController.AttackMode.TERRAIN_MOD; } else if (controllerInput.attackAmount > 0) { controllerInput.attackMode = GameController.AttackMode.ATTACK; } else { controllerInput.attackMode = GameController.AttackMode.NONE; } if (terrainModEnabled) { //terrainModEnabled = true; lookAtPoint = LookAtTerrainPoint(objectLibrary); if (lookAtPoint.X < 0.0f) { lookAtPoint = new Vector3(0.0f, 500.0f, 0.0f); } } // Player uses an element if (controllerInput.elementUse != 0) { if (manna > XML.PlayerSettings.ATTACK_MANNA_COST) { // If terrain mod switch is on if (controllerInput.attackMode == GameController.AttackMode.TERRAIN_MOD) { if (ChangeManna(-Math.Abs(controllerInput.elementUse) * 0.1f)) { if (targetObject == Mass.ObjectType.TERRAIN) { TerrainMod(controllerInput.elementUse, objectLibrary); } } } // must be an attack or defend else { // Check if fire button was used if (controllerInput.elementUse != 0.0f && manna > controllerInput.elementUse / 2.0f) { if (fireElementSelected) { if (ChangeManna(-XML.PlayerSettings.ENERGY_BEAM_MANNA_COST)) { // Play audio for each human foreach (Human human in objectLibrary.humans) { if (human.IsAlive()) { Audio.FireAttack(pSounds, mass.currentPosition, human.mass.currentPosition); } } // Fire Attack UseEnergyBeam(objectLibrary, controllerInput.elementUse); firingEnergyBeam = true; } } } else { firingEnergyBeam = false; } // Check if particle Attack was initiated if (controllerInput.attackAmount > 0.0f && manna > XML.PlayerSettings.ATTACK_MANNA_COST) { // AND make sure they are not shielding at the same time if (controllerInput.defendAmount == 0.0f) { // Attack if (earthElementSelected) { Attack(Particle.ParticleType.Earth, objectLibrary); } else if (waterElementSelected) { Attack(Particle.ParticleType.Water, objectLibrary); } else if (airElementSelected) { Attack(Particle.ParticleType.Air, objectLibrary); } } } // Player uses shield if (controllerInput.defendAmount > 0.0f && manna > XML.PlayerSettings.SHIELD_MANNA_COST) { if (lastModeSelected != ElementalMode.NONE || lastModeSelected != ElementalMode.FIRE_MODE) { // Charge manna for shielding if (ChangeManna(-XML.PlayerSettings.SHIELD_MANNA_COST)) { currentState = PlayerState.SHIELD; } } //Set player's shield to last element selected switch (lastModeSelected) { case ElementalMode.WIND_MODE: activeShield = ShieldType.WIND_SHIELD; break; case ElementalMode.EARTH_MODE: activeShield = ShieldType.EARTH_SHIELD; break; case ElementalMode.WATER_MODE: activeShield = ShieldType.WATER_SHIELD; break; case ElementalMode.FIRE_MODE: case ElementalMode.NONE: activeShield = ShieldType.NO_SHIELD; break; } } else { activeShield = ShieldType.NO_SHIELD; } } } } // If triggers not pressed at all else { activeShield = ShieldType.NO_SHIELD; currentState = PlayerState.NORMAL; } // See if player is jumping if (controllerInput.jump) { if (CheckPlayerOnTerrain(objectLibrary) == false) { if (ChangeManna(-XML.PlayerSettings.JUMP_MANNA_COST)) { mass.AddForce(new Vector3(0, -XML.PlayerSettings.IN_AIR_JUMP_CONSTANT * 200.0f, 0)); } } else { mass.AddForce(new Vector3(0, -XML.PlayerSettings.JUMP_CONSTANT * 200.0f, 0)); } if (terrainModEnabled) { terrainModTarget = Vector3.Zero; } RunController(septaSoulAnimator, die); } // See if player changed the Element mode if (controllerInput.modeSwitch != GameController.ElementalMode.NONE) { switch (controllerInput.modeSwitch) { case GameController.ElementalMode.WIND_MODE: { airElementSelected = true;// !airElementSelected; if (airElementSelected) { // Disable earth and water earthElementSelected = false; waterElementSelected = false; fireElementSelected = false; lastModeSelected = ElementalMode.WIND_MODE; } else { lastModeSelected = ElementalMode.NONE; } } break; case GameController.ElementalMode.EARTH_MODE: { earthElementSelected = true;// !earthElementSelected; if (earthElementSelected) { // Disable air and water airElementSelected = false; waterElementSelected = false; fireElementSelected = false; lastModeSelected = ElementalMode.EARTH_MODE; } else { lastModeSelected = ElementalMode.NONE; } } break; case GameController.ElementalMode.FIRE_MODE: { fireElementSelected = true;// !fireElementSelected; airElementSelected = false; waterElementSelected = false; earthElementSelected = false; if (fireElementSelected) { lastModeSelected = ElementalMode.FIRE_MODE; } else { lastModeSelected = ElementalMode.NONE; } } break; case GameController.ElementalMode.WATER_MODE: { waterElementSelected = true;// !waterElementSelected; if (waterElementSelected) { // Disable earth and air earthElementSelected = false; airElementSelected = false; fireElementSelected = false; lastModeSelected = ElementalMode.WATER_MODE; } else { lastModeSelected = ElementalMode.NONE; } } break; case GameController.ElementalMode.TERRAIN_MODE: { lastModeSelected = ElementalMode.TERRAIN_MODE; } break; } } // Check the player's overall velocity if (mass.velocity.Length() > XML.PlayerSettings.MAX_VELOCITY) { // If NOT falling if (Math.Abs(mass.velocity.Y) < Math.Abs(mass.velocity.X) || Math.Abs(mass.velocity.Y) < Math.Abs(mass.velocity.Z)) { mass.velocity.Normalize(); mass.velocity *= XML.PlayerSettings.MAX_VELOCITY; } } } public override void Update(ObjectLibrary objectLibrary) { // BLATENT HACK // RESET MANNA EACH TIME SO WE CAN JUMP INFINITLY manna = 100; if (energyStabalizeTimer.ElapsedMilliseconds > 3000) { //update player's energy value if (mass.energy < 0.0f) { mass.ChangeEnergy(0.01f); } else if (mass.energy > 0.0f) { mass.ChangeEnergy(-0.01f); } energyStabalizeTimer.Reset(); energyStabalizeTimer.Start(); } if (currentAnimation != null) { currentAnimation.Update(ElementalGame.elementalGameTime); } septaSoulAnimator.Update(); UpdateController(objectLibrary); mass.UpdatePosition(); mass.isMoving = true; //if (mass.isMoving && !ObjectLibrary.dynamicList.Contains(mass)) //{ // ObjectLibrary.dynamicList.Add(mass); //} _boundingSphere.Center = mass.currentPosition; Vector3 sensorDistance; if (mass.movementType == Mass.MovementType.WALK) { sensorDistance = mass.sensorDirection + Vector3.Zero; } else { sensorDistance = mass.velocity + Vector3.Zero; } if (sensorDistance.Length() > XML.PlayerSettings.MAX_SENSOR_DISTANCE) { sensorDistance.Normalize(); sensorDistance = sensorDistance * XML.PlayerSettings.MAX_SENSOR_DISTANCE; } collisionSensor.mass.SetPosition(mass.currentPosition + sensorDistance, mass.currentPosition + sensorDistance * 1.5f); if (health <= 0) { health = 0; } if (spawnDoneTimer.IsRunning) { if (spawnDoneTimer.ElapsedMilliseconds >= XML.PlayerSettings.SPAWN_DONE_DELAY) { spawnDoneTimer.Stop(); spawnDoneTimer.Reset(); } } // Play audio for each human foreach (Human human in objectLibrary.humans) { if (human.IsAlive()) { if (controllerInput.playerMotion.Length() > 0) { Audio.Walking(pSounds, mass.currentPosition, human.mass.currentPosition); } if (controllerInput.jump) { Audio.Jump(pSounds, mass.currentPosition, human.mass.currentPosition); } } } } public override void DrawShadow(ModelManager modelManager) { /* // Did we die?? if (IsAlive() == false) { return; } // Calculate ObjectSpace(Rotation) and WorldSpace(Translation) Transformation Matrix matrix = Matrix.CreateScale(mass.scale) * Matrix.CreateFromQuaternion(mass.currentRotation) * Matrix.CreateTranslation(mass.currentPosition); // Matricies ShaderParameters.World.SetValue(matrix); // Draw the model //foreach (ModelMesh mesh in model.Meshes) //{ // foreach (Effect currentEffect in mesh.Effects) // { // currentEffect.CurrentTechnique = effect.Techniques["ShadowMap"]; // } // mesh.Draw(); //} effect.CurrentTechnique = effect.Techniques["ShadowMap"]; septaSoulAnimator.Draw(ElementalGame.elementalGameTime, effect); */ } public void DrawPlayerDemo(Matrix matrixModelView, Matrix matrixProjection) { //ShaderParameters.modelTexture1.SetValue(textureList[0]); //ShaderParameters.bumpTexture1.SetValue(textureList[1]); //ShaderParameters.World.SetValue(Matrix.Identity); matrix = Matrix.Identity * Matrix.CreateScale(0.5f); // Lighting //ShaderParameters.coreShininess.SetValue(7000.0f); //ShaderParameters.coreMaterialDiffuse.SetValue(materialDiffuse); //ShaderParameters.coreMaterialSpecular.SetValue(materialSpecular); DrawAnimation(); } public override void Draw(ModelManager modelManager) { // Did we die?? if (IsAlive() == false) { return; } //check spawn done delay if (spawnDoneTimer.IsRunning) { float ratio = (float)spawnDoneTimer.ElapsedMilliseconds / (float)XML.PlayerSettings.SPAWN_DONE_DELAY; SetDiffuseAlpha((int)(200 * ratio)); } else { SetDiffuseAlpha(255); } // Calculate ObjectSpace(Rotation) and WorldSpace(Translation) Transformation Matrix matrix = initialTransform * Matrix.CreateScale(mass.scale) * Matrix.CreateFromQuaternion(mass.currentRotation) * Matrix.CreateTranslation(mass.currentPosition); // Textures //ShaderParameters.modelTexture1.SetValue(textureList[0]); //ShaderParameters.bumpTexture1.SetValue(textureList[1]); //// Matricies //ShaderParameters.World.SetValue(matrix); //// Lighting //ShaderParameters.coreShininess.SetValue(7000.0f); //ShaderParameters.coreMaterialDiffuse.SetValue(materialDiffuse); //ShaderParameters.coreMaterialSpecular.SetValue(materialSpecular); DrawAnimation(); if (IsHuman()) { ((Human)this).HUD.Draw(); } } public void DrawEnergyBeam(ObjectLibrary objectLibrary) { if (fireElementSelected == true && controllerInput.elementUse != 0.0f && manna > -controllerInput.elementUse / 2.0f) { Vector3 startPosition = mass.currentPosition + mass.perpVector + mass.normalVector - mass.upVector * 3; Vector3 targetPosition; float[] diffuse = { 1, 1, 1, 1 }; // Get the particles information from LookAtPoint and store it in the local vector3 lookAtPoint Vector3 lookPoint = LookAtObject(objectLibrary); // Check if the target object was Earth if (targetObject == Mass.ObjectType.PARTICLE) { targetPosition = mass.currentPosition + mass.normalVector * lookPoint.Length(); } else { targetPosition = mass.currentPosition + mass.normalVector * XML.PlayerSettings.TERRAIN_MOD_RANGE; } matrix = Matrix.Identity; ShaderParameters.World.SetValue(matrix); ShaderParameters.coreMaterialDiffuse.SetValue(diffuse); //fire texture ShaderParameters.modelTexture1.SetValue(textureList[4]); //water texture ShaderParameters.modelTexture2.SetValue(textureList[3]); //should interpolate ShaderParameters.particleEnergyValue.SetValue((controllerInput.elementUse / 2.0f) + 0.5f); VertexPositionTexture[] list = new VertexPositionTexture[6]; float size = 1.0f; list[0].Position = startPosition - mass.perpVector * size;// new Vector3(-size, 0, 0); //list[0].Color = new Color(0, 0, 0); list[0].TextureCoordinate = new Vector2(0, 1); list[1].Position = targetPosition - mass.perpVector * size + mass.normalVector * size;// new Vector3(-size, 0, size); //list[1].Color = new Color(0, 255, 0); list[1].TextureCoordinate = new Vector2(0, 0); list[2].Position = targetPosition + mass.perpVector * size + mass.normalVector * size;//new Vector3(size, 0, size); //list[2].Color = new Color(0, 0, 255); list[2].TextureCoordinate = new Vector2(1, 0); list[3].Position = list[0].Position;//new Vector3(-size, 0, 0); //list[3].Color = new Color(255, 255, 255); list[3].TextureCoordinate = list[0].TextureCoordinate; list[4].Position = list[2].Position;//new Vector3(size, 0, size); //list[4].Color = new Color(0, 0, 0); list[4].TextureCoordinate = list[2].TextureCoordinate; list[5].Position = startPosition + mass.normalVector * size;//new Vector3(0, 0, size); //list[5].Color = new Color(0, 100, 0); list[5].TextureCoordinate = new Vector2(1, 1); // Technique effect.CurrentTechnique = effect.Techniques["EnergyBeamShaderMain"]; effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); ElementalGame.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, list, 0, 2); pass.End(); } effect.End(); } } public void DrawShield() { if (activeShield != ShieldType.NO_SHIELD) { matrix = Matrix.CreateScale(boundingSphere.Radius * 2) * Matrix.CreateFromQuaternion(mass.currentRotation) * Matrix.CreateTranslation(mass.currentPosition); float[] color = { 1, 1, 1, 1 }; ShaderParameters.World.SetValue(matrix); ShaderParameters.coreMaterialDiffuse.SetValue(color); switch (activeShield) { case ShieldType.EARTH_SHIELD: { ShaderParameters.modelTexture1.SetValue(textureList[2]); break; } case ShieldType.FIRE_SHIELD: { ShaderParameters.modelTexture1.SetValue(textureList[3]); break; } case ShieldType.WATER_SHIELD: { ShaderParameters.modelTexture1.SetValue(textureList[4]); break; } case ShieldType.WIND_SHIELD: { ShaderParameters.modelTexture1.SetValue(textureList[5]); break; } } // Draw the shield model foreach (ModelMesh mesh in shieldModel.Meshes) { foreach (Effect currentEffect in mesh.Effects) { currentEffect.CurrentTechnique = effect.Techniques["ShieldShaderMain"]; } mesh.Draw(); } } } public void DrawAnimation() { try { septaSoulAnimator.world = matrix; septaSoulAnimator.Update(); currentAnimation.Update(ElementalGame.elementalGameTime); int index = 0; // Update all the effects with the palette and world and draw the meshes for (int i = 0; i < septaSoulAnimator.numMeshes; i++) { ModelMesh mesh = model.Meshes[i]; // The starting index for the modelEffects array int effectStartIndex = index; if (septaSoulAnimator.palette[i] != null && septaSoulAnimator.matrixPaletteParams[index] != null) { foreach (Effect effect in mesh.Effects) { septaSoulAnimator.worldParams[index].SetValue(matrix); septaSoulAnimator.matrixPaletteParams[index].SetValue(septaSoulAnimator.palette[i]); index++; } } else { foreach (Effect effect in mesh.Effects) { septaSoulAnimator.worldParams[index].SetValue(septaSoulAnimator.pose[mesh.ParentBone.Index] * matrix); index++; } } int numParts = mesh.MeshParts.Count; GraphicsDevice device = mesh.VertexBuffer.GraphicsDevice; device.Indices = mesh.IndexBuffer; for (int j = 0; j < numParts; j++) { ModelMeshPart currentPart = mesh.MeshParts[j]; if (currentPart.NumVertices == 0 || currentPart.PrimitiveCount == 0) continue; Effect currentEffect = septaSoulAnimator.modelEffects[effectStartIndex + j]; if (septaSoulAnimator.palette[i] != null && septaSoulAnimator.matrixPaletteParams[i] != null) { currentEffect.CurrentTechnique = currentEffect.Techniques["SkinnedPlayerShaderMain"]; } else { currentEffect.CurrentTechnique = currentEffect.Techniques["PlayerShaderMain"]; } // Hit Shader stuff Matrix mat = new Matrix(); mat.M11 = myHits[0].POI.X + this.mass.currentPosition.X; mat.M12 = myHits[0].POI.Y + this.mass.currentPosition.Y; mat.M13 = myHits[0].POI.Z + this.mass.currentPosition.Z; mat.M14 = myHits[0].type; if (this.myHits[0].step < 1 && this.myHits[0].step >= 0.0f) { this.myHits[0].step += .01f; } Vector4 vHit = new Vector4(this.myHits[0].step); currentEffect.Parameters["hits"].SetValue(mat); currentEffect.Parameters["hitTime"].SetValue(vHit); currentEffect.Parameters["ViewProj"].SetValue(Renderer.matrixModelView * Renderer.matrixProjection); currentEffect.Parameters["EyePostion"].SetValue(Matrix.Invert(Renderer.matrixModelView)); currentEffect.Parameters["modelTexture1"].SetValue(textureList[0]); currentEffect.Parameters["bumpTexture1"].SetValue(textureList[1]); // Lighting currentEffect.Parameters["coreShininess"].SetValue(7000.0f); currentEffect.Parameters["coreMaterialDiffuse"].SetValue(materialDiffuse); currentEffect.Parameters["coreMaterialSpecular"].SetValue(materialSpecular); currentEffect.Parameters["particleEnergyValue"].SetValue((mass.energy / 2.0f) + 0.5f); currentEffect.Parameters["fogColor"].SetValue(XML.LevelSettings.fogColor); currentEffect.Parameters["fogDensity"].SetValue(XML.LevelSettings.fogDensity); currentEffect.Parameters["light0"].SetValue(XML.LevelSettings.lightInfo1); if (XML.SystemSettings.singleLightSource) { currentEffect.Parameters["light1"].SetValue(XML.LevelSettings.lightInfo1); } else { currentEffect.Parameters["light1"].SetValue(XML.LevelSettings.lightInfo2); } currentEffect.Parameters["zMaxDepth"].SetValue(XML.LevelSettings.zMaxDepth); currentEffect.Parameters["LightViewProj1"].SetValue(Renderer.lightView1 * Renderer.lightProj); currentEffect.Parameters["LightViewProj2"].SetValue(Renderer.lightView2 * Renderer.lightProj); currentEffect.Parameters["playerIsDead"].SetValue(Renderer.currentPlayerDead); device.VertexDeclaration = currentPart.VertexDeclaration; device.Vertices[0].SetSource(mesh.VertexBuffer, currentPart.StreamOffset, currentPart.VertexStride); currentEffect.Begin(); EffectPassCollection passes = currentEffect.CurrentTechnique.Passes; int numPasses = passes.Count; for (int k = 0; k < numPasses; k++) { EffectPass pass = passes[k]; pass.Begin(); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, currentPart.BaseVertex, 0, currentPart.NumVertices, currentPart.StartIndex, currentPart.PrimitiveCount); pass.End(); } currentEffect.End(); } } } catch (NullReferenceException) { throw new InvalidOperationException("The effects on the model for a " + "ModelAnimator were changed without calling ModelAnimator.InitializeEffectParams()."); } catch (InvalidCastException) { throw new InvalidCastException("ModelAnimator has thrown an InvalidCastException. This is " + "likely because the model uses too many bones for the matrix palette. The default palette size " + "is 56 for windows and 40 for Xbox."); } } /* Player Specific Methods * */ public void SetSpawnPoint(Vector3 spawn) { spawnPosition = Vector3.Zero + spawn; mass.SetPosition(spawnPosition, new Vector3(Terrain.collisionMapSize / 2, 0, Terrain.collisionMapSize / 2));//spawnPosition + (new Vector3(0, 0, 1))); } public void SpawnPlayer() { // Remove from map ObjectLibrary.lookupMap.RemoveLast(this.mass); ObjectLibrary.lookupMap.RemoveCurrent(this.mass); mass.velocity = Vector3.Zero; mass.totalForce = Vector3.Zero; spawnPosition.Y = spawnHeight + XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT + 10; mass.SetPosition(spawnPosition, new Vector3(Terrain.collisionMapSize / 2, 0, Terrain.collisionMapSize / 2));//spawnPosition + (new Vector3(0, 0, 1))); _boundingSphere.Center = new Vector3(spawnPosition.X, XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT / 2.0f, spawnPosition.Z); _boundingSphere.Radius = 10.0f; health = 100; manna = 100; killedBy = -1; activeShield = ShieldType.NO_SHIELD; // Reset the Rate of Fire limiter RateOfFire.Reset(); RateOfFire.Start(); energyStabalizeTimer.Reset(); energyStabalizeTimer.Start(); mannaIncrement = new Stopwatch(); mannaIncrement.Start(); //stop the respawn timer respawnTimer.Stop(); respawnTimer.Reset(); //start the invincibility timer spawnDoneTimer.Reset(); spawnDoneTimer.Start(); ObjectLibrary.lookupMap.SetPosition(this.mass); } /// /// Set the Player's color. If you don't want to set a color component, set the value to negative /// /// public void SetPlayerColor(Vector4 color) { if (color.X >= 0.0f) { } } public void SetDiffuseRed(int red) { materialDiffuse[0] = (1.0f * red) / 255.0f; } public void SetDiffuseGreen(int green) { materialDiffuse[1] = (1.0f * green) / 255.0f; } public void SetDiffuseBlue(int blue) { materialDiffuse[2] = (1.0f * blue) / 255.0f; } public void SetDiffuseAlpha(int alpha) { materialDiffuse[3] = (1.0f * alpha) / 255.0f; } public float[] GetDiffuseColor() { return materialDiffuse; } public void SetDiffuseColor(float[] color) { materialDiffuse[0] = color[0]; materialDiffuse[1] = color[1]; materialDiffuse[2] = color[2]; materialDiffuse[3] = color[3]; } public Vector3 LookAtObject(ObjectLibrary objectLibrary) { Vector3 tempPosition = new Vector3(); Vector3 lastTempPosition = new Vector3(-1.0f); Vector3 lookDirection = new Vector3(); Vector3 finalPoint = new Vector3(-1.0f); // Get copies of the current position and normal vector tempPosition = mass.currentPosition + Vector3.Zero; lookDirection = mass.normalVector + Vector3.Zero; // Reset target object targetObject = Mass.ObjectType.NONE; //ObjectLibrary.lookupMapTemp.GetCollisionObjects( // Increment a ray until the Y value projects beneath the surface of the terrain. Then get the closest vertex by flooring the X and Z // values for (int i = 0; i < XML.PlayerSettings.TERRAIN_MOD_RANGE; i++) { tempPosition += lookDirection; // Bounds checking if (tempPosition.X < 0 || tempPosition.X >= Terrain.collisionMapSize || tempPosition.Z >= Terrain.collisionMapSize || tempPosition.Z < 0) { continue; } lastTempPosition = tempPosition; LinkedList massList = ObjectLibrary.lookupMap.GetListXZ((int)tempPosition.X / Terrain.terrainScaleFactor, (int)tempPosition.Z / Terrain.terrainScaleFactor); // Check the lookup map to see if it has any information stored for that location if (massList.Count != 0) { // We have hit something, based on the object id set the targetObject to the correct type and store the object index (in the // lookup map) in one of the three vector components int j = 0; // Parse through the particles we have found foreach (Mass testMass in massList) { if (testMass != null && testMass.gameObjectPointer != null) { // Check if the particle position and the current search position match (or are close) if (Vector3.Distance(testMass.currentPosition, tempPosition) <= testMass.gameObjectPointer._boundingSphere.Radius) { targetObject = testMass.objectType; // Store the X, Z value and the index from the lookupmap in the vector and return it finalPoint = new Vector3(tempPosition.X, (float)j, tempPosition.Z); return finalPoint; } } j++; } } //check for players foreach (Player player in objectLibrary.humans) { if (player.IsAlive() && player != this) { // Check if the player's position and the current search position match (or are close) if (Vector3.Distance(player.mass.currentPosition, tempPosition) <= player.boundingSphere.Radius) { targetObject = player.mass.objectType; // Store the X, Z value and the index of the player in the vector and return it finalPoint = new Vector3(tempPosition.X, (float)player.playerIndex, tempPosition.Z); return finalPoint; } } } foreach (Player player in objectLibrary.bots) { if (player.IsAlive()) { // Check if the player's position and the current search position match (or are close) if (Vector3.Distance(player.mass.currentPosition, tempPosition) <= player.boundingSphere.Radius) { targetObject = player.mass.objectType; // Store the X, Z value and the index of the player in the vector and return it finalPoint = new Vector3(tempPosition.X, (float)player.playerIndex, tempPosition.Z); return finalPoint; } } } // Check if the current search Y point is below the corresponding Y in collision height data if (tempPosition.Y < objectLibrary.terrain.GetTerrainHeight((int)tempPosition.X / Terrain.terrainScaleFactor, (int)tempPosition.Z / Terrain.terrainScaleFactor)) { // We have hit the terrain and not found any objects, so return -1 return new Vector3(-1.0f); } } // We didn't find any objects in our range so return -1 return new Vector3(-1.0f); } public Vector3 LookAtTerrainPoint(ObjectLibrary objectLibrary) { Vector3 tempPosition = new Vector3(); Vector3 lastTempPosition = new Vector3(-1.0f); Vector3 lookDirection = new Vector3(); Vector3 finalPoint = new Vector3(-1.0f); lookDirection = mass.normalVector + Vector3.Zero; // Get copies of the current position and normal vector tempPosition = mass.currentPosition + Vector3.Zero; // Reset target object targetObject = Mass.ObjectType.NONE; // Increment a ray until the Y value projects beneath the surface of the terrain. Then get the closest vertex by flooring the X and Z // values for (int i = 0; i < XML.PlayerSettings.TERRAIN_MOD_RANGE; i++) { tempPosition += lookDirection; // Bounds checking if (tempPosition.X < 0 || tempPosition.X >= Terrain.collisionMapSize || tempPosition.Z >= Terrain.collisionMapSize || tempPosition.Z < 0) { continue; } lastTempPosition = tempPosition; // Check if the current search Y point is below the corresponding Y in collision height data if (tempPosition.Y < objectLibrary.terrain.GetTerrainHeight((int)tempPosition.X / Terrain.terrainScaleFactor, (int)tempPosition.Z / Terrain.terrainScaleFactor)) { // Store the values in the vector and set targetObject targetObject = Mass.ObjectType.TERRAIN; finalPoint.X = (int)(tempPosition.X / Terrain.terrainScaleFactor); finalPoint.Z = (int)(tempPosition.Z / Terrain.terrainScaleFactor); finalPoint.Y = objectLibrary.terrain.GetTerrainHeight((int)tempPosition.X / Terrain.terrainScaleFactor, (int)tempPosition.Z / Terrain.terrainScaleFactor); if (terrainModEnabled) { if (terrainModTarget == Vector3.Zero) { terrainModTarget = finalPoint; } else { finalPoint = terrainModTarget; } } return finalPoint; } } // We didn't find any matching point if (finalPoint.X < 0) { // Check if the player is looking downwards if (lookDirection.Y < 0.2f) { // Ensure that the last position is non-negative if (lastTempPosition.X > 0) { // Set target object and values in the vector targetObject = Mass.ObjectType.TERRAIN; finalPoint.X = (int)(lastTempPosition.X / Terrain.terrainScaleFactor); finalPoint.Z = (int)(lastTempPosition.Z / Terrain.terrainScaleFactor); finalPoint.Y = objectLibrary.terrain.GetTerrainHeight((int)lastTempPosition.X / Terrain.terrainScaleFactor, (int)lastTempPosition.Z / Terrain.terrainScaleFactor); } } } if (terrainModEnabled) { if (terrainModTarget == Vector3.Zero) { terrainModTarget = finalPoint; } else { finalPoint = terrainModTarget; } } return finalPoint; } // Update the players Manna level public bool ChangeManna(float diff) { if (manna + diff < 0) { //don't have enough return false; } manna += diff; if (manna < 0) { manna = 0; } else if (manna > 100) { manna = 100; } return true; } // Update the players Health level public void ChangeHealth(float diff, ObjectLibrary objectLibrary) { if (spawnDoneTimer.IsRunning) { return; } if (diff < 0) { // Play audio for each human foreach (Human human in objectLibrary.humans) { if (human.IsAlive()) { Audio.SmackDownHit(pSounds, mass.currentPosition, human.mass.currentPosition); } } } health += diff; if (health < 0) { health = 0; } else if (health > 100) { health = 100; } //check to see if its human if (playerIndex < 4 && diff < 0) { ((Human)this).ShowDamageIndicator(); } } public void Kill(int killerID, ObjectLibrary objectLibrary) { Kill(killerID); //assign kill credit Collision.AssignKillCredit(this, objectLibrary); } public void Kill(int killerID) { killedBy = killerID; //Begin their respawn timer respawnTimer.Reset(); respawnTimer.Start(); } // Check to see if player is still alive public bool IsAlive() { return (health > 0); } // Function to set the particle's energy value public void UseEnergyBeam(ObjectLibrary objectLibrary, float elementUse) { Vector3 lookAtPoint = new Vector3(-1.0f); // Get the particles information from LookAtPoint and store it in the local vector3 lookAtPoint lookAtPoint = LookAtObject(objectLibrary); // Check if the target object was a particle or a player if (targetObject == Mass.ObjectType.PARTICLE || targetObject == Mass.ObjectType.PLAYER) { if (targetObject == Mass.ObjectType.PARTICLE) { // Reference the particle from lookupMap LinkedList linkedList = ObjectLibrary.lookupMap.GetListXZ((int)lookAtPoint.X / Terrain.terrainScaleFactor, (int)lookAtPoint.Z / Terrain.terrainScaleFactor); int j = 0; foreach (Mass massObj in linkedList) { if (j == (int)lookAtPoint.Y) { gameObject = massObj.gameObjectPointer; break; } j++; } } else //its a player { if ((int)lookAtPoint.Y < 4) { //its a human gameObject = objectLibrary.humans[(int)lookAtPoint.Y]; } else { //its a bot gameObject = objectLibrary.bots[(int)lookAtPoint.Y - 4]; } } if (gameObject == null) { //didn't find it.. probably won't happen but just in case return; } // Expel or absorb energy float cost = 0; if (elementUse < 0) { if (targetObject == Mass.ObjectType.PARTICLE) { //absorb manna from particle cost = -XML.PlayerSettings.PARTICLE_ABSORB_MANNA_COST * -elementUse; } else { //absorb health from player cost = -XML.PlayerSettings.PLAYER_ABSORB_MANNA_COST * -elementUse; } } else { //expel cost = -XML.PlayerSettings.EXPEL_MANNA_COST * elementUse; } if (targetObject == Mass.ObjectType.PARTICLE) { if (Math.Abs(gameObject.mass.energy) <= 1.0f && ChangeManna(cost)) { float dEnergy = elementUse; //If we use dpad: float dEnergy = (particleThermalValue - 37) / 40.0f; gameObject.mass.ChangeEnergy(dEnergy * 0.01f); if (gameObject.mass.objectType == Mass.ObjectType.PARTICLE) { ((Particle)gameObject).ownerID = playerIndex; } gameObject.mass.isChanging = true; if (elementUse < 0) { //add manna ChangeManna(XML.PlayerSettings.PARTICLE_ABSORB_MANNA_GAIN * -elementUse); if (IsHuman()) { ((Human)this).ShowMannaIndicator(); } } } } else { if (Math.Abs(gameObject.mass.energy) <= 1.0f && ChangeManna(cost)) { float dEnergy = elementUse; //If we use dpad: float dEnergy = (particleThermalValue - 37) / 40.0f; gameObject.mass.ChangeEnergy(dEnergy * 0.01f); if (elementUse < 0) { //add health from player ChangeHealth(XML.PlayerSettings.PLAYER_ABSORB_HEALTH_GAIN * -elementUse, objectLibrary); ((Player)gameObject).SetHitShader(new Vector3(lookAtPoint.X, ((Player)gameObject).mass.currentPosition.Y + XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT, lookAtPoint.Z), 4); //subtract other player's health ((Player)gameObject).ChangeHealth(-XML.PlayerSettings.PLAYER_ABSORB_HEALTH_GAIN * -elementUse, objectLibrary); } else { //hurt player ((Player)gameObject).ChangeHealth(-XML.PlayerSettings.EXPEL_HEALTH_LOSS * elementUse, objectLibrary); ((Player)gameObject).SetHitShader(new Vector3(lookAtPoint.X, ((Player)gameObject).mass.currentPosition.Y + XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT, lookAtPoint.Z), 3); } //check if we killed the player if (((Player)gameObject).IsAlive() == false) { ((Player)gameObject).Kill(playerIndex, objectLibrary); if (((Player)gameObject).IsHuman()) { //set killed info on screen for human string s; if (IsHuman()) { s = "Player " + (playerIndex + 1); } else { s = "Bot " + (playerIndex + 1); } ((Human)gameObject).SetKilledByInfo("ZAPPED by " + s); } } } } /* if (Math.Abs(gameObject.mass.energy) <= 1.0f && ChangeManna(cost)) { float dEnergy = elementUse; //If we use dpad: float dEnergy = (particleThermalValue - 37) / 40.0f; gameObject.mass.ChangeEnergy(dEnergy * 0.01f); if (gameObject.mass.objectType == Mass.ObjectType.PARTICLE) { ((Particle)gameObject).ownerID = playerIndex; } gameObject.mass.isChanging = true; if (elementUse < 0) { if (targetObject == Mass.ObjectType.PARTICLE) { //add manna ChangeManna(XML.PlayerSettings.PARTICLE_ABSORB_MANNA_GAIN * -elementUse); if (IsHuman()) { ((Human)this).ShowMannaIndicator(); } } else { //add health from player ChangeHealth(XML.PlayerSettings.PLAYER_ABSORB_HEALTH_GAIN * -elementUse, objectLibrary); //subtract other player's health ((Player)gameObject).ChangeHealth(-XML.PlayerSettings.PLAYER_ABSORB_HEALTH_GAIN * -elementUse, objectLibrary); } } else { if (targetObject == Mass.ObjectType.PLAYER) { //hurt player ((Player)gameObject).ChangeHealth(-XML.PlayerSettings.EXPEL_HEALTH_LOSS * elementUse, objectLibrary); ((Player)gameObject).SetHitShader(new Vector3(lookAtPoint.X, ((Player)gameObject).mass.currentPosition.Y + XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT, lookAtPoint.Z)); //check if we killed the player if (((Player)gameObject).IsAlive() == false) { ((Player)gameObject).Kill(playerIndex); if (((Player)gameObject).IsHuman()) { //set killed info on screen for human string s; if (IsHuman()) { s = "Player " + (playerIndex + 1); } else { s = "Bot " + (playerIndex + 1); } ((Human)gameObject).SetKilledByInfo("ZAPPED by " + s); } } } } */ } } // Initiate Attack public void Attack(Particle.ParticleType type, ObjectLibrary objectLibrary) { // Enable shooting again if Rate Of Fire timer returns greater than the static fire rate if (RateOfFire.Elapsed.TotalMilliseconds > XML.PlayerSettings.RATE_OF_FIRE + ((float)particleMassValue * 10.0f)) { // Reset the rate of fire counter RateOfFire.Reset(); RateOfFire.Start(); // Set state to ATTACK currentState = PlayerState.ATTACK; // Charge Manna if (ChangeManna(-XML.PlayerSettings.ATTACK_MANNA_COST * ((particleMassValue + particleThermalValue) / 10.0f))) { // Start the attack objectLibrary.Attack(playerIndex, type, mass.currentPosition + 5 * mass.normalVector, mass.normalVector, particleMassValue, particleThermalValue); } } } // Do terrain mod public void TerrainMod(float modAmount, ObjectLibrary objectLibrary) { // Play audio for each human foreach (Human human in objectLibrary.humans) { if (human.IsAlive()) { Vector3 soundPosition = new Vector3(); soundPosition.X= lookAtPoint.X * Terrain.terrainScaleFactor; soundPosition.Y = lookAtPoint.Y; soundPosition.Z = lookAtPoint.Z * Terrain.terrainScaleFactor; Audio.TerrainMod(pSounds, soundPosition, human.mass.currentPosition); } } int modRadius = (int)(particleMassValue / 25) + 1; bool isJumping = !CheckPlayerOnTerrain(objectLibrary); float terrainHeightBefore = objectLibrary.terrain.GetTerrainHeight(mass.currentPosition.X / Terrain.terrainScaleFactor, mass.currentPosition.Z / Terrain.terrainScaleFactor); objectLibrary.terrain.ModifyTerrain(modAmount, lookAtPoint, modRadius); //Is the player under terrain? float terrainHeightAfter = objectLibrary.terrain.GetTerrainHeight(mass.currentPosition.X / Terrain.terrainScaleFactor, mass.currentPosition.Z / Terrain.terrainScaleFactor); if (terrainHeightBefore != terrainHeightAfter && isJumping == false) { mass.currentPosition.Y = terrainHeightAfter + XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT * 1.5f; } } public void SetHitShader(Vector3 toHit, Particle particle) { Hit newHit = new Hit(); toHit.Normalize(); newHit.POI = toHit; newHit.pitchyaw = mass.currentRotation; newHit.step = 0.01F; newHit.type = (int)particle.particleType; myHits[0] = newHit; } public void SetHitShader(Vector3 toHit, int type) { if (myHits[0].step < 0.01f || myHits[0].step > 1.0f) { Hit newHit = new Hit(); toHit.Normalize(); newHit.POI = toHit; newHit.pitchyaw = mass.currentRotation; newHit.step = 0.01F; newHit.type = type; // 0 = earth, 1 = water, 2 = air, 3 = fire, 4 = ice myHits[0] = newHit; } } // Activate the shield public void SetShield(ShieldType shield) { activeShield = shield; } public bool IsHuman() { if (playerIndex < 4) { return true; } return false; } } }