//--------------------------------------------------------------------------------------------------------------------------------------------------- // // 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 System.Threading; #endregion public class Human : Player { public GameController playerController = new GameController(); //Heads up display public HeadsUpDisplay HUD = new HeadsUpDisplay(); public HeadsUpDisplay deadHUD = new HeadsUpDisplay(); float sizeRatioH; float sizeRatioW; private int hudDamageIndicator; private int hudMannaGainIndicator; private int hudKeyIndicator; private int hudMovementType; private int hudWeaponSelect; private int stickBack; private int stickBack2; private int plungerMana; private int plungerHealth; private int hudTargetIndex; public int hudKillsIndex; private int mainSpinner; private int hudKeysIndex; private int keysCollected; //dead HUD private int dhudKilledByIndex; private int hudDPadGlyph; private int hudDPadRetical; private int width; //Heads Up Display Texture Indexes int manaIndex; int healthIndex; private Texture2D borderTexture_top; private Texture2D borderTexture_side; public bool isConnected = false; // Is controller connected public bool rumbleEnabled = true; // Should this controller rumble? // Update Rumble Pack public float leftRumbleAmount = 0.0f; public float rightRumbleAmount = 0.0f; List rumbleEventList = new List(); const int RUMBLE_TIME_MSEC = 100; private Stopwatch stopAllRumble = new Stopwatch(); private const float MAX_RUMBLE_VALUE = 1.0f; private const int STOP_ALL_RUMBLETIME_MILLI = 300; //damage indicator private const int DAMAGE_INDICATOR_TIME_MILLI = 500; private Stopwatch damageIndicatorTimer = new Stopwatch(); //manna gain indicator private const int MANNA_GAIN_INDICATOR_TIME_MILLI = 500; private Stopwatch mannaIndicatorTimer = new Stopwatch(); // Key indicator private const int KEY_INDICATOR_TIME_MILLI = 500; private Stopwatch keyIndicatorTimer = new Stopwatch(); private class RumbleEvent { public float leftRumbleAmount; public float rightRumbleAmount; public int rumbleDuration; public Stopwatch timer; public RumbleEvent() { leftRumbleAmount = 0; rightRumbleAmount = 0; rumbleDuration = 0; timer = new Stopwatch(); } // Activate the rumble for a specified duration the duration is in milliseconds! public void Activate(float left, float right, int duration) { leftRumbleAmount = left; rightRumbleAmount = right; rumbleDuration = duration; timer = Stopwatch.StartNew(); } // Checks to see if we should stop this rumble public bool HasStopped() { if (timer.ElapsedMilliseconds >= rumbleDuration) { return true; } return false; } }; public Human() : base() { } public Human(int playerNumber) : base(playerNumber, ObjectLibrary.darkMatter[ObjectLibrary.darkMatterIterator++]) { isConnected = false; rumbleEventList.Clear(); mass.objectType = Mass.ObjectType.PLAYER; mass.gameObjectPointer = this; } public void ShowDamageIndicator() { HUD.UpdateImageDraw(this.hudDamageIndicator, true); //reset stopwatch damageIndicatorTimer.Reset(); damageIndicatorTimer.Start(); } public void ShowMannaIndicator() { HUD.UpdateImageDraw(this.hudMannaGainIndicator, true); //reset stopwatch mannaIndicatorTimer.Reset(); mannaIndicatorTimer.Start(); } public void ShowKeyIndicator() { HUD.UpdateImageDraw(hudKeyIndicator, true); //reset stopwatch keyIndicatorTimer.Reset(); keyIndicatorTimer.Start(); } /* GameObject Interface Methods * */ public override void Load(XmlNode node) { StopAllSoundsAndRumble(); playerController = new GameController(); rumbleEventList.Clear(); isConnected = true; try { int x = (int)(Terrain.collisionMapSize * float.Parse(node.Attributes["startx"].Value)); int z = (int)(Terrain.collisionMapSize * float.Parse(node.Attributes["startz"].Value)); SetSpawnPoint(new Vector3(x, spawnHeight + XML.PlayerSettings.DEFAULT_PLAYER_HEIGHT + 10, z)); //mass.SetPosition(new Vector3(x, Player.DEFAULT_PLAYER_HEIGHT, z), new Vector3(x, Player.DEFAULT_PLAYER_HEIGHT, z + 1)); } catch { System.Diagnostics.Debug.WriteLine("Error reading player attributes"); return; } base.Load(node); } public override void Update(ObjectLibrary objectLibrary) { if (playerController == null) { return; } // Get the controller updates playerController.UpdateControllers(); // If not overriding the controls, get controller input if (!controllerInput.manualOverride) { // Controller check controllerInput.playerRotation = playerController.GetObjectRotation(); controllerInput.playerMotion = playerController.GetObjectMotion(); controllerInput.attackAmount = playerController.GetAttackAmount(); controllerInput.defendAmount = playerController.GetDefendAmount(); controllerInput.elementUse = controllerInput.attackAmount - controllerInput.defendAmount; //Tweak and integrate these two // controllerInput.terrainModToggle = playerController.GetTerrainModToggle(); controllerInput.modeSwitch = playerController.GetElementModeSwitching((GameController.ElementalMode)this.lastModeSelected); if (controllerInput.modeSwitch == GameController.ElementalMode.TERRAIN_MODE && lastModeSelected != ElementalMode.TERRAIN_MODE) { controllerInput.terrainModToggle = true; } else if (controllerInput.modeSwitch == GameController.ElementalMode.NONE) { controllerInput.terrainModToggle = false; } else if (controllerInput.modeSwitch != GameController.ElementalMode.TERRAIN_MODE && lastModeSelected == ElementalMode.TERRAIN_MODE) { controllerInput.terrainModToggle = true; } else { controllerInput.terrainModToggle = false; } controllerInput.movementTypeToggle = playerController.GetMovementTypeToggle(); controllerInput.jump = playerController.GetJumpKey(); controllerInput.massChangeDelta = playerController.GetMassChangeDelta(); controllerInput.thermalChangeDelta = playerController.GetThermalChangeDelta(); if (controllerInput.massChangeDelta != 0 || controllerInput.thermalChangeDelta != 0) { Audio.MenuDPad(); } } // Update the rumble if (controllerInput.elementUse != 0) { float left = 0; float right = 0; // If terrain mod switch is on OR there are no elements selected if (controllerInput.attackMode == GameController.AttackMode.TERRAIN_MOD) { if (controllerInput.defendAmount > 0.0f) { left = 0.4f; } if (controllerInput.attackAmount > 0.0f) { right = 0.4f; } AddRumble(controllerInput.defendAmount, controllerInput.attackAmount, 150); } else { if (controllerInput.defendAmount > 0.0f) { left = 0.1f; } if (controllerInput.attackAmount > 0.0f) { right = 0.2f; } AddRumble(left, right, 100); } } // Update HUD UpdateHUD(); UpdateRumble(); base.Update(objectLibrary); } /* Player Methods * */ public void UpdateRumble() { if (playerController.playerControllerType == GameController.ControllerType.PC_ONLY) { return; } if (IsAlive() == false) { GamePad.SetVibration(playerController.playerControllerIndex, 0, 0); return; } // Check if time has run out if (stopAllRumble.ElapsedMilliseconds >= STOP_ALL_RUMBLETIME_MILLI) { GamePad.SetVibration(playerController.playerControllerIndex, 0, 0); rumbleEventList.Clear(); } // Check current state if (hitWhere.Contains(HitWhere.LEFT)) { AddRumble(0.5f, 0.0f, 50); currentState = PlayerState.NORMAL; } else if (hitWhere.Contains(HitWhere.RIGHT)) { AddRumble(0.0f, 0.5f, 50); currentState = PlayerState.NORMAL; } // First check to see if any rumble events have ended for (int i = 0; i < rumbleEventList.Count; i++) { if (rumbleEventList[i].HasStopped()) { leftRumbleAmount -= rumbleEventList[i].leftRumbleAmount; rightRumbleAmount -= rumbleEventList[i].rightRumbleAmount; // Apply new rumble amount GamePad.SetVibration(playerController.playerControllerIndex, leftRumbleAmount, rightRumbleAmount); // Remove from the list rumbleEventList.RemoveAt(i); i--; } } } public void AddRumble(float left, float right, int duration) { if (playerController.playerControllerType == GameController.ControllerType.PC_ONLY || rumbleEnabled == false) { return; } if (rumbleEventList.Count >= 5) { // Don't want too many events return; } // Add a new rumble event rumbleEventList.Add(new RumbleEvent()); rumbleEventList[rumbleEventList.Count - 1].Activate(left, right, duration); leftRumbleAmount += left; rightRumbleAmount += right; // Check for max rumble if (leftRumbleAmount > MAX_RUMBLE_VALUE) { leftRumbleAmount = MAX_RUMBLE_VALUE; } if (rightRumbleAmount > MAX_RUMBLE_VALUE) { rightRumbleAmount = MAX_RUMBLE_VALUE; } // Apply new rumble amount GamePad.SetVibration(playerController.playerControllerIndex, leftRumbleAmount, rightRumbleAmount); // Start global rumble timer stopAllRumble = Stopwatch.StartNew(); } public void SetKilledByInfo(string s) { deadHUD.UpdateText(this.dhudKilledByIndex, s); } public void SetKilledByInfo(Particle particle) { string killerString; if (killedBy == playerIndex) { deadHUD.UpdateText(this.dhudKilledByIndex, "Suicidal tendencies..."); } else { switch (killedBy) { case 0: killerString = "Player 1"; break; case 1: killerString = "Player 2"; break; case 2: killerString = "Player 3"; break; case 3: killerString = "Player 4"; break; default: killerString = "Bot " + (killedBy - 3); break; } switch (particle.particleType) { case Particle.ParticleType.Air: deadHUD.UpdateText(this.dhudKilledByIndex, "Blown away by " + killerString); break; case Particle.ParticleType.Earth: if (particle.mass.energy > 0.3f) { deadHUD.UpdateText(this.dhudKilledByIndex, "Molted by " + killerString); } else { deadHUD.UpdateText(this.dhudKilledByIndex, "Buried by " + killerString); } break; case Particle.ParticleType.Water: if (particle.mass.energy > 0.3f) { deadHUD.UpdateText(this.dhudKilledByIndex, "Boiled by " + killerString); } else if (particle.mass.energy < -0.3f) { deadHUD.UpdateText(this.dhudKilledByIndex, "Frozen by " + killerString); } else { deadHUD.UpdateText(this.dhudKilledByIndex, "Drowned by " + killerString); } break; } } } public void UpdateHUD() { if (particleThermalValue > 75) { particleThermalValue = 75; } if (particleMassValue > 75) { particleMassValue = 75; } if (borderTexture_side != null) { int padding = 25; #if XBOX360 padding = 35; #endif //update reticle HUD.UpdateImagePosition(hudDPadRetical, new Vector2(borderTexture_side.Width + (16 + particleThermalValue) * sizeRatioH, HUD.parentViewport.Height - padding - (borderTexture_top.Height + particleMassValue) * sizeRatioH)); //HUD.UpdateImagePosition(this.plungerHealth, new Vector2(width - (100 * sizeRatioH) - borderTexture_side.Width, (200 - (health / 100) * 200) * sizeRatioH)); } HUD.UpdateImageScale(this.healthIndex, 1.0f, health / 100.0f); HUD.UpdateImageScale(this.manaIndex, 1.0f, manna / 100.0f); HUD.UpdateImageHeight(this.healthIndex, (int)(((health / 100) * 200) * sizeRatioH)); HUD.UpdateImageHeight(this.manaIndex, (int)(((manna / 100) * 200) * sizeRatioH)); //Syringe position HUD.UpdateImageHeight(this.plungerHealth, (int)(200*sizeRatioH - (1 - (health / 100.0f)) * 40 * sizeRatioH)); HUD.UpdateImageHeight(this.plungerMana, (int)(200 * sizeRatioH - (1 - (manna / 100.0f)) * 40 * sizeRatioH)); if (GameFlow.gameType == GameFlow.GameType.STORY_MODE) { this.keysCollected = this.numberOfKeysFound; HUD.UpdateTextVis(this.hudKeysIndex, "Keys: " + this.keysCollected, true); } HUD.UpdateText(this.hudKillsIndex, "Kills: " + this.kills); if (mass.movementType == Mass.MovementType.WALK) { HUD.UpdateText(this.hudMovementType, "Move: Walk"); } else { HUD.UpdateText(this.hudMovementType, "Move: Hover"); } if (airElementSelected) { HUD.SpinnerSet(this.mainSpinner, 3); } if (waterElementSelected) { HUD.SpinnerSet(this.mainSpinner, 2); } if (earthElementSelected) { HUD.SpinnerSet(this.mainSpinner, 0); } if (fireElementSelected) { HUD.SpinnerSet(this.mainSpinner, 1); } if (terrainModEnabled) { HUD.SpinnerSet(this.mainSpinner, 4); } //if manna indicator has timed out.. remove it if (mannaIndicatorTimer.ElapsedMilliseconds >= MANNA_GAIN_INDICATOR_TIME_MILLI) { HUD.UpdateImageDraw(this.hudMannaGainIndicator, false); mannaIndicatorTimer.Stop(); mannaIndicatorTimer.Reset(); } //if damage indicator has timed out.. remove it if (damageIndicatorTimer.ElapsedMilliseconds >= DAMAGE_INDICATOR_TIME_MILLI) { HUD.UpdateImageDraw(this.hudDamageIndicator, false); damageIndicatorTimer.Stop(); damageIndicatorTimer.Reset(); } //if damage indicator has timed out.. remove it if (keyIndicatorTimer.ElapsedMilliseconds >= KEY_INDICATOR_TIME_MILLI) { HUD.UpdateImageDraw(this.hudKeyIndicator, false); keyIndicatorTimer.Stop(); keyIndicatorTimer.Reset(); } } public void CreateHUD(Viewport viewport, ContentManager content) { sizeRatioW = ((float)viewport.Width / (float)XML.SystemSettings.GAME_WINDOW_WIDTH); sizeRatioH = ((float)viewport.Height / (float)XML.SystemSettings.GAME_WINDOW_HEIGHT); float scaleX = (XML.SystemSettings.GAME_WINDOW_WIDTH / 1280.0f); float scaleY = (XML.SystemSettings.GAME_WINDOW_HEIGHT / 1024.0f); int spinnerX = (int)(748 * scaleX); int spinnerY = (int)(817 * scaleY); width = viewport.Width; HUD = new HeadsUpDisplay(playerIndex, viewport); deadHUD = new HeadsUpDisplay(playerIndex, viewport); //initialize the HUD for when player is dead... //this is where you put "You were killed by blah..." this.dhudKilledByIndex = deadHUD.AddTextDisplay("", new Vector2(60, 60), Color.Black); //the regular HUD borderTexture_side = content.Load("_textures/box_sides_small"); borderTexture_top = content.Load("_textures/box_top_small"); // Also add the manna gain indicator (blue) hudMannaGainIndicator = HUD.AddImageDisplay(content.Load("_textures/whitesquare"), new Vector2(0, 0), viewport.Width, viewport.Height, new Color(0, 0, 255, 100), false); // First add the red image for hit effect (red) hudDamageIndicator = HUD.AddImageDisplay(content.Load("_textures/whitesquare"), new Vector2(0, 0), viewport.Width, viewport.Height, new Color(255, 0, 0, 100), false); // Add the green image for key effect hudKeyIndicator = HUD.AddImageDisplay(content.Load("_textures/whitesquare"), new Vector2(0, 0), viewport.Width, viewport.Height, new Color(164, 255, 164, 100), false); // HUD background on left side of the screen HUD.AddImageDisplay(content.Load("_textures/black"), new Vector2(50,30), (int) (140), (int)(80), new Color(255,255,255,100), true); this.hudKillsIndex = HUD.AddTextDisplay("Kills:", new Vector2(60, 40), Color.White); this.hudMovementType = HUD.AddTextDisplay("Move: Walk", new Vector2(60, 60), Color.White); this.hudKeysIndex = HUD.AddTextDisplay("Keys: ", new Vector2(60, 80), Color.White); HUD.UpdateTextVis(this.hudKeysIndex, "", false); // HUD background on right side of the screen HUD.AddImageDisplay(content.Load("_textures/black"), new Vector2(viewport.Width - (120 * sizeRatioH) - borderTexture_side.Width, borderTexture_side.Width - 10), (int)(150 * sizeRatioH), (int)(220 * sizeRatioH), new Color(255, 255, 255, 175), true); this.healthIndex = HUD.AddImageDisplay(content.Load("_textures/Health"), new Vector2(viewport.Width - (100 * sizeRatioH) - borderTexture_side.Width, borderTexture_side.Width), (int)(50 * sizeRatioH), (int)(200 * sizeRatioH), Color.White, true); this.manaIndex = HUD.AddImageDisplay(content.Load("_textures/Manna"), new Vector2(viewport.Width - (50 * sizeRatioH) - borderTexture_side.Width, borderTexture_side.Width), (int)(50 * sizeRatioH), (int)(200 * sizeRatioH), Color.White, true); this.plungerMana = HUD.AddImageDisplay(content.Load("_textures/plunger"), new Vector2(viewport.Width - (50 * sizeRatioH) - borderTexture_side.Width, borderTexture_side.Width - 10), (int)(50 * sizeRatioH), (int)(200 * sizeRatioH), Color.White, true); this.plungerHealth = HUD.AddImageDisplay(content.Load("_textures/plunger"), new Vector2(viewport.Width - (100 * sizeRatioH) - borderTexture_side.Width, borderTexture_side.Width - 10), (int)(50 * sizeRatioH), (int)(200 * sizeRatioH), Color.White, true); this.stickBack = HUD.AddImageDisplay(content.Load("_textures/syringe"), new Vector2(viewport.Width - (100 * sizeRatioH) - borderTexture_side.Width, borderTexture_side.Width), (int)(50 * sizeRatioH), (int)(200 * sizeRatioH), Color.White, true); this.stickBack2 = HUD.AddImageDisplay(content.Load("_textures/syringe"), new Vector2(viewport.Width - (50 * sizeRatioH) - borderTexture_side.Width, borderTexture_side.Width), (int)(50 * sizeRatioH), (int)(200 * sizeRatioH), Color.White, true); this.hudWeaponSelect = HUD.AddImageDisplay(content.Load("_textures/wsbg"), new Vector2(viewport.Width - (spinnerX+2) * sizeRatioW - borderTexture_side.Width, borderTexture_side.Width + (spinnerY-2) * sizeRatioH), (int)(313 * scaleX * sizeRatioW), (int)(73 * scaleY * sizeRatioW), Color.White, true); int targetSize = 50; hudTargetIndex = HUD.AddImageDisplay(content.Load("_textures/target"), new Vector2(viewport.Width / 2.0f - (targetSize *2) / 2, viewport.Height / 2.0f - (targetSize *2) / 2), (int)(targetSize * 2), (int)(targetSize * 2), Color.White, true); this.hudDPadGlyph = HUD.AddImageDisplay(content.Load("_textures/DPAD_Glyph"), new Vector2(borderTexture_side.Width, viewport.Height - borderTexture_top.Height - 100 * sizeRatioH), (int)(100 * sizeRatioH), (int)(100 * sizeRatioH), Color.White, true); this.hudDPadRetical = HUD.AddImageDisplay(content.Load("_textures/DPAD_Target"), new Vector2(borderTexture_side.Width + 16 * sizeRatioH, viewport.Height - 25 - borderTexture_top.Height * sizeRatioH), (int)(10 * sizeRatioH), (int)(10 * sizeRatioH), Color.White, true); HeadsUpDisplay.ImageSpinner spinny = new HeadsUpDisplay.ImageSpinner(4); HeadsUpDisplay.ImageDisplay temp = new HeadsUpDisplay.ImageDisplay(); //Main bottom spinner temp = new HeadsUpDisplay.ImageDisplay(); spinny = new HeadsUpDisplay.ImageSpinner(5); temp.image = content.Load("_textures/earthHud"); temp.width = (int)(60 * scaleX * sizeRatioW); temp.height = (int)(72 * scaleY * sizeRatioW); temp.position = new Vector2(viewport.Width - spinnerX * sizeRatioW - borderTexture_side.Width, borderTexture_side.Width + spinnerY * sizeRatioH); temp.color = Color.White; temp.visible = true; spinny.visible = true; spinny.addImage(temp, 0); temp = new HeadsUpDisplay.ImageDisplay(); temp.image = content.Load("_textures/fireHud"); temp.width = (int)(60 * scaleX * sizeRatioW); temp.height = (int)(72 * scaleY * sizeRatioW); temp.position = new Vector2(viewport.Width - (spinnerX * sizeRatioW - (temp.width + 2)) - borderTexture_side.Width, borderTexture_side.Width + spinnerY * sizeRatioH); temp.color = Color.White; temp.visible = true; spinny.visible = true; spinny.addImage(temp, 1); temp = new HeadsUpDisplay.ImageDisplay(); temp.image = content.Load("_textures/waterHud"); temp.width = (int)(60 * scaleX * sizeRatioW); temp.height = (int)(72 * scaleY * sizeRatioW); temp.position = new Vector2(viewport.Width - (spinnerX * sizeRatioW - (temp.width + 2) * 2) - borderTexture_side.Width, borderTexture_side.Width + spinnerY * sizeRatioH); temp.color = Color.White; temp.visible = true; spinny.visible = true; spinny.addImage(temp, 2); temp = new HeadsUpDisplay.ImageDisplay(); temp.image = content.Load("_textures/airHud"); temp.width = (int)(60 * scaleX * sizeRatioW); temp.height = (int)(72 * scaleY * sizeRatioW); temp.position = new Vector2(viewport.Width - (spinnerX * sizeRatioW - (temp.width + 2) * 3) - borderTexture_side.Width, borderTexture_side.Width + spinnerY * sizeRatioH); temp.color = Color.White; temp.visible = true; spinny.visible = true; spinny.addImage(temp, 3); temp = new HeadsUpDisplay.ImageDisplay(); ; temp.image = content.Load("_textures/terrainmod"); temp.width = (int)(60 * scaleX * sizeRatioW); temp.height = (int)(72 * scaleY * sizeRatioW); temp.position = new Vector2(viewport.Width - (spinnerX * sizeRatioW - (temp.width + 2) * 4) - borderTexture_side.Width, borderTexture_side.Width + spinnerY * sizeRatioH); temp.color = Color.White; temp.visible = true; spinny.visible = true; spinny.addImage(temp, 4); this.mainSpinner = HUD.AddImageSpinner(spinny); /* * Hide the border.. don't really need it for (int x = 0; x < viewport.Width; x = x + borderTexture_top.Width) { HUD.AddImageDisplay(borderTexture_top, new Vector2(x, 0), borderTexture_top.Width, borderTexture_top.Height, Color.White, true); HUD.AddImageDisplay(borderTexture_top, new Vector2(x, viewport.Height - borderTexture_top.Height), borderTexture_top.Width, borderTexture_top.Height, Color.White, true); } for (int y = 0; y < viewport.Height; y = y + borderTexture_side.Height) { HUD.AddImageDisplay(borderTexture_side, new Vector2(0, y), borderTexture_side.Width, borderTexture_side.Height, Color.White, true); HUD.AddImageDisplay(borderTexture_side, new Vector2(viewport.Width - borderTexture_side.Width, y), borderTexture_side.Width, borderTexture_side.Height, Color.White, true); } */ } public void StopAllSoundsAndRumble() { // Remove all rumble GamePad.SetVibration(playerController.playerControllerIndex, 0.0f, 0.0f); } } }