//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace DarkWynter.Game.GameObjects
{
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.Xml;
using System.Diagnostics;
using System.Threading;
using System.Collections;
using DarkWynter.Engine;
using DarkWynter.Engine.Globals;
using DarkWynter.Engine.ObjectLib;
using DarkWynter.Engine.GameObjects;
using DarkWynter.Engine.Controllers;
using DarkWynter.Engine.UserInterface;
using DarkWynter.Stream;
using Xclna.Xna.Animation;
using DarkWynter.Engine.EventControl;
using DarkWynter.Engine.Utilities;
using DarkWynter.Engine.Init;
#endregion
///
/// Child class of player which handles human interactions with the game
///
public class Human : Player, IHuman
{
#region init variables
//Human specific indexes of text/imageDisplays
private int timerIndex;
private int positIndex;
private int successIndex;
private int thoughtIndex;
private int boopIndex;
private int realmapIndex;
private int posiX;
private int posiY;
private int newXpos;
private int newYpos;
//Heap Game Variables
char buttonLetter = 'A';
int buttonIndex;
int barIndex;
int currentBoxIndex;
int cIndex, leftIndex, rightIndex;
InteractiveImageDisplay currentButton;
public Arrows currentArrow;
MouseState prevMouseState;
List buttonPositions = new List();
List arrows = new List();
bool once = true;
bool buttonStuckToMouse = false;
//Heap Game Variables^^
private Stopwatch logPositionTimer = new Stopwatch();
private const double MAGIC_HEALTH_NUMBER = 1.475;
private int coins = Statics_Engine.PlayerSettings.coinsCollected;
private int displayLimit = 1000;
public int mapIndex { get { return _mapIndex; } set { _mapIndex = value; } }
public int _mapIndex;
public Texture2D MapStart { get { return _MapStart; } set { _MapStart = value; } }
public Texture2D _MapStart;
public Vector2 MAP_IMAGE_LOCATION { get { return _MAP_IMAGE_LOCATION; } set { _MAP_IMAGE_LOCATION = value; } }
public Vector2 _MAP_IMAGE_LOCATION = new Vector2(0, 0);
public int MapXOffset = 212;
public int MapYOffset = 10;
public int stackIndex { get { return _stackIndex; } set { _stackIndex = value; } }
public int _stackIndex;
public Texture2D StackStart { get { return _StackStart; } set { _StackStart = value; } }
public Texture2D _StackStart;
public Vector2 STACK_IMAGE_LOCATION { get { return _STACK_IMAGE_LOCATION; } set { _STACK_IMAGE_LOCATION = value; } }
public Vector2 _STACK_IMAGE_LOCATION = new Vector2(0, 0);
public int StackXOffset = 212;
public int StackYOffset = 10;
#endregion
public Human()
: base()
{
}
///
/// Constructor
///
public Human(Load gameObjectLoader)
: base(gameObjectLoader)
{
mass.gameObjectPointer = this;
}
///
/// Find the indexes of all text/imageDisplays specific to human
///
/// ObjectLibrary
/// True if load was successful
public override bool Load(ObjectLibrary objectLibrary)
{
#region HUD Locators
for (int x = 0; x < DarkWynterEngine.HUD.textDisplays.Count; x++)
{
if (DarkWynterEngine.HUD.textDisplays[x].name == "timerText")
{
timerIndex = x;
}
if (DarkWynterEngine.HUD.textDisplays[x].name == "positionText")
{
positIndex = x;
}
}
for (int x = 0; x < DarkWynterEngine.HUD.imageDisplays.Count; x++)
{
if (DarkWynterEngine.HUD.imageDisplays[x].name == "ThoughtE")
{
thoughtIndex = x;
}
if (DarkWynterEngine.HUD.imageDisplays[x].name == "success")
{
successIndex = x;
}
if (DarkWynterEngine.HUD.imageDisplays[x].name == "boop")
{
boopIndex = x;
}
if (DarkWynterEngine.HUD.imageDisplays[x].name == "REALmap")
{
realmapIndex = x;
}
if (DarkWynterEngine.HUD.imageDisplays[x].name == "Toolbox_Background")
{
barIndex = x;
}
}
for (int x = 0; x < DarkWynterEngine.HUD.interactiveImageDisplays.Count; x++)
{
buttonIndex = x;
DarkWynterEngine.HUD.interactiveImageDisplays[x].text = buttonLetter.ToString();
buttonLetter++;
}
#endregion
DarkWynterEngine.HUD.imageDisplays[successIndex].stopWatch.Start();
logPositionTimer.Start();
for (int i = 0; i < DarkWynterEngine.HUD.interactiveImageDisplays.Count; i++)
{
buttonPositions.Add(DarkWynterEngine.HUD.interactiveImageDisplays[i].position);
}
currentButton = DarkWynterEngine.HUD.interactiveImageDisplays[0];
currentBoxIndex = 0;
currentButton.isSelected = true;
cIndex = currentBoxIndex + 1;
rightIndex = (2 * cIndex) - 1;
leftIndex = 2 * cIndex;
DarkWynterEngine.HUD.interactiveImageDisplays[0].color = Color.LemonChiffon;
DarkWynterEngine.HUD.interactiveImageDisplays[1].color = Color.Coral;
DarkWynterEngine.HUD.interactiveImageDisplays[2].color = Color.Coral;
DarkWynterEngine.HUD.interactiveImageDisplays[3].color = Color.CornflowerBlue;
DarkWynterEngine.HUD.interactiveImageDisplays[4].color = Color.CornflowerBlue;
DarkWynterEngine.HUD.interactiveImageDisplays[5].color = Color.CornflowerBlue;
DarkWynterEngine.HUD.interactiveImageDisplays[6].color = Color.CornflowerBlue;
DarkWynterEngine.HUD.interactiveImageDisplays[7].color = Color.LightGreen;
DarkWynterEngine.HUD.interactiveImageDisplays[8].color = Color.LightGreen;
DarkWynterEngine.HUD.interactiveImageDisplays[9].color = Color.LightGreen;
DarkWynterEngine.HUD.interactiveImageDisplays[10].color = Color.LightGreen;
DarkWynterEngine.HUD.interactiveImageDisplays[11].color = Color.LightGreen;
DarkWynterEngine.HUD.interactiveImageDisplays[12].color = Color.LightGreen;
DarkWynterEngine.HUD.interactiveImageDisplays[13].color = Color.LightGreen;
DarkWynterEngine.HUD.interactiveImageDisplays[14].color = Color.LightGreen;
if (!base.Load(objectLibrary))
{
return false;
}
return true;
}
///
/// Update player behavior
///
public override void Update(ref ObjectLibrary objectLibrary)
{
#region Logging
if (logPositionTimer.ElapsedMilliseconds > 6000)
{
if (mass.currentPosition != Statics_Engine.PlayerSettings.previousPosition)
{
Logging.G2LPositionalLog.Add(DateTime.Now.ToString() + " " + mass.currentPosition.ToString());
Statics_Engine.PlayerSettings.previousPosition = mass.currentPosition;
}
logPositionTimer.Reset();
logPositionTimer.Start();
}
#endregion
#region Human HUD specific updates (GameTime, Health, Position, and Thought Collected)
// Update the Game Time
int seconds = ((int)Statics_Engine.LevelSettings.gameTimer.Elapsed.TotalSeconds) % 60;
int minutes = ((int)Statics_Engine.LevelSettings.gameTimer.Elapsed.TotalSeconds) / 60;
string formatedSeconds = seconds.ToString();
if (seconds < 10)
{
formatedSeconds = "0" + seconds.ToString();
}
string timing = minutes.ToString() + ":" + formatedSeconds;
//update the boop
posiX = (int)Convert.ToDecimal(this.x);
posiY = (int)Convert.ToDecimal(this.z);
DarkWynterEngine.HUD.textDisplays[timerIndex].text = timing;
//this is terrible fix it later
//HACK
newXpos = (int)(((float)posiX / 8192.0) * DarkWynterEngine.HUD.imageDisplays[realmapIndex].width + DarkWynterEngine.HUD.imageDisplays[realmapIndex].position.X) - DarkWynterEngine.HUD.imageDisplays[boopIndex].width / 2;
newYpos = (int)(((float)posiY / 8192.0) * DarkWynterEngine.HUD.imageDisplays[realmapIndex].height + DarkWynterEngine.HUD.imageDisplays[realmapIndex].position.Y) - DarkWynterEngine.HUD.imageDisplays[boopIndex].height / 2;
DarkWynterEngine.HUD.imageDisplays[boopIndex].position = new Vector2(newXpos, newYpos);
DarkWynterEngine.HUD.textDisplays[positIndex].text = this.mass.currentPosition.ToString(); //"X: " + newXpos + " Y: " + newYpos;
// Update the sanity bar
DarkWynterEngine.HUD.imageDisplays[thoughtIndex].Source = new Rectangle(0, 0,
DarkWynterEngine.HUD.imageDisplays[thoughtIndex].width,
(int)(MAGIC_HEALTH_NUMBER * ((80 - (int)((Statics_Engine.PlayerSettings.coinsCollected) * 10)) *
((int)DarkWynterEngine.HUD.imageDisplays[thoughtIndex].height / 80))));
// Update the success image upon collecting a coin if the coin count changes
if (Statics_Engine.PlayerSettings.coinsCollected != coins)
{
//start the timer and post the message to the screen
if (!DarkWynterEngine.HUD.imageDisplays[successIndex].stopWatch.IsRunning)
{
coins = Statics_Engine.PlayerSettings.coinsCollected;
DarkWynterEngine.HUD.imageDisplays[successIndex].stopWatch.Reset();
DarkWynterEngine.HUD.imageDisplays[successIndex].stopWatch.Start();
DarkWynterEngine.HUD.imageDisplays[successIndex].visible = true;
}
if (DarkWynterEngine.HUD.imageDisplays[successIndex].stopWatch.ElapsedMilliseconds >= displayLimit)
{
DarkWynterEngine.HUD.imageDisplays[successIndex].visible = false;
DarkWynterEngine.HUD.imageDisplays[successIndex].stopWatch.Stop();
DarkWynterEngine.HUD.imageDisplays[successIndex].stopWatch.Reset();
}
}
#endregion
if (currentArrow != null)
{
//currentArrow.mass.currentPosition = mass.currentPosition;
}
//Needs to be used only for Heap Game
//HACK
if (true)
{
ButtonMovement();
}
base.Update(ref objectLibrary);
}
private void ButtonMovement()
{
//populate Arrow List only once
//Since the Human is the first Object loaded
//I was not able to populate this arrow list in
//Human's Load call
//HACK
if (once == true)
{
SetButtonArrowLists();
once = false;
}
//Update values of buttons to the corresponding arrows
UpdateButtonValues();
MouseState mouseState = Mouse.GetState();
Vector2 mouseVector = new Vector2(mouseState.X, mouseState.Y);
if (mouseState.MiddleButton == ButtonState.Pressed &&
prevMouseState.MiddleButton == ButtonState.Released)
{
if (!buttonStuckToMouse)
{
//Pick Up Nearest Button
buttonStuckToMouse = true;
float distance = 100000.0f;
Vector2 temp = Vector2.Zero;
currentBoxIndex = -1;
for(int i = 0; i < buttonPositions.Count; i++)
{
if (Vector2.Distance(mouseVector, (buttonPositions[i] + new Vector2(18, 0))) < distance)
{
distance = Vector2.Distance(mouseVector, (buttonPositions[i] + new Vector2(18, 0)));
temp = buttonPositions[i];
currentBoxIndex = i;
UpdateChildIndices();
}
}
//After finding nearest position check all buttons
//to see which matches the found position
for (int i = 0; i < DarkWynterEngine.HUD.interactiveImageDisplays.Count; i++)
{
if (DarkWynterEngine.HUD.interactiveImageDisplays[i].position == temp ||
Vector2.Distance(DarkWynterEngine.HUD.interactiveImageDisplays[i].position, temp) < 1.0f)
{
currentButton.isSelected = false;
currentButton = DarkWynterEngine.HUD.interactiveImageDisplays[i];
currentButton.isSelected = true;
break;
}
}
//Set the current button based on the button
//picked up, buttons have letters correspnding
//to their arrows
for (int i = 0; i < arrows.Count; i++)
{
if (arrows[i].letter == currentButton.text)
{
currentArrow = arrows[i];
//Remove the Terrain Mod at which ever letter you picked up
TerrainModRequest request = new TerrainModRequest(100, 0,
(currentArrow.mass.currentPosition / Statics_Engine.TerrainSettings.terrainScaleFactor) + new Vector3(2, 0, 2),
currentArrow.mass.currentPosition / Statics_Engine.TerrainSettings.terrainScaleFactor,
2, Enums_Engine.TerrainModType.EQUALTO);
DarkWynter.Engine.Controllers.GameController.NonControllerBasedTerrainMod(request);
}
}
}
else
{
//Drop Button on Nearset box
//Need to swap with box that is in that position
float distance = 100000.0f;
Vector2 temp = Vector2.Zero;
for(int i = 0; i < buttonPositions.Count; i++)
{
if (Vector2.Distance(mouseVector, (buttonPositions[i] + new Vector2(18,0))) < distance)
{
distance = Vector2.Distance(mouseVector, (buttonPositions[i] + new Vector2(18, 0)));
temp = buttonPositions[i];
}
}
//After finding nearest position
//Move the box at this position to the
//previous position of the current button
bool isChild = false;
for (int i = 0; i < DarkWynterEngine.HUD.interactiveImageDisplays.Count; i++)
{
if ((DarkWynterEngine.HUD.interactiveImageDisplays[i].position == temp ||
Vector2.Distance(DarkWynterEngine.HUD.interactiveImageDisplays[i].position, temp) < 1.0f))
{
//Find the arrow correspong to the buttons and
for (int k = 0; k < arrows.Count; k++)
{
if (arrows[k].letter == DarkWynterEngine.HUD.interactiveImageDisplays[i].text &&
(k == rightIndex || k == leftIndex))
{
isChild = SwapArrows(i, k);
}
}
break;
}
}
if (isChild)
{
currentButton.position = temp;
}
else
{
currentButton.position = buttonPositions[currentBoxIndex];
//rebuild the terrain of the button dropped
TerrainModRequest request = new TerrainModRequest(100, int.Parse(currentArrow.id),
(currentArrow.mass.currentPosition / Statics_Engine.TerrainSettings.terrainScaleFactor) + new Vector3(2, 0, 2),
currentArrow.mass.currentPosition / Statics_Engine.TerrainSettings.terrainScaleFactor,
2, Enums_Engine.TerrainModType.EQUALTO);
DarkWynter.Engine.Controllers.GameController.NonControllerBasedTerrainMod(request);
}
buttonStuckToMouse = false;
}
}
//Make current button follow the box
if (buttonStuckToMouse)
{
currentButton.position = mouseVector - new Vector2(currentButton.width / 2, currentButton.height / 2);
}
prevMouseState = mouseState;
}
private void UpdateChildIndices()
{
cIndex = currentBoxIndex + 1;
rightIndex = (2 * cIndex) - 1;
leftIndex = 2 * cIndex;
}
private bool SwapArrows(int i, int k)
{
Arrows tempArrow = currentArrow;
arrows[currentBoxIndex] = arrows[k];
arrows[k] = currentArrow;
DarkWynterEngine.HUD.interactiveImageDisplays[i].position = buttonPositions[currentBoxIndex];
//Vector3 tempArrowPosition = arrows[k].mass.currentPosition;
//arrows[k].mass.currentPosition = currentArrow.mass.currentPosition;
//currentArrow.mass.currentPosition = tempArrowPosition;
Vector3 tempArrowPosition = arrows[currentBoxIndex].mass.currentPosition;
arrows[currentBoxIndex].mass.currentPosition = arrows[k].mass.currentPosition;
arrows[k].mass.currentPosition = tempArrowPosition;
//Rebuild the terrain for both arrows
TerrainModRequest request1 = new TerrainModRequest(100,
int.Parse(arrows[currentBoxIndex].id),
(arrows[currentBoxIndex].mass.currentPosition / Statics_Engine.TerrainSettings.terrainScaleFactor) + new Vector3(2, 0, 2),
arrows[currentBoxIndex].mass.currentPosition / Statics_Engine.TerrainSettings.terrainScaleFactor, 2, Enums_Engine.TerrainModType.EQUALTO);
TerrainModRequest request2 = new TerrainModRequest(100,
int.Parse(arrows[k].id),
(arrows[k].mass.currentPosition / Statics_Engine.TerrainSettings.terrainScaleFactor) + new Vector3(2, 0, 2),
arrows[k].mass.currentPosition / Statics_Engine.TerrainSettings.terrainScaleFactor, 2, Enums_Engine.TerrainModType.EQUALTO);
DarkWynter.Engine.Controllers.GameController.NonControllerBasedTerrainMod(request2);
DarkWynter.Engine.Controllers.GameController.NonControllerBasedTerrainMod(request1);
//Reposition the arrows to be directly
//above the terrain
currentArrow.mass.currentPosition.Y =
int.Parse(currentArrow.id) * (Statics_Engine.TerrainSettings.terrainScaleFactor - 15);
arrows[k].mass.currentPosition.Y =
int.Parse(arrows[k].id) * (Statics_Engine.TerrainSettings.terrainScaleFactor - 15);
return true;
}
private void UpdateButtonValues()
{
for (int i = 0; i < DarkWynterEngine.HUD.interactiveImageDisplays.Count; i++)
{
for (int k = 0; k < arrows.Count; k++)
{
if (DarkWynterEngine.HUD.interactiveImageDisplays[i].text == arrows[k].letter)
{
DarkWynterEngine.HUD.interactiveImageDisplays[i].altText = arrows[k].id;
}
}
}
}
private void SetButtonArrowLists()
{
foreach (GameObject alias in DarkWynterEngine.objectLibrary.gameObjectList)
{
if (alias.typeID == "Arrow")
{
alias.id = "0";
arrows.Add((Arrows)alias);
}
foreach (InteractiveImageDisplay image in DarkWynterEngine.HUD.interactiveImageDisplays)
{
if (alias.letter == image.text)
{
image.altText = alias.id;
}
}
}
}
///
/// Toggle First Person View
///
public override void FPVToggle()
{
fpvEnabled = !fpvEnabled;
}
}
}