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